mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-06-05 21:39:12 +02:00
Compare commits
17 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
55e15c8dee | ||
|
9d567e22ba | ||
|
848712f89e | ||
|
5d1e039e05 | ||
|
c76a3b9f2e | ||
|
2d7731bda2 | ||
|
ae23bbc63c | ||
|
81e35b9277 | ||
|
f768881e64 | ||
|
9499fd03b6 | ||
|
f2646ea38e | ||
|
c49b21c407 | ||
|
fe622e7aa0 | ||
|
26778307c8 | ||
|
ef03e9636e | ||
|
612d63af73 | ||
|
e8fb169bed |
@@ -7,5 +7,6 @@
|
||||
# https://bitbucket.org/chromiumembedded/cef/wiki/BranchesAndBuilding
|
||||
|
||||
{
|
||||
'chromium_checkout': 'refs/tags/119.0.6045.0'
|
||||
'chromium_checkout': 'refs/tags/119.0.6045.199',
|
||||
'depot_tools_checkout': '744bfd2a7b'
|
||||
}
|
||||
|
@@ -12,7 +12,7 @@
|
||||
# distribution include:
|
||||
#
|
||||
# Linux: Ninja, GCC 7.5.0+, Unix Makefiles
|
||||
# MacOS: Ninja, Xcode 12.2 to 13.0
|
||||
# MacOS: Ninja, Xcode 12.2 to 15.0
|
||||
# Windows: Ninja, Visual Studio 2022
|
||||
#
|
||||
# Ninja is a cross-platform open-source tool for running fast builds using
|
||||
@@ -36,7 +36,7 @@
|
||||
#
|
||||
# The below requirements must be met to build this CEF binary distribution.
|
||||
#
|
||||
# - CMake version 3.19 or newer.
|
||||
# - CMake version 3.21 or newer.
|
||||
#
|
||||
# - Linux requirements:
|
||||
# Currently supported distributions include Debian 10 (Buster), Ubuntu 18
|
||||
@@ -48,7 +48,7 @@
|
||||
# libgtk3.0-dev (required by the cefclient target only)
|
||||
#
|
||||
# - MacOS requirements:
|
||||
# Xcode 12.2 to 13.4 building on MacOS 10.15.4 (Catalina) or newer. Only
|
||||
# Xcode 12.2 to 15.0 building on MacOS 10.15.4 (Catalina) or newer. Only
|
||||
# 64-bit builds are supported. The Xcode command-line tools must also be
|
||||
# installed. Newer Xcode versions may not have been been tested and are not
|
||||
# recommended.
|
||||
|
@@ -147,6 +147,8 @@
|
||||
'libcef_dll/wrapper/cef_byte_read_handler.cc',
|
||||
'libcef_dll/wrapper/cef_closure_task.cc',
|
||||
'libcef_dll/wrapper/cef_message_router.cc',
|
||||
'libcef_dll/wrapper/cef_message_router_utils.cc',
|
||||
'libcef_dll/wrapper/cef_message_router_utils.h',
|
||||
'libcef_dll/wrapper/cef_resource_manager.cc',
|
||||
'libcef_dll/wrapper/cef_scoped_temp_dir.cc',
|
||||
'libcef_dll/wrapper/cef_stream_resource_handler.cc',
|
||||
@@ -218,6 +220,8 @@
|
||||
'tests/shared/browser/util_win.h',
|
||||
],
|
||||
'cefclient_sources_browser': [
|
||||
'tests/cefclient/browser/binary_transfer_test.cc',
|
||||
'tests/cefclient/browser/binary_transfer_test.h',
|
||||
'tests/cefclient/browser/binding_test.cc',
|
||||
'tests/cefclient/browser/binding_test.h',
|
||||
'tests/cefclient/browser/browser_window.cc',
|
||||
@@ -309,6 +313,7 @@
|
||||
'tests/cefclient/resources/dialogs.html',
|
||||
'tests/cefclient/resources/draggable.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',
|
||||
@@ -496,6 +501,7 @@
|
||||
'tests/ceftests/jsdialog_unittest.cc',
|
||||
'tests/ceftests/life_span_unittest.cc',
|
||||
'tests/ceftests/media_access_unittest.cc',
|
||||
'tests/ceftests/message_router_binary_unittest.cc',
|
||||
'tests/ceftests/message_router_harness_unittest.cc',
|
||||
'tests/ceftests/message_router_multi_query_unittest.cc',
|
||||
'tests/ceftests/message_router_single_query_unittest.cc',
|
||||
@@ -603,6 +609,7 @@
|
||||
'tests/ceftests/dom_unittest.cc',
|
||||
'tests/ceftests/frame_unittest.cc',
|
||||
'tests/ceftests/media_access_unittest.cc',
|
||||
'tests/ceftests/message_router_binary_unittest.cc',
|
||||
'tests/ceftests/message_router_harness_unittest.cc',
|
||||
'tests/ceftests/message_router_multi_query_unittest.cc',
|
||||
'tests/ceftests/message_router_single_query_unittest.cc',
|
||||
|
@@ -33,7 +33,7 @@
|
||||
// by hand. See the translator.README.txt file in the tools directory for
|
||||
// more information.
|
||||
//
|
||||
// $hash=db4fce1215cb4f69346ef2d048974ba34187b2b1$
|
||||
// $hash=eed525e9abcbf8e8b959067e0056ca470c5210c7$
|
||||
//
|
||||
|
||||
#ifndef CEF_INCLUDE_CAPI_CEF_BROWSER_CAPI_H_
|
||||
@@ -932,6 +932,48 @@ typedef struct _cef_browser_host_t {
|
||||
/// be called on the UI thread.
|
||||
///
|
||||
int(CEF_CALLBACK* is_audio_muted)(struct _cef_browser_host_t* self);
|
||||
|
||||
///
|
||||
/// Returns true (1) if the renderer is currently in browser fullscreen. This
|
||||
/// differs from window fullscreen in that browser fullscreen is entered using
|
||||
/// the JavaScript Fullscreen API and modifies CSS attributes such as the
|
||||
/// ::backdrop pseudo-element and :fullscreen pseudo-structure. This function
|
||||
/// can only be called on the UI thread.
|
||||
///
|
||||
int(CEF_CALLBACK* is_fullscreen)(struct _cef_browser_host_t* self);
|
||||
|
||||
///
|
||||
/// Requests the renderer to exit browser fullscreen. In most cases exiting
|
||||
/// window fullscreen should also exit browser fullscreen. With the Alloy
|
||||
/// runtime this function should be called in response to a user action such
|
||||
/// as clicking the green traffic light button on MacOS
|
||||
/// (cef_window_delegate_t::OnWindowFullscreenTransition callback) or pressing
|
||||
/// the "ESC" key (cef_keyboard_handler_t::OnPreKeyEvent callback). With the
|
||||
/// Chrome runtime these standard exit actions are handled internally but
|
||||
/// new/additional user actions can use this function. Set |will_cause_resize|
|
||||
/// to true (1) if exiting browser fullscreen will cause a view resize.
|
||||
///
|
||||
void(CEF_CALLBACK* exit_fullscreen)(struct _cef_browser_host_t* self,
|
||||
int will_cause_resize);
|
||||
|
||||
///
|
||||
/// Returns true (1) if a Chrome command is supported and enabled. Values for
|
||||
/// |command_id| can be found in the cef_command_ids.h file. This function can
|
||||
/// only be called on the UI thread. Only used with the Chrome runtime.
|
||||
///
|
||||
int(CEF_CALLBACK* can_execute_chrome_command)(
|
||||
struct _cef_browser_host_t* self,
|
||||
int command_id);
|
||||
|
||||
///
|
||||
/// Execute a Chrome command. Values for |command_id| can be found in the
|
||||
/// cef_command_ids.h file. |disposition| provides information about the
|
||||
/// intended command target. Only used with the Chrome runtime.
|
||||
///
|
||||
void(CEF_CALLBACK* execute_chrome_command)(
|
||||
struct _cef_browser_host_t* self,
|
||||
int command_id,
|
||||
cef_window_open_disposition_t disposition);
|
||||
} cef_browser_host_t;
|
||||
|
||||
///
|
||||
|
@@ -33,7 +33,7 @@
|
||||
// by hand. See the translator.README.txt file in the tools directory for
|
||||
// more information.
|
||||
//
|
||||
// $hash=1c807597b96889f44a1e5199e860e8db4948b473$
|
||||
// $hash=32a0c21a71aa7137fa9660b942f597705bc8b05e$
|
||||
//
|
||||
|
||||
#ifndef CEF_INCLUDE_CAPI_CEF_LIFE_SPAN_HANDLER_CAPI_H_
|
||||
@@ -100,6 +100,34 @@ typedef struct _cef_life_span_handler_t {
|
||||
struct _cef_dictionary_value_t** extra_info,
|
||||
int* no_javascript_access);
|
||||
|
||||
///
|
||||
/// Called on the UI thread before a new DevTools popup browser is created.
|
||||
/// The |browser| value represents the source of the popup request. Optionally
|
||||
/// modify |windowInfo|, |client|, |settings| and |extra_info| values. The
|
||||
/// |client|, |settings| and |extra_info| values will default to the source
|
||||
/// browser's values. Any modifications to |windowInfo| will be ignored if the
|
||||
/// parent browser is Views-hosted (wrapped in a cef_browser_view_t).
|
||||
///
|
||||
/// The |extra_info| parameter provides an opportunity to specify extra
|
||||
/// information specific to the created popup browser that will be passed to
|
||||
/// cef_render_process_handler_t::on_browser_created() in the render process.
|
||||
/// The existing |extra_info| object, if any, will be read-only but may be
|
||||
/// replaced with a new object.
|
||||
///
|
||||
/// Views-hosted source browsers will create Views-hosted DevTools popups
|
||||
/// unless |use_default_window| is set to to true (1). DevTools popups can be
|
||||
/// blocked by returning true (1) from cef_command_handler_t::OnChromeCommand
|
||||
/// for IDC_DEV_TOOLS. Only used with the Chrome runtime.
|
||||
///
|
||||
void(CEF_CALLBACK* on_before_dev_tools_popup)(
|
||||
struct _cef_life_span_handler_t* self,
|
||||
struct _cef_browser_t* browser,
|
||||
struct _cef_window_info_t* windowInfo,
|
||||
struct _cef_client_t** client,
|
||||
struct _cef_browser_settings_t* settings,
|
||||
struct _cef_dictionary_value_t** extra_info,
|
||||
int* use_default_window);
|
||||
|
||||
///
|
||||
/// Called after a new browser is created. It is now safe to begin performing
|
||||
/// actions with |browser|. cef_frame_handler_t callbacks related to initial
|
||||
|
@@ -33,7 +33,7 @@
|
||||
// by hand. See the translator.README.txt file in the tools directory for
|
||||
// more information.
|
||||
//
|
||||
// $hash=42de7c0e6f5ec529d9182fe4cbf2c1edfacd7392$
|
||||
// $hash=865ca5bff4a0867d0c25cb41bd2aa808cf3fddbd$
|
||||
//
|
||||
|
||||
#ifndef CEF_INCLUDE_CAPI_CEF_V8_CAPI_H_
|
||||
@@ -679,6 +679,19 @@ typedef struct _cef_v8value_t {
|
||||
///
|
||||
int(CEF_CALLBACK* neuter_array_buffer)(struct _cef_v8value_t* self);
|
||||
|
||||
///
|
||||
/// Returns the length (in bytes) of the ArrayBuffer.
|
||||
///
|
||||
size_t(CEF_CALLBACK* get_array_buffer_byte_length)(
|
||||
struct _cef_v8value_t* self);
|
||||
|
||||
///
|
||||
/// Returns a pointer to the beginning of the memory block for this
|
||||
/// ArrayBuffer backing store. The returned pointer is valid as long as the
|
||||
/// cef_v8value_t is alive.
|
||||
///
|
||||
void*(CEF_CALLBACK* get_array_buffer_data)(struct _cef_v8value_t* self);
|
||||
|
||||
///
|
||||
/// Returns the function name.
|
||||
///
|
||||
|
@@ -33,7 +33,7 @@
|
||||
// by hand. See the translator.README.txt file in the tools directory for
|
||||
// more information.
|
||||
//
|
||||
// $hash=1b8f7f620685c30b91c8fa656e1a01d182684ae6$
|
||||
// $hash=7b8fee9d4a0530782ed62f5741820708f110e24e$
|
||||
//
|
||||
|
||||
#ifndef CEF_INCLUDE_CAPI_CEF_VALUES_CAPI_H_
|
||||
@@ -265,6 +265,12 @@ typedef struct _cef_binary_value_t {
|
||||
struct _cef_binary_value_t*(CEF_CALLBACK* copy)(
|
||||
struct _cef_binary_value_t* self);
|
||||
|
||||
///
|
||||
/// Returns a pointer to the beginning of the memory block. The returned
|
||||
/// pointer is valid as long as the cef_binary_value_t is alive.
|
||||
///
|
||||
const void*(CEF_CALLBACK* get_raw_data)(struct _cef_binary_value_t* self);
|
||||
|
||||
///
|
||||
/// Returns the data size.
|
||||
///
|
||||
|
@@ -33,7 +33,7 @@
|
||||
// by hand. See the translator.README.txt file in the tools directory for
|
||||
// more information.
|
||||
//
|
||||
// $hash=f72e94f6bd63b6ea623c4d3170b5ad4333c136d6$
|
||||
// $hash=bc80e7f1e467a4e0943dcbf7ea6d08366817d5ca$
|
||||
//
|
||||
|
||||
#ifndef CEF_INCLUDE_CAPI_VIEWS_CEF_BROWSER_VIEW_CAPI_H_
|
||||
@@ -77,13 +77,19 @@ typedef struct _cef_browser_view_t {
|
||||
struct _cef_browser_view_t* self);
|
||||
|
||||
///
|
||||
/// Sets whether accelerators registered with cef_window_t::SetAccelerator are
|
||||
/// triggered before or after the event is sent to the cef_browser_t. If
|
||||
/// |prefer_accelerators| is true (1) then the matching accelerator will be
|
||||
/// triggered immediately and the event will not be sent to the cef_browser_t.
|
||||
/// If |prefer_accelerators| is false (0) then the matching accelerator will
|
||||
/// only be triggered if the event is not handled by web content or by
|
||||
/// cef_keyboard_handler_t. The default value is false (0).
|
||||
/// Sets whether normal priority accelerators are first forwarded to the web
|
||||
/// content (`keydown` event handler) or cef_keyboard_handler_t. Normal
|
||||
/// priority accelerators can be registered via cef_window_t::SetAccelerator
|
||||
/// (with |high_priority|=false (0)) or internally for standard accelerators
|
||||
/// supported by the Chrome runtime. If |prefer_accelerators| is true (1) then
|
||||
/// the matching accelerator will be triggered immediately (calling
|
||||
/// cef_window_delegate_t::OnAccelerator or
|
||||
/// cef_command_handler_t::OnChromeCommand respectively) and the event will
|
||||
/// not be forwarded to the web content or cef_keyboard_handler_t first. If
|
||||
/// |prefer_accelerators| is false (0) then the matching accelerator will only
|
||||
/// be triggered if the event is not handled by web content (`keydown` event
|
||||
/// handler that calls `event.preventDefault()`) or by cef_keyboard_handler_t.
|
||||
/// The default value is false (0).
|
||||
///
|
||||
void(CEF_CALLBACK* set_prefer_accelerators)(struct _cef_browser_view_t* self,
|
||||
int prefer_accelerators);
|
||||
|
@@ -33,7 +33,7 @@
|
||||
// by hand. See the translator.README.txt file in the tools directory for
|
||||
// more information.
|
||||
//
|
||||
// $hash=4b43fe0b493d860e8b28d7a6d892db49d1135b34$
|
||||
// $hash=a48904fcd0f6be07e27839922d8feb07271ed2b5$
|
||||
//
|
||||
|
||||
#ifndef CEF_INCLUDE_CAPI_VIEWS_CEF_WINDOW_CAPI_H_
|
||||
@@ -332,16 +332,25 @@ typedef struct _cef_window_t {
|
||||
|
||||
///
|
||||
/// Set the keyboard accelerator for the specified |command_id|. |key_code|
|
||||
/// can be any virtual key or character value.
|
||||
/// can be any virtual key or character value. Required modifier keys are
|
||||
/// specified by |shift_pressed|, |ctrl_pressed| and/or |alt_pressed|.
|
||||
/// cef_window_delegate_t::OnAccelerator will be called if the keyboard
|
||||
/// combination is triggered while this window has focus.
|
||||
///
|
||||
/// The |high_priority| value will be considered if a child cef_browser_view_t
|
||||
/// has focus when the keyboard combination is triggered. If |high_priority|
|
||||
/// is true (1) then the key event will not be forwarded to the web content
|
||||
/// (`keydown` event handler) or cef_keyboard_handler_t first. If
|
||||
/// |high_priority| is false (0) then the behavior will depend on the
|
||||
/// cef_browser_view_t::SetPreferAccelerators configuration.
|
||||
///
|
||||
void(CEF_CALLBACK* set_accelerator)(struct _cef_window_t* self,
|
||||
int command_id,
|
||||
int key_code,
|
||||
int shift_pressed,
|
||||
int ctrl_pressed,
|
||||
int alt_pressed);
|
||||
int alt_pressed,
|
||||
int high_priority);
|
||||
|
||||
///
|
||||
/// Remove the keyboard accelerator for the specified |command_id|.
|
||||
|
@@ -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 "647a2df6b870951e70487997f30e75960d609632"
|
||||
#define CEF_API_HASH_UNIVERSAL "ce9401699c6753553cba867b1f5c329f759d2c67"
|
||||
#if defined(OS_WIN)
|
||||
#define CEF_API_HASH_PLATFORM "4a22d727f3f1f625844191f0f5adf297a2f17fa7"
|
||||
#define CEF_API_HASH_PLATFORM "e094f42b7a60d2c8c9bcb3db51907a3b42f51d04"
|
||||
#elif defined(OS_MAC)
|
||||
#define CEF_API_HASH_PLATFORM "84a450a85c81d6cb16dda55d7f07047264d1e205"
|
||||
#define CEF_API_HASH_PLATFORM "6ce44bd7182aa7e9544f5ca33c310f2a096ab638"
|
||||
#elif defined(OS_LINUX)
|
||||
#define CEF_API_HASH_PLATFORM "b7cbd7d044e02cb1854184cc1d5d621605b8476b"
|
||||
#define CEF_API_HASH_PLATFORM "8e9886cd490aefc89283d65f5f7d104a51e2d289"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@@ -964,6 +964,48 @@ class CefBrowserHost : public virtual CefBaseRefCounted {
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual bool IsAudioMuted() = 0;
|
||||
|
||||
///
|
||||
/// Returns true if the renderer is currently in browser fullscreen. This
|
||||
/// differs from window fullscreen in that browser fullscreen is entered using
|
||||
/// the JavaScript Fullscreen API and modifies CSS attributes such as the
|
||||
/// ::backdrop pseudo-element and :fullscreen pseudo-class. This method can
|
||||
/// only be called on the UI thread.
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual bool IsFullscreen() = 0;
|
||||
|
||||
///
|
||||
/// Requests the renderer to exit browser fullscreen. In most cases exiting
|
||||
/// window fullscreen should also exit browser fullscreen. With the Alloy
|
||||
/// runtime this method should be called in response to a user action such as
|
||||
/// clicking the green traffic light button on MacOS
|
||||
/// (CefWindowDelegate::OnWindowFullscreenTransition callback) or pressing the
|
||||
/// "ESC" key (CefKeyboardHandler::OnPreKeyEvent callback). With the Chrome
|
||||
/// runtime these standard exit actions are handled internally but
|
||||
/// new/additional user actions can use this method. Set |will_cause_resize|
|
||||
/// to true if exiting browser fullscreen will cause a view resize.
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual void ExitFullscreen(bool will_cause_resize) = 0;
|
||||
|
||||
///
|
||||
/// Returns true if a Chrome command is supported and enabled. Values for
|
||||
/// |command_id| can be found in the cef_command_ids.h file. This method can
|
||||
/// only be called on the UI thread. Only used with the Chrome runtime.
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual bool CanExecuteChromeCommand(int command_id) = 0;
|
||||
|
||||
///
|
||||
/// Execute a Chrome command. Values for |command_id| can be found in the
|
||||
/// cef_command_ids.h file. |disposition| provides information about the
|
||||
/// intended command target. Only used with the Chrome runtime.
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual void ExecuteChromeCommand(
|
||||
int command_id,
|
||||
cef_window_open_disposition_t disposition) = 0;
|
||||
};
|
||||
|
||||
#endif // CEF_INCLUDE_CEF_BROWSER_H_
|
||||
|
@@ -94,6 +94,33 @@ class CefLifeSpanHandler : public virtual CefBaseRefCounted {
|
||||
return false;
|
||||
}
|
||||
|
||||
///
|
||||
/// Called on the UI thread before a new DevTools popup browser is created.
|
||||
/// The |browser| value represents the source of the popup request. Optionally
|
||||
/// modify |windowInfo|, |client|, |settings| and |extra_info| values. The
|
||||
/// |client|, |settings| and |extra_info| values will default to the source
|
||||
/// browser's values. Any modifications to |windowInfo| will be ignored if the
|
||||
/// parent browser is Views-hosted (wrapped in a CefBrowserView).
|
||||
///
|
||||
/// The |extra_info| parameter provides an opportunity to specify extra
|
||||
/// information specific to the created popup browser that will be passed to
|
||||
/// CefRenderProcessHandler::OnBrowserCreated() in the render process. The
|
||||
/// existing |extra_info| object, if any, will be read-only but may be
|
||||
/// replaced with a new object.
|
||||
///
|
||||
/// Views-hosted source browsers will create Views-hosted DevTools popups
|
||||
/// unless |use_default_window| is set to to true. DevTools popups can be
|
||||
/// blocked by returning true from CefCommandHandler::OnChromeCommand for
|
||||
/// IDC_DEV_TOOLS. Only used with the Chrome runtime.
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual void OnBeforeDevToolsPopup(CefRefPtr<CefBrowser> browser,
|
||||
CefWindowInfo& windowInfo,
|
||||
CefRefPtr<CefClient>& client,
|
||||
CefBrowserSettings& settings,
|
||||
CefRefPtr<CefDictionaryValue>& extra_info,
|
||||
bool* use_default_window) {}
|
||||
|
||||
///
|
||||
/// Called after a new browser is created. It is now safe to begin performing
|
||||
/// actions with |browser|. CefFrameHandler callbacks related to initial main
|
||||
|
@@ -520,7 +520,7 @@ class CefV8Value : public virtual CefBaseRefCounted {
|
||||
/// or CefV8Accessor callback, or in combination with calling Enter() and
|
||||
/// Exit() on a stored CefV8Context reference.
|
||||
///
|
||||
/*--cef()--*/
|
||||
/*--cef(optional_param=buffer)--*/
|
||||
static CefRefPtr<CefV8Value> CreateArrayBuffer(
|
||||
void* buffer,
|
||||
size_t length,
|
||||
@@ -866,6 +866,20 @@ class CefV8Value : public virtual CefBaseRefCounted {
|
||||
/*--cef()--*/
|
||||
virtual bool NeuterArrayBuffer() = 0;
|
||||
|
||||
///
|
||||
/// Returns the length (in bytes) of the ArrayBuffer.
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual size_t GetArrayBufferByteLength() = 0;
|
||||
|
||||
///
|
||||
/// Returns a pointer to the beginning of the memory block for this
|
||||
/// ArrayBuffer backing store. The returned pointer is valid as long as the
|
||||
/// CefV8Value is alive.
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual void* GetArrayBufferData() = 0;
|
||||
|
||||
// FUNCTION METHODS - These methods are only available on functions.
|
||||
|
||||
///
|
||||
|
@@ -278,6 +278,13 @@ class CefBinaryValue : public virtual CefBaseRefCounted {
|
||||
/*--cef()--*/
|
||||
virtual CefRefPtr<CefBinaryValue> Copy() = 0;
|
||||
|
||||
///
|
||||
/// Returns a pointer to the beginning of the memory block.
|
||||
/// The returned pointer is valid as long as the CefBinaryValue is alive.
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual const void* GetRawData() = 0;
|
||||
|
||||
///
|
||||
/// Returns the data size.
|
||||
///
|
||||
|
@@ -353,7 +353,7 @@ struct CefStringTraitsUTF16 {
|
||||
/// modifying CEF strings from multiple threads.
|
||||
///
|
||||
template <class traits>
|
||||
class CefStringBase {
|
||||
class CefStringBase final {
|
||||
public:
|
||||
typedef typename traits::char_type char_type;
|
||||
typedef typename traits::struct_type struct_type;
|
||||
@@ -442,7 +442,7 @@ class CefStringBase {
|
||||
Attach(const_cast<struct_type*>(src), false);
|
||||
}
|
||||
|
||||
virtual ~CefStringBase() { ClearAndFree(); }
|
||||
~CefStringBase() { ClearAndFree(); }
|
||||
|
||||
/// The following methods are named for compatibility with the standard
|
||||
/// library string template types.
|
||||
|
@@ -1004,52 +1004,52 @@ typedef enum {
|
||||
/// renumbered.
|
||||
///
|
||||
typedef enum {
|
||||
WOD_UNKNOWN,
|
||||
CEF_WOD_UNKNOWN,
|
||||
|
||||
///
|
||||
/// Current tab. This is the default in most cases.
|
||||
///
|
||||
WOD_CURRENT_TAB,
|
||||
CEF_WOD_CURRENT_TAB,
|
||||
|
||||
///
|
||||
/// Indicates that only one tab with the url should exist in the same window.
|
||||
///
|
||||
WOD_SINGLETON_TAB,
|
||||
CEF_WOD_SINGLETON_TAB,
|
||||
|
||||
///
|
||||
/// Shift key + Middle mouse button or meta/ctrl key while clicking.
|
||||
///
|
||||
WOD_NEW_FOREGROUND_TAB,
|
||||
CEF_WOD_NEW_FOREGROUND_TAB,
|
||||
|
||||
///
|
||||
/// Middle mouse button or meta/ctrl key while clicking.
|
||||
///
|
||||
WOD_NEW_BACKGROUND_TAB,
|
||||
CEF_WOD_NEW_BACKGROUND_TAB,
|
||||
|
||||
///
|
||||
/// New popup window.
|
||||
///
|
||||
WOD_NEW_POPUP,
|
||||
CEF_WOD_NEW_POPUP,
|
||||
|
||||
///
|
||||
/// Shift key while clicking.
|
||||
///
|
||||
WOD_NEW_WINDOW,
|
||||
CEF_WOD_NEW_WINDOW,
|
||||
|
||||
///
|
||||
/// Alt key while clicking.
|
||||
///
|
||||
WOD_SAVE_TO_DISK,
|
||||
CEF_WOD_SAVE_TO_DISK,
|
||||
|
||||
///
|
||||
/// New off-the-record (incognito) window.
|
||||
///
|
||||
WOD_OFF_THE_RECORD,
|
||||
CEF_WOD_OFF_THE_RECORD,
|
||||
|
||||
///
|
||||
/// Special case error condition from the renderer.
|
||||
///
|
||||
WOD_IGNORE_ACTION,
|
||||
CEF_WOD_IGNORE_ACTION,
|
||||
|
||||
///
|
||||
/// Activates an existing tab containing the url, rather than navigating.
|
||||
@@ -1059,12 +1059,14 @@ typedef enum {
|
||||
/// no session history; and behaves like CURRENT_TAB instead of
|
||||
/// NEW_FOREGROUND_TAB when no existing tab is found.
|
||||
///
|
||||
WOD_SWITCH_TO_TAB,
|
||||
CEF_WOD_SWITCH_TO_TAB,
|
||||
|
||||
///
|
||||
/// Creates a new document picture-in-picture window showing a child WebView.
|
||||
///
|
||||
WOD_NEW_PICTURE_IN_PICTURE,
|
||||
CEF_WOD_NEW_PICTURE_IN_PICTURE,
|
||||
|
||||
CEF_WOD_MAX_VALUE = CEF_WOD_NEW_PICTURE_IN_PICTURE,
|
||||
} cef_window_open_disposition_t;
|
||||
|
||||
///
|
||||
|
@@ -92,13 +92,18 @@ class CefBrowserView : public CefView {
|
||||
virtual CefRefPtr<CefView> GetChromeToolbar() = 0;
|
||||
|
||||
///
|
||||
/// Sets whether accelerators registered with CefWindow::SetAccelerator are
|
||||
/// triggered before or after the event is sent to the CefBrowser. If
|
||||
/// |prefer_accelerators| is true then the matching accelerator will be
|
||||
/// triggered immediately and the event will not be sent to the CefBrowser. If
|
||||
/// |prefer_accelerators| is false then the matching accelerator will only be
|
||||
/// triggered if the event is not handled by web content or by
|
||||
/// CefKeyboardHandler. The default value is false.
|
||||
/// Sets whether normal priority accelerators are first forwarded to the web
|
||||
/// content (`keydown` event handler) or CefKeyboardHandler. Normal priority
|
||||
/// accelerators can be registered via CefWindow::SetAccelerator (with
|
||||
/// |high_priority|=false) or internally for standard accelerators supported
|
||||
/// by the Chrome runtime. If |prefer_accelerators| is true then the matching
|
||||
/// accelerator will be triggered immediately (calling
|
||||
/// CefWindowDelegate::OnAccelerator or CefCommandHandler::OnChromeCommand
|
||||
/// respectively) and the event will not be forwarded to the web content or
|
||||
/// CefKeyboardHandler first. If |prefer_accelerators| is false then the
|
||||
/// matching accelerator will only be triggered if the event is not handled by
|
||||
/// web content (`keydown` event handler that calls `event.preventDefault()`)
|
||||
/// or by CefKeyboardHandler. The default value is false.
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual void SetPreferAccelerators(bool prefer_accelerators) = 0;
|
||||
|
@@ -344,16 +344,25 @@ class CefWindow : public CefPanel {
|
||||
|
||||
///
|
||||
/// Set the keyboard accelerator for the specified |command_id|. |key_code|
|
||||
/// can be any virtual key or character value.
|
||||
/// can be any virtual key or character value. Required modifier keys are
|
||||
/// specified by |shift_pressed|, |ctrl_pressed| and/or |alt_pressed|.
|
||||
/// CefWindowDelegate::OnAccelerator will be called if the keyboard
|
||||
/// combination is triggered while this window has focus.
|
||||
///
|
||||
/// The |high_priority| value will be considered if a child CefBrowserView has
|
||||
/// focus when the keyboard combination is triggered. If |high_priority| is
|
||||
/// true then the key event will not be forwarded to the web content
|
||||
/// (`keydown` event handler) or CefKeyboardHandler first. If |high_priority|
|
||||
/// is false then the behavior will depend on the
|
||||
/// CefBrowserView::SetPreferAccelerators configuration.
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual void SetAccelerator(int command_id,
|
||||
int key_code,
|
||||
bool shift_pressed,
|
||||
bool ctrl_pressed,
|
||||
bool alt_pressed) = 0;
|
||||
bool alt_pressed,
|
||||
bool high_priority) = 0;
|
||||
|
||||
///
|
||||
/// Remove the keyboard accelerator for the specified |command_id|.
|
||||
|
@@ -219,6 +219,38 @@ struct CefMessageRouterConfig {
|
||||
size_t message_size_threshold;
|
||||
};
|
||||
|
||||
///
|
||||
/// This class acts as a container for managing binary data. It retains
|
||||
/// references to the underlying backing store, ensuring it is valid as long as
|
||||
/// the CefBinaryBuffer exists. This allows efficient, zero-copy access to data
|
||||
/// received from another process.
|
||||
///
|
||||
/// This class is not designed to be thread-safe, and it is the user's
|
||||
/// responsibility to synchronize access from multiple threads to ensure data
|
||||
/// integrity.
|
||||
///
|
||||
class CefBinaryBuffer : public CefBaseRefCounted {
|
||||
public:
|
||||
///
|
||||
/// Returns the read-only pointer to the memory. Returns nullptr if
|
||||
/// |GetSize()| returns zero. The returned pointer is only valid for the life
|
||||
/// span of this object.
|
||||
///
|
||||
virtual const void* GetData() const = 0;
|
||||
|
||||
///
|
||||
/// Returns the writable pointer to the memory. Returns nullptr if
|
||||
/// |GetSize()| returns zero. The returned pointer is only valid for the life
|
||||
/// span of this object.
|
||||
///
|
||||
virtual void* GetData() = 0;
|
||||
|
||||
///
|
||||
/// Returns the size of the data.
|
||||
///
|
||||
virtual size_t GetSize() const = 0;
|
||||
};
|
||||
|
||||
///
|
||||
/// Implements the browser side of query routing. The methods of this class may
|
||||
/// be called on any browser process thread unless otherwise indicated.
|
||||
@@ -238,10 +270,17 @@ class CefMessageRouterBrowserSide
|
||||
public:
|
||||
///
|
||||
/// Notify the associated JavaScript onSuccess callback that the query has
|
||||
/// completed successfully with the specified |response|.
|
||||
/// completed successfully with the specified string |response|.
|
||||
///
|
||||
virtual void Success(const CefString& response) = 0;
|
||||
|
||||
///
|
||||
/// Notify the associated JavaScript onSuccess callback that the query has
|
||||
/// completed successfully with binary data. A |data| pointer to the binary
|
||||
/// data can be nullptr only if the |size| is 0.
|
||||
///
|
||||
virtual void Success(const void* data, size_t size) = 0;
|
||||
|
||||
///
|
||||
/// Notify the associated JavaScript onFailure callback that the query has
|
||||
/// failed with the specified |error_code| and |error_message|.
|
||||
@@ -276,6 +315,25 @@ class CefMessageRouterBrowserSide
|
||||
return false;
|
||||
}
|
||||
|
||||
///
|
||||
/// Executed when a new query is received. |query_id| uniquely identifies
|
||||
/// the query for the life span of the router. Return true to handle the
|
||||
/// query or false to propagate the query to other registered handlers, if
|
||||
/// any. If no handlers return true from this method then the query will be
|
||||
/// automatically canceled with an error code of -1 delivered to the
|
||||
/// JavaScript onFailure callback. If this method returns true then a
|
||||
/// Callback method must be executed either in this method or asynchronously
|
||||
/// to complete the query.
|
||||
///
|
||||
virtual bool OnQuery(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
int64_t query_id,
|
||||
CefRefPtr<const CefBinaryBuffer> request,
|
||||
bool persistent,
|
||||
CefRefPtr<Callback> callback) {
|
||||
return false;
|
||||
}
|
||||
|
||||
///
|
||||
/// Executed when a query has been canceled either explicitly using the
|
||||
/// JavaScript cancel function or implicitly due to browser destruction,
|
||||
|
@@ -57,33 +57,6 @@ using content::KeyboardEventProcessingResult;
|
||||
|
||||
namespace {
|
||||
|
||||
class ShowDevToolsHelper {
|
||||
public:
|
||||
ShowDevToolsHelper(CefRefPtr<AlloyBrowserHostImpl> browser,
|
||||
const CefWindowInfo& windowInfo,
|
||||
CefRefPtr<CefClient> client,
|
||||
const CefBrowserSettings& settings,
|
||||
const CefPoint& inspect_element_at)
|
||||
: browser_(browser),
|
||||
window_info_(windowInfo),
|
||||
client_(client),
|
||||
settings_(settings),
|
||||
inspect_element_at_(inspect_element_at) {}
|
||||
|
||||
CefRefPtr<AlloyBrowserHostImpl> browser_;
|
||||
CefWindowInfo window_info_;
|
||||
CefRefPtr<CefClient> client_;
|
||||
CefBrowserSettings settings_;
|
||||
CefPoint inspect_element_at_;
|
||||
};
|
||||
|
||||
void ShowDevToolsWithHelper(ShowDevToolsHelper* helper) {
|
||||
helper->browser_->ShowDevTools(helper->window_info_, helper->client_,
|
||||
helper->settings_,
|
||||
helper->inspect_element_at_);
|
||||
delete helper;
|
||||
}
|
||||
|
||||
static constexpr base::TimeDelta kRecentlyAudibleTimeout = base::Seconds(2);
|
||||
|
||||
} // namespace
|
||||
@@ -358,22 +331,15 @@ void AlloyBrowserHostImpl::StopFinding(bool clearSelection) {
|
||||
}
|
||||
}
|
||||
|
||||
void AlloyBrowserHostImpl::ShowDevTools(const CefWindowInfo& windowInfo,
|
||||
CefRefPtr<CefClient> client,
|
||||
const CefBrowserSettings& settings,
|
||||
const CefPoint& inspect_element_at) {
|
||||
if (!CEF_CURRENTLY_ON_UIT()) {
|
||||
ShowDevToolsHelper* helper = new ShowDevToolsHelper(
|
||||
this, windowInfo, client, settings, inspect_element_at);
|
||||
CEF_POST_TASK(CEF_UIT, base::BindOnce(ShowDevToolsWithHelper, helper));
|
||||
return;
|
||||
}
|
||||
|
||||
void AlloyBrowserHostImpl::ShowDevToolsOnUIThread(
|
||||
std::unique_ptr<CefShowDevToolsParams> params) {
|
||||
CEF_REQUIRE_UIT();
|
||||
if (!EnsureDevToolsManager()) {
|
||||
return;
|
||||
}
|
||||
devtools_manager_->ShowDevTools(windowInfo, client, settings,
|
||||
inspect_element_at);
|
||||
devtools_manager_->ShowDevTools(params->window_info_, params->client_,
|
||||
params->settings_,
|
||||
params->inspect_element_at_);
|
||||
}
|
||||
|
||||
void AlloyBrowserHostImpl::CloseDevTools() {
|
||||
@@ -438,6 +404,16 @@ bool AlloyBrowserHostImpl::IsBackgroundHost() {
|
||||
return is_background_host_;
|
||||
}
|
||||
|
||||
bool AlloyBrowserHostImpl::CanExecuteChromeCommand(int command_id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void AlloyBrowserHostImpl::ExecuteChromeCommand(
|
||||
int command_id,
|
||||
cef_window_open_disposition_t disposition) {
|
||||
NOTIMPLEMENTED();
|
||||
}
|
||||
|
||||
bool AlloyBrowserHostImpl::IsWindowRenderingDisabled() {
|
||||
return IsWindowless();
|
||||
}
|
||||
|
@@ -85,10 +85,6 @@ class AlloyBrowserHostImpl : public CefBrowserHostBase,
|
||||
bool matchCase,
|
||||
bool findNext) override;
|
||||
void StopFinding(bool clearSelection) override;
|
||||
void ShowDevTools(const CefWindowInfo& windowInfo,
|
||||
CefRefPtr<CefClient> client,
|
||||
const CefBrowserSettings& settings,
|
||||
const CefPoint& inspect_element_at) override;
|
||||
void CloseDevTools() override;
|
||||
bool HasDevTools() override;
|
||||
bool IsWindowRenderingDisabled() override;
|
||||
@@ -127,6 +123,9 @@ class AlloyBrowserHostImpl : public CefBrowserHostBase,
|
||||
const CefSize& max_size) override;
|
||||
CefRefPtr<CefExtension> GetExtension() override;
|
||||
bool IsBackgroundHost() override;
|
||||
bool CanExecuteChromeCommand(int command_id) override;
|
||||
void ExecuteChromeCommand(int command_id,
|
||||
cef_window_open_disposition_t disposition) override;
|
||||
|
||||
// Returns true if windowless rendering is enabled.
|
||||
bool IsWindowless() const override;
|
||||
@@ -285,6 +284,10 @@ class AlloyBrowserHostImpl : public CefBrowserHostBase,
|
||||
override;
|
||||
void WebContentsDestroyed() override;
|
||||
|
||||
protected:
|
||||
void ShowDevToolsOnUIThread(
|
||||
std::unique_ptr<CefShowDevToolsParams> params) override;
|
||||
|
||||
private:
|
||||
friend class CefBrowserPlatformDelegateAlloy;
|
||||
|
||||
|
@@ -39,20 +39,15 @@ content::WebContents* CefBrowserPlatformDelegateAlloy::CreateWebContents(
|
||||
REQUIRE_ALLOY_RUNTIME();
|
||||
DCHECK(primary_);
|
||||
|
||||
// Get or create the request context and browser context.
|
||||
CefRefPtr<CefRequestContextImpl> request_context_impl =
|
||||
CefRequestContextImpl::GetOrCreateForRequestContext(
|
||||
create_params.request_context);
|
||||
CHECK(request_context_impl);
|
||||
auto cef_browser_context = request_context_impl->GetBrowserContext();
|
||||
CHECK(cef_browser_context);
|
||||
auto browser_context = cef_browser_context->AsBrowserContext();
|
||||
|
||||
if (!create_params.request_context) {
|
||||
// Using the global request context.
|
||||
create_params.request_context = request_context_impl.get();
|
||||
create_params.request_context = CefRequestContext::GetGlobalContext();
|
||||
}
|
||||
|
||||
auto* browser_context =
|
||||
CefRequestContextImpl::GetBrowserContext(create_params.request_context);
|
||||
CHECK(browser_context);
|
||||
|
||||
scoped_refptr<content::SiteInstance> site_instance;
|
||||
if (extensions::ExtensionsEnabled() && !create_params.url.empty()) {
|
||||
GURL gurl = url_util::MakeGURL(create_params.url, /*fixup=*/true);
|
||||
|
@@ -505,6 +505,22 @@ void CefBrowserHostBase::PrintToPDF(const CefString& path,
|
||||
print_util::PrintToPDF(web_contents, path, settings, callback);
|
||||
}
|
||||
|
||||
void CefBrowserHostBase::ShowDevTools(const CefWindowInfo& windowInfo,
|
||||
CefRefPtr<CefClient> client,
|
||||
const CefBrowserSettings& settings,
|
||||
const CefPoint& inspect_element_at) {
|
||||
auto params = std::make_unique<CefShowDevToolsParams>(
|
||||
windowInfo, client, settings, inspect_element_at);
|
||||
|
||||
if (!CEF_CURRENTLY_ON_UIT()) {
|
||||
CEF_POST_TASK(CEF_UIT,
|
||||
base::BindOnce(&CefBrowserHostBase::ShowDevToolsOnUIThread,
|
||||
this, std::move(params)));
|
||||
} else {
|
||||
ShowDevToolsOnUIThread(std::move(params));
|
||||
}
|
||||
}
|
||||
|
||||
bool CefBrowserHostBase::SendDevToolsMessage(const void* message,
|
||||
size_t message_size) {
|
||||
if (!message || message_size == 0) {
|
||||
@@ -633,6 +649,31 @@ void CefBrowserHostBase::NotifyMoveOrResizeStarted() {
|
||||
#endif
|
||||
}
|
||||
|
||||
bool CefBrowserHostBase::IsFullscreen() {
|
||||
if (!CEF_CURRENTLY_ON_UIT()) {
|
||||
DCHECK(false) << "called on invalid thread";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (auto web_contents = GetWebContents()) {
|
||||
return web_contents->IsFullscreen();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void CefBrowserHostBase::ExitFullscreen(bool will_cause_resize) {
|
||||
if (!CEF_CURRENTLY_ON_UIT()) {
|
||||
CEF_POST_TASK(CEF_UIT, base::BindOnce(&CefBrowserHostBase::ExitFullscreen,
|
||||
this, will_cause_resize));
|
||||
return;
|
||||
}
|
||||
|
||||
auto web_contents = GetWebContents();
|
||||
if (web_contents && web_contents->IsFullscreen()) {
|
||||
web_contents->ExitFullscreen(will_cause_resize);
|
||||
}
|
||||
}
|
||||
|
||||
void CefBrowserHostBase::ReplaceMisspelling(const CefString& word) {
|
||||
if (!CEF_CURRENTLY_ON_UIT()) {
|
||||
CEF_POST_TASK(
|
||||
|
@@ -94,6 +94,23 @@ struct CefBrowserCreateParams {
|
||||
extensions::mojom::ViewType::kInvalid;
|
||||
};
|
||||
|
||||
// Parameters passed to ShowDevToolsOnUIThread().
|
||||
struct CefShowDevToolsParams {
|
||||
CefShowDevToolsParams(const CefWindowInfo& windowInfo,
|
||||
CefRefPtr<CefClient> client,
|
||||
const CefBrowserSettings& settings,
|
||||
const CefPoint& inspect_element_at)
|
||||
: window_info_(windowInfo),
|
||||
client_(client),
|
||||
settings_(settings),
|
||||
inspect_element_at_(inspect_element_at) {}
|
||||
|
||||
CefWindowInfo window_info_;
|
||||
CefRefPtr<CefClient> client_;
|
||||
CefBrowserSettings settings_;
|
||||
CefPoint inspect_element_at_;
|
||||
};
|
||||
|
||||
// Base class for CefBrowserHost implementations. Includes functionality that is
|
||||
// shared by the alloy and chrome runtimes. All methods are thread-safe unless
|
||||
// otherwise indicated.
|
||||
@@ -191,6 +208,10 @@ class CefBrowserHostBase : public CefBrowserHost,
|
||||
void PrintToPDF(const CefString& path,
|
||||
const CefPdfPrintSettings& settings,
|
||||
CefRefPtr<CefPdfPrintCallback> callback) override;
|
||||
void ShowDevTools(const CefWindowInfo& windowInfo,
|
||||
CefRefPtr<CefClient> client,
|
||||
const CefBrowserSettings& settings,
|
||||
const CefPoint& inspect_element_at) override;
|
||||
void ReplaceMisspelling(const CefString& word) override;
|
||||
void AddWordToDictionary(const CefString& word) override;
|
||||
void SendKeyEvent(const CefKeyEvent& event) override;
|
||||
@@ -212,6 +233,8 @@ class CefBrowserHostBase : public CefBrowserHost,
|
||||
bool current_only) override;
|
||||
CefRefPtr<CefNavigationEntry> GetVisibleNavigationEntry() override;
|
||||
void NotifyMoveOrResizeStarted() override;
|
||||
bool IsFullscreen() override;
|
||||
void ExitFullscreen(bool will_cause_resize) override;
|
||||
|
||||
// CefBrowser methods:
|
||||
bool IsValid() override;
|
||||
@@ -344,6 +367,10 @@ class CefBrowserHostBase : public CefBrowserHost,
|
||||
// Called from LoadMainFrameURL to perform the actual navigation.
|
||||
virtual bool Navigate(const content::OpenURLParams& params);
|
||||
|
||||
// Called from ShowDevTools to perform the actual show.
|
||||
virtual void ShowDevToolsOnUIThread(
|
||||
std::unique_ptr<CefShowDevToolsParams> params) = 0;
|
||||
|
||||
// Create the CefFileDialogManager if it doesn't already exist.
|
||||
bool EnsureFileDialogManager();
|
||||
|
||||
|
@@ -33,6 +33,16 @@ CefBrowserInfo::CefBrowserInfo(int browser_id,
|
||||
is_windowless_(is_windowless),
|
||||
extra_info_(extra_info) {
|
||||
DCHECK_GT(browser_id, 0);
|
||||
|
||||
if (extra_info_ && !extra_info_->IsReadOnly()) {
|
||||
// |extra_info_| should always be read-only to avoid accidental future
|
||||
// modification. Take a copy instead of modifying the passed-in object for
|
||||
// backwards compatibility.
|
||||
extra_info_ = extra_info_->Copy(/*exclude_empty_children=*/false);
|
||||
auto extra_info_impl =
|
||||
static_cast<CefDictionaryValueImpl*>(extra_info_.get());
|
||||
extra_info_impl->MarkReadOnly();
|
||||
}
|
||||
}
|
||||
|
||||
CefBrowserInfo::~CefBrowserInfo() {
|
||||
|
@@ -193,15 +193,8 @@ bool CefBrowserInfoManager::CanCreateWindow(
|
||||
pending_popup->use_default_browser_creation = true;
|
||||
}
|
||||
|
||||
// In most cases, Views-hosted browsers should create Views-hosted popups
|
||||
// and native browsers should use default popup handling. With the Chrome
|
||||
// runtime, we should additionally use default handling (a) when using an
|
||||
// external parent and (b) when using default Browser creation.
|
||||
create_params.popup_with_views_hosted_opener =
|
||||
browser->HasView() &&
|
||||
!browser->platform_delegate()->HasExternalParent() &&
|
||||
!pending_popup->use_default_browser_creation;
|
||||
|
||||
create_params.popup_with_views_hosted_opener = ShouldCreateViewsHostedPopup(
|
||||
browser, pending_popup->use_default_browser_creation);
|
||||
create_params.settings = pending_popup->settings;
|
||||
create_params.client = pending_popup->client;
|
||||
create_params.extra_info = pending_popup->extra_info;
|
||||
@@ -420,6 +413,19 @@ bool CefBrowserInfoManager::MaybeAllowNavigation(
|
||||
return true;
|
||||
}
|
||||
|
||||
// static
|
||||
bool CefBrowserInfoManager::ShouldCreateViewsHostedPopup(
|
||||
CefRefPtr<CefBrowserHostBase> opener,
|
||||
bool use_default_browser_creation) {
|
||||
// In most cases, Views-hosted browsers should create Views-hosted popups
|
||||
// and native browsers should use default popup handling. With the Chrome
|
||||
// runtime, we should additionally use default handling (a) when using an
|
||||
// external parent and (b) when using default Browser creation.
|
||||
return opener->HasView() &&
|
||||
!opener->platform_delegate()->HasExternalParent() &&
|
||||
!use_default_browser_creation;
|
||||
}
|
||||
|
||||
CefBrowserInfoManager::BrowserInfoList
|
||||
CefBrowserInfoManager::GetBrowserInfoList() {
|
||||
base::AutoLock lock_scope(browser_info_lock_);
|
||||
|
@@ -143,6 +143,9 @@ class CefBrowserInfoManager : public content::RenderProcessHostObserver {
|
||||
const content::OpenURLParams& params,
|
||||
CefRefPtr<CefBrowserHostBase>& browser) const;
|
||||
|
||||
static bool ShouldCreateViewsHostedPopup(CefRefPtr<CefBrowserHostBase> opener,
|
||||
bool use_default_browser_creation);
|
||||
|
||||
private:
|
||||
// RenderProcessHostObserver methods:
|
||||
void RenderProcessHostDestroyed(content::RenderProcessHost* host) override;
|
||||
|
@@ -16,6 +16,7 @@
|
||||
#include "ui/base/window_open_disposition.h"
|
||||
|
||||
class Browser;
|
||||
class Profile;
|
||||
|
||||
namespace cef {
|
||||
|
||||
@@ -40,6 +41,14 @@ class BrowserDelegate : public content::WebContentsDelegate {
|
||||
|
||||
~BrowserDelegate() override {}
|
||||
|
||||
// Optionally override Browser creation in
|
||||
// DevToolsWindow::CreateDevToolsBrowser. The returned Browser, if any, will
|
||||
// take ownership of |devtools_contents|.
|
||||
virtual Browser* CreateDevToolsBrowser(
|
||||
Profile* profile,
|
||||
Browser* opener,
|
||||
std::unique_ptr<content::WebContents>& devtools_contents) = 0;
|
||||
|
||||
// Optionally override chrome::AddWebContents behavior. This is most often
|
||||
// called via Browser::AddNewContents for new popup browsers and provides an
|
||||
// opportunity for CEF to create a new Browser instead of proceeding with
|
||||
|
@@ -12,6 +12,7 @@
|
||||
#include "libcef/browser/browser_platform_delegate.h"
|
||||
#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/media_access_query.h"
|
||||
#include "libcef/browser/request_context_impl.h"
|
||||
#include "libcef/browser/views/browser_view_impl.h"
|
||||
@@ -24,6 +25,8 @@
|
||||
#include "chrome/browser/ui/browser_tabstrip.h"
|
||||
#include "content/public/browser/global_routing_id.h"
|
||||
#include "content/public/browser/keyboard_event_processing_result.h"
|
||||
#include "content/public/browser/render_widget_host.h"
|
||||
#include "content/public/browser/render_widget_host_view.h"
|
||||
#include "content/public/common/input/native_web_keyboard_event.h"
|
||||
|
||||
using content::KeyboardEventProcessingResult;
|
||||
@@ -36,7 +39,8 @@ ChromeBrowserDelegate::ChromeBrowserDelegate(
|
||||
DCHECK(browser_);
|
||||
|
||||
if (opener) {
|
||||
DCHECK(browser->is_type_picture_in_picture());
|
||||
DCHECK(browser->is_type_picture_in_picture() ||
|
||||
browser->is_type_devtools());
|
||||
auto opener_host = ChromeBrowserHostImpl::GetBrowserForBrowser(opener);
|
||||
DCHECK(opener_host);
|
||||
if (opener_host) {
|
||||
@@ -47,6 +51,134 @@ ChromeBrowserDelegate::ChromeBrowserDelegate(
|
||||
|
||||
ChromeBrowserDelegate::~ChromeBrowserDelegate() = default;
|
||||
|
||||
Browser* ChromeBrowserDelegate::CreateDevToolsBrowser(
|
||||
Profile* profile,
|
||||
Browser* opener,
|
||||
std::unique_ptr<content::WebContents>& devtools_contents) {
|
||||
// |opener| is the same value that will be passed to the ChromeBrowserDelegate
|
||||
// constructor for the new popup Browser. It may be nullptr in certain rare
|
||||
// situations (e.g. if DevTools is launched for a WebContents that is not a
|
||||
// Browser Tab). In that case, the popup browser host will instead be created
|
||||
// via SetAsDelegate.
|
||||
auto opener_browser_host =
|
||||
opener ? ChromeBrowserHostImpl::GetBrowserForBrowser(opener) : nullptr;
|
||||
if (!opener_browser_host) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// We expect openers and popups to have the same Profile.
|
||||
CHECK_EQ(
|
||||
CefRequestContextImpl::GetProfile(opener_browser_host->request_context()),
|
||||
profile);
|
||||
|
||||
//
|
||||
// 1. Get configuration settings from the user and create the new platform
|
||||
// delegate. Logical equivalent of CefBrowserInfoManager::CanCreateWindow()
|
||||
// for normal popups.
|
||||
//
|
||||
|
||||
auto opener_client = opener_browser_host->GetClient();
|
||||
auto life_span_handler =
|
||||
opener_client ? opener_client->GetLifeSpanHandler() : nullptr;
|
||||
|
||||
CefBrowserCreateParams create_params;
|
||||
CefWindowInfo window_info;
|
||||
|
||||
// If |client| is empty, or if the user clears |client| in
|
||||
// OnBeforeDevToolsPopup, we'll use the result of GetDefaultClient() later on
|
||||
// in CreateBrowserHost().
|
||||
if (pending_show_devtools_params_) {
|
||||
// Start with the params passed to CefBrowserHost::ShowDevTools().
|
||||
create_params.client = pending_show_devtools_params_->client_;
|
||||
create_params.settings = pending_show_devtools_params_->settings_;
|
||||
window_info = pending_show_devtools_params_->window_info_;
|
||||
|
||||
// Pending params are only used a single time.
|
||||
pending_show_devtools_params_.reset();
|
||||
} else {
|
||||
// Start with the same client and settings as the opener.
|
||||
create_params.client = opener_client;
|
||||
create_params.settings = opener_browser_host->settings();
|
||||
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
window_info.SetAsPopup(nullptr, CefString());
|
||||
#endif
|
||||
}
|
||||
|
||||
// Start with the same extra info as the opener, for consistency with
|
||||
// current Alloy runtime behavior (see CefDevToolsFrontend::Show). This
|
||||
// value, if non-empty, will be read-only.
|
||||
create_params.extra_info = opener_browser_host->browser_info()->extra_info();
|
||||
DCHECK(!create_params.extra_info || create_params.extra_info->IsReadOnly());
|
||||
|
||||
// Use default (non-Views-hosted) window if OnBeforeDevToolsPopup is
|
||||
// unhandled.
|
||||
bool use_default_window = !life_span_handler;
|
||||
|
||||
if (life_span_handler) {
|
||||
life_span_handler->OnBeforeDevToolsPopup(
|
||||
opener_browser_host.get(), window_info, create_params.client,
|
||||
create_params.settings, create_params.extra_info, &use_default_window);
|
||||
}
|
||||
|
||||
if (opener_browser_host->platform_delegate()->HasExternalParent()) {
|
||||
// A parent window handle for DevTools creation is only supported if the
|
||||
// opener also has an external parent.
|
||||
create_params.MaybeSetWindowInfo(window_info);
|
||||
} else if (chrome_child_window::HasParentHandle(window_info)) {
|
||||
LOG(ERROR) << "Parent window handle not supported for this DevTools window";
|
||||
}
|
||||
|
||||
create_params.popup_with_views_hosted_opener =
|
||||
CefBrowserInfoManager::ShouldCreateViewsHostedPopup(opener_browser_host,
|
||||
use_default_window);
|
||||
|
||||
auto platform_delegate = CefBrowserPlatformDelegate::Create(create_params);
|
||||
CHECK(platform_delegate);
|
||||
|
||||
//
|
||||
// 2. Create the new browser host. Logical equivalent of WebContentsCreated()
|
||||
// for normal popups.
|
||||
//
|
||||
|
||||
// Create a new browser host that remains alive until the associated
|
||||
// WebContents is destroyed. Associate that browser host with the WebContents
|
||||
// and execute initial client callbacks. Deliver required information to the
|
||||
// renderer process.
|
||||
auto browser_host = CreateBrowserHostForPopup(
|
||||
devtools_contents.get(), create_params.settings, create_params.client,
|
||||
create_params.extra_info, std::move(platform_delegate),
|
||||
/*is_devtools_popup=*/true, opener_browser_host);
|
||||
|
||||
//
|
||||
// 3. Create the new Browser. Logical equivalent of AddWebContents() for
|
||||
// normal popups.
|
||||
//
|
||||
|
||||
// Use Browser creation params specific to DevTools popups.
|
||||
auto chrome_params = Browser::CreateParams::CreateForDevTools(profile);
|
||||
|
||||
// Pass |opener| to the ChromeBrowserDelegate constructor for the new popup
|
||||
// Browser.
|
||||
chrome_params.opener = opener;
|
||||
|
||||
// Create a new Browser and give it ownership of the new WebContents.
|
||||
// Results in a call to SetAsDelegate to associate the Browser with the
|
||||
// browser host.
|
||||
browser_host->AddNewContents(std::move(devtools_contents),
|
||||
std::move(chrome_params));
|
||||
|
||||
// Give the opener browser a reference to the new DevTools browser. Do this
|
||||
// last because don't want the client to attempt access to the DevTools
|
||||
// browser via opener browser methods (e.g. ShowDevTools, CloseDevTools, etc)
|
||||
// while creation is still in progress.
|
||||
opener_browser_host->SetDevToolsBrowserHost(browser_host->GetWeakPtr());
|
||||
|
||||
auto browser = browser_host->browser();
|
||||
CHECK(browser);
|
||||
return browser;
|
||||
}
|
||||
|
||||
std::unique_ptr<content::WebContents> ChromeBrowserDelegate::AddWebContents(
|
||||
std::unique_ptr<content::WebContents> new_contents) {
|
||||
if (CefBrowserInfoManager::GetInstance()->AddWebContents(
|
||||
@@ -56,7 +188,9 @@ std::unique_ptr<content::WebContents> ChromeBrowserDelegate::AddWebContents(
|
||||
ChromeBrowserHostImpl::GetBrowserForContents(new_contents.get());
|
||||
if (new_browser) {
|
||||
// Create a new Browser and give it ownership of the new WebContents.
|
||||
new_browser->AddNewContents(std::move(new_contents));
|
||||
// Results in a call to SetAsDelegate to associate the Browser with the
|
||||
// browser host.
|
||||
new_browser->AddNewContents(std::move(new_contents), std::nullopt);
|
||||
} else {
|
||||
LOG(ERROR) << "No host found for chrome popup browser";
|
||||
}
|
||||
@@ -90,19 +224,26 @@ void ChromeBrowserDelegate::SetAsDelegate(content::WebContents* web_contents,
|
||||
return;
|
||||
}
|
||||
|
||||
const bool is_devtools_popup = browser_->is_type_devtools();
|
||||
|
||||
// We should never reach here for DevTools popups that have an opener, as
|
||||
// CreateDevToolsBrowser should have already created the browser host.
|
||||
DCHECK(!is_devtools_popup || !opener_host_);
|
||||
|
||||
auto platform_delegate = CefBrowserPlatformDelegate::Create(create_params_);
|
||||
CHECK(platform_delegate);
|
||||
|
||||
auto browser_info = CefBrowserInfoManager::GetInstance()->CreateBrowserInfo(
|
||||
/*is_popup=*/false, /*is_windowless=*/false, create_params_.extra_info);
|
||||
is_devtools_popup, /*is_windowless=*/false, create_params_.extra_info);
|
||||
|
||||
auto request_context_impl =
|
||||
CefRequestContextImpl::GetOrCreateForRequestContext(
|
||||
create_params_.request_context);
|
||||
|
||||
CreateBrowser(web_contents, create_params_.settings, create_params_.client,
|
||||
std::move(platform_delegate), browser_info, /*opener=*/nullptr,
|
||||
request_context_impl);
|
||||
CreateBrowserHost(web_contents, create_params_.settings,
|
||||
create_params_.client, std::move(platform_delegate),
|
||||
browser_info, is_devtools_popup, /*opener=*/nullptr,
|
||||
request_context_impl);
|
||||
}
|
||||
|
||||
bool ChromeBrowserDelegate::ShowStatusBubble(bool show_by_default) {
|
||||
@@ -123,6 +264,11 @@ bool ChromeBrowserDelegate::ShowStatusBubble(bool show_by_default) {
|
||||
|
||||
bool ChromeBrowserDelegate::HandleCommand(int command_id,
|
||||
WindowOpenDisposition disposition) {
|
||||
// Verify that our enum matches Chromium's values.
|
||||
static_assert(static_cast<int>(CEF_WOD_MAX_VALUE) ==
|
||||
static_cast<int>(WindowOpenDisposition::MAX_VALUE),
|
||||
"enum mismatch");
|
||||
|
||||
if (auto browser = ChromeBrowserHostImpl::GetBrowserForBrowser(browser_)) {
|
||||
if (auto client = browser->GetClient()) {
|
||||
if (auto handler = client->GetCommandHandler()) {
|
||||
@@ -299,19 +445,13 @@ void ChromeBrowserDelegate::WebContentsCreated(
|
||||
return;
|
||||
}
|
||||
|
||||
auto browser_info =
|
||||
CefBrowserInfoManager::GetInstance()->CreatePopupBrowserInfo(
|
||||
new_contents, /*is_windowless=*/false, extra_info);
|
||||
CHECK(browser_info->is_popup());
|
||||
|
||||
// Popups must share the same RequestContext as the parent.
|
||||
auto request_context_impl = opener->request_context();
|
||||
CHECK(request_context_impl);
|
||||
|
||||
// We don't officially own |new_contents| until AddNewContents() is called.
|
||||
// However, we need to install observers/delegates here.
|
||||
CreateBrowser(new_contents, settings, client, std::move(platform_delegate),
|
||||
browser_info, opener, request_context_impl);
|
||||
// Create a new browser host that remains alive until the associated
|
||||
// WebContents is destroyed. Associate that browser host with the WebContents
|
||||
// and execute initial client callbacks. Deliver required information to the
|
||||
// renderer process.
|
||||
CreateBrowserHostForPopup(new_contents, settings, client, extra_info,
|
||||
std::move(platform_delegate),
|
||||
/*is_devtools_popup=*/false, opener);
|
||||
}
|
||||
|
||||
content::WebContents* ChromeBrowserDelegate::OpenURLFromTab(
|
||||
@@ -379,6 +519,14 @@ void ChromeBrowserDelegate::ExitFullscreenModeForTab(
|
||||
if (auto delegate = GetDelegateForWebContents(web_contents)) {
|
||||
delegate->ExitFullscreenModeForTab(web_contents);
|
||||
}
|
||||
|
||||
// Workaround for https://crbug.com/1500371. Ensure WebContents exits
|
||||
// fullscreen state by explicitly sending a resize message.
|
||||
if (auto* rwhv = web_contents->GetRenderWidgetHostView()) {
|
||||
if (auto* render_widget_host = rwhv->GetRenderWidgetHost()) {
|
||||
render_widget_host->SynchronizeVisualProperties();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ChromeBrowserDelegate::CanDownload(
|
||||
@@ -413,12 +561,19 @@ bool ChromeBrowserDelegate::HandleKeyboardEvent(
|
||||
return false;
|
||||
}
|
||||
|
||||
void ChromeBrowserDelegate::CreateBrowser(
|
||||
void ChromeBrowserDelegate::SetPendingShowDevToolsParams(
|
||||
std::unique_ptr<CefShowDevToolsParams> params) {
|
||||
DCHECK(!pending_show_devtools_params_);
|
||||
pending_show_devtools_params_ = std::move(params);
|
||||
}
|
||||
|
||||
CefRefPtr<ChromeBrowserHostImpl> ChromeBrowserDelegate::CreateBrowserHost(
|
||||
content::WebContents* web_contents,
|
||||
CefBrowserSettings settings,
|
||||
const CefBrowserSettings& settings,
|
||||
CefRefPtr<CefClient> client,
|
||||
std::unique_ptr<CefBrowserPlatformDelegate> platform_delegate,
|
||||
scoped_refptr<CefBrowserInfo> browser_info,
|
||||
bool is_devtools_popup,
|
||||
CefRefPtr<ChromeBrowserHostImpl> opener,
|
||||
CefRefPtr<CefRequestContextImpl> request_context_impl) {
|
||||
CEF_REQUIRE_UIT();
|
||||
@@ -454,12 +609,40 @@ void ChromeBrowserDelegate::CreateBrowser(
|
||||
CefRefPtr<ChromeBrowserHostImpl> browser_host =
|
||||
new ChromeBrowserHostImpl(settings, client, std::move(platform_delegate),
|
||||
browser_info, request_context_impl);
|
||||
browser_host->Attach(web_contents, opener);
|
||||
browser_host->Attach(web_contents, is_devtools_popup, opener);
|
||||
|
||||
// The Chrome browser for a popup won't be created until AddNewContents().
|
||||
// The Chrome browser for a normal popup won't be created until
|
||||
// AddNewContents().
|
||||
if (!opener) {
|
||||
browser_host->SetBrowser(browser_);
|
||||
}
|
||||
|
||||
return browser_host;
|
||||
}
|
||||
|
||||
CefRefPtr<ChromeBrowserHostImpl>
|
||||
ChromeBrowserDelegate::CreateBrowserHostForPopup(
|
||||
content::WebContents* web_contents,
|
||||
const CefBrowserSettings& settings,
|
||||
CefRefPtr<CefClient> client,
|
||||
CefRefPtr<CefDictionaryValue> extra_info,
|
||||
std::unique_ptr<CefBrowserPlatformDelegate> platform_delegate,
|
||||
bool is_devtools_popup,
|
||||
CefRefPtr<ChromeBrowserHostImpl> opener) {
|
||||
auto browser_info =
|
||||
CefBrowserInfoManager::GetInstance()->CreatePopupBrowserInfo(
|
||||
web_contents, /*is_windowless=*/false, extra_info);
|
||||
CHECK(browser_info->is_popup());
|
||||
|
||||
// Popups must share the same RequestContext as the parent.
|
||||
auto request_context_impl = opener->request_context();
|
||||
CHECK(request_context_impl);
|
||||
|
||||
// We don't officially own |web_contents| until AddNewContents() is called.
|
||||
// However, we need to install observers/delegates here.
|
||||
return CreateBrowserHost(web_contents, settings, client,
|
||||
std::move(platform_delegate), browser_info,
|
||||
is_devtools_popup, opener, request_context_impl);
|
||||
}
|
||||
|
||||
CefBrowserContentsDelegate* ChromeBrowserDelegate::GetDelegateForWebContents(
|
||||
|
@@ -39,6 +39,9 @@ class ChromeBrowserHostImpl;
|
||||
// but the Browser object will change when the tab is dragged between windows.
|
||||
class ChromeBrowserDelegate : public cef::BrowserDelegate {
|
||||
public:
|
||||
// The |create_params| and |opener| values are specified via the
|
||||
// Browser::CreateParams passed to Browser::Create. |opener| will only be
|
||||
// specified for certain special Browser types.
|
||||
ChromeBrowserDelegate(Browser* browser,
|
||||
const CefBrowserCreateParams& create_params,
|
||||
const Browser* opener);
|
||||
@@ -49,6 +52,10 @@ class ChromeBrowserDelegate : public cef::BrowserDelegate {
|
||||
~ChromeBrowserDelegate() override;
|
||||
|
||||
// cef::BrowserDelegate methods:
|
||||
Browser* CreateDevToolsBrowser(
|
||||
Profile* profile,
|
||||
Browser* opener,
|
||||
std::unique_ptr<content::WebContents>& devtools_contents) override;
|
||||
std::unique_ptr<content::WebContents> AddWebContents(
|
||||
std::unique_ptr<content::WebContents> new_contents) override;
|
||||
void OnWebContentsCreated(content::WebContents* new_contents) override;
|
||||
@@ -104,18 +111,31 @@ class ChromeBrowserDelegate : public cef::BrowserDelegate {
|
||||
content::WebContents* source,
|
||||
const content::NativeWebKeyboardEvent& event) override;
|
||||
|
||||
void SetPendingShowDevToolsParams(
|
||||
std::unique_ptr<CefShowDevToolsParams> params);
|
||||
|
||||
Browser* browser() const { return browser_; }
|
||||
|
||||
private:
|
||||
void CreateBrowser(
|
||||
CefRefPtr<ChromeBrowserHostImpl> CreateBrowserHost(
|
||||
content::WebContents* web_contents,
|
||||
CefBrowserSettings settings,
|
||||
const CefBrowserSettings& settings,
|
||||
CefRefPtr<CefClient> client,
|
||||
std::unique_ptr<CefBrowserPlatformDelegate> platform_delegate,
|
||||
scoped_refptr<CefBrowserInfo> browser_info,
|
||||
bool is_devtools_popup,
|
||||
CefRefPtr<ChromeBrowserHostImpl> opener,
|
||||
CefRefPtr<CefRequestContextImpl> request_context_impl);
|
||||
|
||||
CefRefPtr<ChromeBrowserHostImpl> CreateBrowserHostForPopup(
|
||||
content::WebContents* web_contents,
|
||||
const CefBrowserSettings& settings,
|
||||
CefRefPtr<CefClient> client,
|
||||
CefRefPtr<CefDictionaryValue> extra_info,
|
||||
std::unique_ptr<CefBrowserPlatformDelegate> platform_delegate,
|
||||
bool is_devtools_popup,
|
||||
CefRefPtr<ChromeBrowserHostImpl> opener);
|
||||
|
||||
CefBrowserContentsDelegate* GetDelegateForWebContents(
|
||||
content::WebContents* web_contents);
|
||||
|
||||
@@ -130,6 +150,8 @@ class ChromeBrowserDelegate : public cef::BrowserDelegate {
|
||||
absl::optional<bool> show_status_bubble_;
|
||||
absl::optional<SkRegion> draggable_region_;
|
||||
mutable absl::optional<bool> frameless_pip_;
|
||||
|
||||
std::unique_ptr<CefShowDevToolsParams> pending_show_devtools_params_;
|
||||
};
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_CHROME_CHROME_BROWSER_DELEGATE_H_
|
||||
|
@@ -6,6 +6,7 @@
|
||||
|
||||
#include "libcef/browser/browser_platform_delegate.h"
|
||||
#include "libcef/browser/chrome/browser_platform_delegate_chrome.h"
|
||||
#include "libcef/browser/chrome/chrome_browser_delegate.h"
|
||||
#include "libcef/browser/thread_util.h"
|
||||
#include "libcef/browser/views/browser_view_impl.h"
|
||||
#include "libcef/common/net/url_util.h"
|
||||
@@ -13,8 +14,8 @@
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "base/notreached.h"
|
||||
#include "chrome/browser/devtools/devtools_window.h"
|
||||
#include "chrome/browser/profiles/profile.h"
|
||||
#include "chrome/browser/ui/browser.h"
|
||||
#include "chrome/browser/ui/browser_commands.h"
|
||||
#include "chrome/browser/ui/browser_navigator.h"
|
||||
#include "chrome/browser/ui/browser_tabstrip.h"
|
||||
@@ -28,7 +29,7 @@
|
||||
// static
|
||||
CefRefPtr<ChromeBrowserHostImpl> ChromeBrowserHostImpl::Create(
|
||||
const CefBrowserCreateParams& params) {
|
||||
auto browser = CreateBrowser(params);
|
||||
auto browser = CreateBrowser(params, std::nullopt);
|
||||
|
||||
GURL url = url_util::MakeGURL(params.url, /*fixup=*/true);
|
||||
if (url.is_empty()) {
|
||||
@@ -99,7 +100,8 @@ CefRefPtr<ChromeBrowserHostImpl> ChromeBrowserHostImpl::GetBrowserForBrowser(
|
||||
ChromeBrowserHostImpl::~ChromeBrowserHostImpl() = default;
|
||||
|
||||
void ChromeBrowserHostImpl::AddNewContents(
|
||||
std::unique_ptr<content::WebContents> contents) {
|
||||
std::unique_ptr<content::WebContents> contents,
|
||||
std::optional<Browser::CreateParams> browser_create_params) {
|
||||
DCHECK(contents);
|
||||
DCHECK(!browser_);
|
||||
|
||||
@@ -111,7 +113,7 @@ void ChromeBrowserHostImpl::AddNewContents(
|
||||
params.browser_view = GetBrowserView();
|
||||
|
||||
// Create the new Browser representation.
|
||||
auto browser = CreateBrowser(params);
|
||||
auto browser = CreateBrowser(params, std::move(browser_create_params));
|
||||
|
||||
// Add the WebContents to the Browser.
|
||||
browser->tab_strip_model()->AddWebContents(
|
||||
@@ -199,20 +201,66 @@ void ChromeBrowserHostImpl::StopFinding(bool clearSelection) {
|
||||
NOTIMPLEMENTED();
|
||||
}
|
||||
|
||||
void ChromeBrowserHostImpl::ShowDevTools(const CefWindowInfo& windowInfo,
|
||||
CefRefPtr<CefClient> client,
|
||||
const CefBrowserSettings& settings,
|
||||
const CefPoint& inspect_element_at) {
|
||||
NOTIMPLEMENTED();
|
||||
void ChromeBrowserHostImpl::ShowDevToolsOnUIThread(
|
||||
std::unique_ptr<CefShowDevToolsParams> params) {
|
||||
CEF_REQUIRE_UIT();
|
||||
|
||||
if (!browser_) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto* web_contents = GetWebContents();
|
||||
if (!web_contents) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto* profile = CefRequestContextImpl::GetProfile(request_context());
|
||||
if (!DevToolsWindow::AllowDevToolsFor(profile, web_contents)) {
|
||||
LOG(WARNING) << "DevTools is not allowed for this browser";
|
||||
return;
|
||||
}
|
||||
|
||||
auto inspect_element_at = params->inspect_element_at_;
|
||||
|
||||
if (!devtools_browser_host_) {
|
||||
// Configure parameters for ChromeBrowserDelegate::CreateDevToolsBrowser
|
||||
// which will be called indirectly to create the DevTools window.
|
||||
auto chrome_browser_delegate =
|
||||
static_cast<ChromeBrowserDelegate*>(browser_->cef_delegate());
|
||||
chrome_browser_delegate->SetPendingShowDevToolsParams(std::move(params));
|
||||
}
|
||||
|
||||
// Focus the existing DevTools window or create a new one.
|
||||
if (!inspect_element_at.IsEmpty()) {
|
||||
DevToolsWindow::InspectElement(web_contents->GetPrimaryMainFrame(),
|
||||
inspect_element_at.x, inspect_element_at.y);
|
||||
} else {
|
||||
DevToolsWindow::OpenDevToolsWindow(web_contents, profile);
|
||||
}
|
||||
|
||||
// The DevTools browser host should now exist.
|
||||
DCHECK(devtools_browser_host_);
|
||||
}
|
||||
|
||||
void ChromeBrowserHostImpl::CloseDevTools() {
|
||||
NOTIMPLEMENTED();
|
||||
if (!CEF_CURRENTLY_ON_UIT()) {
|
||||
CEF_POST_TASK(CEF_UIT,
|
||||
base::BindOnce(&ChromeBrowserHostImpl::CloseDevTools, this));
|
||||
return;
|
||||
}
|
||||
|
||||
if (devtools_browser_host_) {
|
||||
devtools_browser_host_->TryCloseBrowser();
|
||||
}
|
||||
}
|
||||
|
||||
bool ChromeBrowserHostImpl::HasDevTools() {
|
||||
NOTIMPLEMENTED();
|
||||
return false;
|
||||
if (!CEF_CURRENTLY_ON_UIT()) {
|
||||
DCHECK(false) << "called on invalid thread";
|
||||
return false;
|
||||
}
|
||||
|
||||
return !!devtools_browser_host_;
|
||||
}
|
||||
|
||||
bool ChromeBrowserHostImpl::IsWindowRenderingDisabled() {
|
||||
@@ -332,6 +380,36 @@ bool ChromeBrowserHostImpl::IsBackgroundHost() {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ChromeBrowserHostImpl::CanExecuteChromeCommand(int command_id) {
|
||||
// Verify that this method is being called on the UI thread.
|
||||
if (!CEF_CURRENTLY_ON_UIT()) {
|
||||
DCHECK(false) << "called on invalid thread";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (browser_) {
|
||||
return chrome::SupportsCommand(browser_, command_id) &&
|
||||
chrome::IsCommandEnabled(browser_, command_id);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ChromeBrowserHostImpl::ExecuteChromeCommand(
|
||||
int command_id,
|
||||
cef_window_open_disposition_t disposition) {
|
||||
if (!CEF_CURRENTLY_ON_UIT()) {
|
||||
CEF_POST_TASK(CEF_UIT,
|
||||
base::BindOnce(&ChromeBrowserHostImpl::ExecuteChromeCommand,
|
||||
this, command_id, disposition));
|
||||
return;
|
||||
}
|
||||
|
||||
if (browser_) {
|
||||
chrome::ExecuteCommandWithDisposition(
|
||||
browser_, command_id, static_cast<WindowOpenDisposition>(disposition));
|
||||
}
|
||||
}
|
||||
|
||||
ChromeBrowserView* ChromeBrowserHostImpl::chrome_browser_view() const {
|
||||
if (browser_ && is_views_hosted_) {
|
||||
return static_cast<ChromeBrowserView*>(browser_->window());
|
||||
@@ -389,19 +467,16 @@ ChromeBrowserHostImpl::ChromeBrowserHostImpl(
|
||||
|
||||
// static
|
||||
Browser* ChromeBrowserHostImpl::CreateBrowser(
|
||||
const CefBrowserCreateParams& params) {
|
||||
// Get or create the request context and profile.
|
||||
CefRefPtr<CefRequestContextImpl> request_context_impl =
|
||||
CefRequestContextImpl::GetOrCreateForRequestContext(
|
||||
params.request_context);
|
||||
CHECK(request_context_impl);
|
||||
auto cef_browser_context = request_context_impl->GetBrowserContext();
|
||||
CHECK(cef_browser_context);
|
||||
auto profile = cef_browser_context->AsProfile();
|
||||
CHECK(profile);
|
||||
|
||||
Browser::CreateParams chrome_params =
|
||||
Browser::CreateParams(profile, /*user_gesture=*/false);
|
||||
const CefBrowserCreateParams& params,
|
||||
std::optional<Browser::CreateParams> browser_create_params) {
|
||||
Browser::CreateParams chrome_params = [¶ms, &browser_create_params]() {
|
||||
if (!browser_create_params.has_value()) {
|
||||
auto* profile = CefRequestContextImpl::GetProfile(params.request_context);
|
||||
return Browser::CreateParams(profile, /*user_gesture=*/false);
|
||||
} else {
|
||||
return std::move(*browser_create_params);
|
||||
}
|
||||
}();
|
||||
|
||||
// Pass |params| to cef::BrowserDelegate::Create from the Browser constructor.
|
||||
chrome_params.cef_params = base::MakeRefCounted<DelegateCreateParams>(params);
|
||||
@@ -412,10 +487,12 @@ Browser* ChromeBrowserHostImpl::CreateBrowser(
|
||||
// documentation.
|
||||
ChromeBrowserView* chrome_browser_view = nullptr;
|
||||
if (params.browser_view) {
|
||||
// Don't show most controls.
|
||||
chrome_params.type = Browser::TYPE_POPUP;
|
||||
// Don't show title bar or address.
|
||||
chrome_params.trusted_source = true;
|
||||
if (chrome_params.type == Browser::TYPE_NORMAL) {
|
||||
// Don't show most controls.
|
||||
chrome_params.type = Browser::TYPE_POPUP;
|
||||
// Don't show title bar or address.
|
||||
chrome_params.trusted_source = true;
|
||||
}
|
||||
|
||||
auto view_impl =
|
||||
static_cast<CefBrowserViewImpl*>(params.browser_view.get());
|
||||
@@ -456,6 +533,7 @@ Browser* ChromeBrowserHostImpl::CreateBrowser(
|
||||
}
|
||||
|
||||
void ChromeBrowserHostImpl::Attach(content::WebContents* web_contents,
|
||||
bool is_devtools_popup,
|
||||
CefRefPtr<ChromeBrowserHostImpl> opener) {
|
||||
DCHECK(web_contents);
|
||||
|
||||
@@ -464,7 +542,7 @@ void ChromeBrowserHostImpl::Attach(content::WebContents* web_contents,
|
||||
// new browser's platform delegate.
|
||||
opener->platform_delegate_->PopupWebContentsCreated(
|
||||
settings_, client_, web_contents, platform_delegate_.get(),
|
||||
/*is_devtools_popup=*/false);
|
||||
is_devtools_popup);
|
||||
}
|
||||
|
||||
platform_delegate_->WebContentsCreated(web_contents,
|
||||
@@ -480,7 +558,7 @@ void ChromeBrowserHostImpl::Attach(content::WebContents* web_contents,
|
||||
// Notify that the browser has been created. These must be delivered in the
|
||||
// expected order.
|
||||
|
||||
if (opener && opener->platform_delegate_) {
|
||||
if (opener) {
|
||||
// 1. Notify the opener browser's platform delegate. With Views this will
|
||||
// result in a call to CefBrowserViewDelegate::OnPopupBrowserViewCreated().
|
||||
// We want to call this method first because the implementation will often
|
||||
@@ -488,9 +566,7 @@ void ChromeBrowserHostImpl::Attach(content::WebContents* web_contents,
|
||||
// CefBrowserHost::GetWindowHandle() will return kNullWindowHandle in
|
||||
// OnAfterCreated(), which breaks client expectations (e.g. clients expect
|
||||
// everything about the browser to be valid at that time).
|
||||
opener->platform_delegate_->PopupBrowserCreated(
|
||||
this,
|
||||
/*is_devtools_popup=*/false);
|
||||
opener->platform_delegate_->PopupBrowserCreated(this, is_devtools_popup);
|
||||
}
|
||||
|
||||
// 2. Notify the browser's LifeSpanHandler. This must always be the first
|
||||
@@ -509,14 +585,27 @@ void ChromeBrowserHostImpl::Attach(content::WebContents* web_contents,
|
||||
|
||||
void ChromeBrowserHostImpl::SetBrowser(Browser* browser) {
|
||||
CEF_REQUIRE_UIT();
|
||||
if (browser == browser_) {
|
||||
return;
|
||||
}
|
||||
|
||||
browser_ = browser;
|
||||
static_cast<CefBrowserPlatformDelegateChrome*>(platform_delegate_.get())
|
||||
->set_chrome_browser(browser);
|
||||
if (browser_) {
|
||||
host_window_handle_ = platform_delegate_->GetHostWindowHandle();
|
||||
} else {
|
||||
host_window_handle_ = kNullWindowHandle;
|
||||
}
|
||||
}
|
||||
|
||||
void ChromeBrowserHostImpl::SetDevToolsBrowserHost(
|
||||
base::WeakPtr<ChromeBrowserHostImpl> devtools_browser_host) {
|
||||
CEF_REQUIRE_UIT();
|
||||
DCHECK(!devtools_browser_host_);
|
||||
devtools_browser_host_ = devtools_browser_host;
|
||||
}
|
||||
|
||||
void ChromeBrowserHostImpl::WindowDestroyed() {
|
||||
CEF_REQUIRE_UIT();
|
||||
if (auto view = chrome_browser_view()) {
|
||||
|
@@ -12,8 +12,8 @@
|
||||
#include "libcef/browser/chrome/browser_delegate.h"
|
||||
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "chrome/browser/ui/browser.h"
|
||||
|
||||
class Browser;
|
||||
class ChromeBrowserDelegate;
|
||||
class ChromeBrowserView;
|
||||
|
||||
@@ -72,10 +72,6 @@ class ChromeBrowserHostImpl : public CefBrowserHostBase {
|
||||
bool matchCase,
|
||||
bool findNext) override;
|
||||
void StopFinding(bool clearSelection) override;
|
||||
void ShowDevTools(const CefWindowInfo& windowInfo,
|
||||
CefRefPtr<CefClient> client,
|
||||
const CefBrowserSettings& settings,
|
||||
const CefPoint& inspect_element_at) override;
|
||||
void CloseDevTools() override;
|
||||
bool HasDevTools() override;
|
||||
bool IsWindowRenderingDisabled() override;
|
||||
@@ -114,6 +110,9 @@ class ChromeBrowserHostImpl : public CefBrowserHostBase {
|
||||
const CefSize& max_size) override;
|
||||
CefRefPtr<CefExtension> GetExtension() override;
|
||||
bool IsBackgroundHost() override;
|
||||
bool CanExecuteChromeCommand(int command_id) override;
|
||||
void ExecuteChromeCommand(int command_id,
|
||||
cef_window_open_disposition_t disposition) override;
|
||||
|
||||
Browser* browser() const { return browser_; }
|
||||
|
||||
@@ -126,6 +125,8 @@ class ChromeBrowserHostImpl : public CefBrowserHostBase {
|
||||
|
||||
protected:
|
||||
bool Navigate(const content::OpenURLParams& params) override;
|
||||
void ShowDevToolsOnUIThread(
|
||||
std::unique_ptr<CefShowDevToolsParams> params) override;
|
||||
|
||||
private:
|
||||
friend class ChromeBrowserDelegate;
|
||||
@@ -138,22 +139,32 @@ class ChromeBrowserHostImpl : public CefBrowserHostBase {
|
||||
CefRefPtr<CefRequestContextImpl> request_context);
|
||||
|
||||
// Create a new Browser without initializing the WebContents.
|
||||
static Browser* CreateBrowser(const CefBrowserCreateParams& params);
|
||||
// |browser_create_params| may be empty for default Browser creation behavior.
|
||||
static Browser* CreateBrowser(
|
||||
const CefBrowserCreateParams& params,
|
||||
std::optional<Browser::CreateParams> browser_create_params);
|
||||
|
||||
// Called from ChromeBrowserDelegate::CreateBrowser when this object is first
|
||||
// created. Must be called on the UI thread.
|
||||
void Attach(content::WebContents* web_contents,
|
||||
bool is_devtools_popup,
|
||||
CefRefPtr<ChromeBrowserHostImpl> opener);
|
||||
|
||||
// Called from ChromeBrowserDelegate::AddNewContents to take ownership of a
|
||||
// popup WebContents.
|
||||
void AddNewContents(std::unique_ptr<content::WebContents> contents);
|
||||
// popup WebContents. |browser_create_params| may be empty for default Browser
|
||||
// creation behavior.
|
||||
void AddNewContents(
|
||||
std::unique_ptr<content::WebContents> contents,
|
||||
std::optional<Browser::CreateParams> browser_create_params);
|
||||
|
||||
// Called when this object changes Browser ownership (e.g. initially created,
|
||||
// dragging between windows, etc). The old Browser, if any, will be cleared
|
||||
// before the new Browser is added. Must be called on the UI thread.
|
||||
void SetBrowser(Browser* browser);
|
||||
|
||||
void SetDevToolsBrowserHost(
|
||||
base::WeakPtr<ChromeBrowserHostImpl> devtools_browser_host);
|
||||
|
||||
// CefBrowserHostBase methods:
|
||||
void WindowDestroyed() override;
|
||||
bool WillBeDestroyed() const override;
|
||||
@@ -168,6 +179,8 @@ class ChromeBrowserHostImpl : public CefBrowserHostBase {
|
||||
Browser* browser_ = nullptr;
|
||||
CefWindowHandle host_window_handle_ = kNullWindowHandle;
|
||||
|
||||
base::WeakPtr<ChromeBrowserHostImpl> devtools_browser_host_;
|
||||
|
||||
base::WeakPtrFactory<ChromeBrowserHostImpl> weak_ptr_factory_{this};
|
||||
};
|
||||
|
||||
|
@@ -4,6 +4,8 @@
|
||||
|
||||
#include "libcef/browser/chrome/views/chrome_browser_frame.h"
|
||||
|
||||
#include "libcef/browser/chrome/chrome_browser_host_impl.h"
|
||||
|
||||
#include "chrome/browser/themes/theme_service.h"
|
||||
#include "chrome/browser/ui/browser.h"
|
||||
#include "chrome/browser/ui/browser_commands.h"
|
||||
@@ -57,3 +59,24 @@ ChromeBrowserFrame::CreateNonClientFrameView() {
|
||||
// Bypass the BrowserFrame implementation.
|
||||
return views::Widget::CreateNonClientFrameView();
|
||||
}
|
||||
|
||||
void ChromeBrowserFrame::Activate() {
|
||||
if (browser_view_ && browser_view_->browser() &&
|
||||
browser_view_->browser()->is_type_devtools()) {
|
||||
if (auto browser_host = ChromeBrowserHostImpl::GetBrowserForBrowser(
|
||||
browser_view_->browser())) {
|
||||
if (browser_host->platform_delegate()->HasExternalParent()) {
|
||||
// Handle activation of DevTools with external parent via the platform
|
||||
// delegate. On Windows the default platform implementation
|
||||
// (HWNDMessageHandler::Activate) will call SetForegroundWindow but that
|
||||
// doesn't seem to work for DevTools windows when activated via the
|
||||
// right-click context menu.
|
||||
browser_host->SetFocus(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Proceed with default handling.
|
||||
BrowserFrame::Activate();
|
||||
}
|
||||
|
@@ -103,6 +103,7 @@ class ChromeBrowserFrame : public BrowserFrame {
|
||||
views::internal::RootView* CreateRootView() override;
|
||||
std::unique_ptr<views::NonClientFrameView> CreateNonClientFrameView()
|
||||
override;
|
||||
void Activate() override;
|
||||
|
||||
BrowserView* browser_view() const { return browser_view_; }
|
||||
|
||||
|
@@ -126,8 +126,6 @@ class ChildBrowserViewDelegate : public CefBrowserViewDelegate {
|
||||
bool OnPopupBrowserViewCreated(CefRefPtr<CefBrowserView> browser_view,
|
||||
CefRefPtr<CefBrowserView> popup_browser_view,
|
||||
bool is_devtools) override {
|
||||
DCHECK(!is_devtools);
|
||||
|
||||
auto new_browser = static_cast<CefBrowserHostBase*>(
|
||||
popup_browser_view->GetBrowser().get());
|
||||
auto new_platform_delegate = new_browser->platform_delegate();
|
||||
|
@@ -202,14 +202,8 @@ class CefBrowserURLRequest::Context
|
||||
scoped_refptr<base::SequencedTaskRunner> task_runner) {
|
||||
CEF_REQUIRE_UIT();
|
||||
|
||||
// Get or create the request context and browser context.
|
||||
CefRefPtr<CefRequestContextImpl> request_context_impl =
|
||||
CefRequestContextImpl::GetOrCreateForRequestContext(request_context);
|
||||
CHECK(request_context_impl);
|
||||
CefBrowserContext* cef_browser_context =
|
||||
request_context_impl->GetBrowserContext();
|
||||
CHECK(cef_browser_context);
|
||||
auto browser_context = cef_browser_context->AsBrowserContext();
|
||||
auto* browser_context =
|
||||
CefRequestContextImpl::GetBrowserContext(request_context);
|
||||
CHECK(browser_context);
|
||||
|
||||
scoped_refptr<net_service::URLLoaderFactoryGetter> loader_factory_getter;
|
||||
|
@@ -89,6 +89,17 @@ class ResolveHostHelper : public network::ResolveHostClientBase {
|
||||
mojo::Receiver<network::mojom::ResolveHostClient> receiver_{this};
|
||||
};
|
||||
|
||||
CefBrowserContext* GetCefBrowserContext(
|
||||
CefRefPtr<CefRequestContext> request_context) {
|
||||
CEF_REQUIRE_UIT();
|
||||
CefRefPtr<CefRequestContextImpl> request_context_impl =
|
||||
CefRequestContextImpl::GetOrCreateForRequestContext(request_context);
|
||||
CHECK(request_context_impl);
|
||||
auto* cef_browser_context = request_context_impl->GetBrowserContext();
|
||||
CHECK(cef_browser_context);
|
||||
return cef_browser_context;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// CefBrowserContext
|
||||
@@ -184,6 +195,21 @@ CefRequestContextImpl::GetOrCreateForRequestContext(
|
||||
return CefRequestContextImpl::GetOrCreateRequestContext(config);
|
||||
}
|
||||
|
||||
content::BrowserContext* CefRequestContextImpl::GetBrowserContext(
|
||||
CefRefPtr<CefRequestContext> request_context) {
|
||||
auto* browser_context =
|
||||
GetCefBrowserContext(request_context)->AsBrowserContext();
|
||||
CHECK(browser_context);
|
||||
return browser_context;
|
||||
}
|
||||
|
||||
Profile* CefRequestContextImpl::GetProfile(
|
||||
CefRefPtr<CefRequestContext> request_context) {
|
||||
auto* profile = GetCefBrowserContext(request_context)->AsProfile();
|
||||
CHECK(profile);
|
||||
return profile;
|
||||
}
|
||||
|
||||
bool CefRequestContextImpl::VerifyBrowserContext() const {
|
||||
if (!CEF_CURRENTLY_ON_UIT()) {
|
||||
DCHECK(false) << "called on invalid thread";
|
||||
|
@@ -38,6 +38,15 @@ class CefRequestContextImpl : public CefRequestContext {
|
||||
static CefRefPtr<CefRequestContextImpl> GetOrCreateForRequestContext(
|
||||
CefRefPtr<CefRequestContext> request_context);
|
||||
|
||||
// Returns the BrowserContext for the specified |request_context|. Will return
|
||||
// the global BrowserContext if |request_context| is NULL.
|
||||
static content::BrowserContext* GetBrowserContext(
|
||||
CefRefPtr<CefRequestContext> request_context);
|
||||
|
||||
// Returns the Profile for the specified |request_context|. Will return the
|
||||
// global Profile if |request_context| is NULL.
|
||||
static Profile* GetProfile(CefRefPtr<CefRequestContext> request_context);
|
||||
|
||||
// Verify that the browser context can be directly accessed (e.g. on the UI
|
||||
// thread and initialized).
|
||||
bool VerifyBrowserContext() const;
|
||||
|
@@ -121,12 +121,18 @@ void CefNativeWidgetMac::OnWindowFullscreenTransitionStart() {
|
||||
views::NativeWidgetMac::OnWindowFullscreenTransitionStart();
|
||||
if (IsCefWindowInitialized()) {
|
||||
window_delegate_->OnWindowFullscreenTransition(window_, false);
|
||||
if (browser_view_) {
|
||||
browser_view_->FullscreenStateChanging();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CefNativeWidgetMac::OnWindowFullscreenTransitionComplete() {
|
||||
views::NativeWidgetMac::OnWindowFullscreenTransitionComplete();
|
||||
if (IsCefWindowInitialized()) {
|
||||
if (browser_view_) {
|
||||
browser_view_->FullscreenStateChanged();
|
||||
}
|
||||
window_delegate_->OnWindowFullscreenTransition(window_, true);
|
||||
}
|
||||
}
|
||||
|
@@ -669,7 +669,8 @@ void CefWindowImpl::SetAccelerator(int command_id,
|
||||
int key_code,
|
||||
bool shift_pressed,
|
||||
bool ctrl_pressed,
|
||||
bool alt_pressed) {
|
||||
bool alt_pressed,
|
||||
bool high_priority) {
|
||||
CEF_REQUIRE_VALID_RETURN_VOID();
|
||||
if (!widget_) {
|
||||
return;
|
||||
@@ -698,7 +699,10 @@ void CefWindowImpl::SetAccelerator(int command_id,
|
||||
views::FocusManager* focus_manager = widget_->GetFocusManager();
|
||||
DCHECK(focus_manager);
|
||||
focus_manager->RegisterAccelerator(
|
||||
accelerator, ui::AcceleratorManager::kNormalPriority, this);
|
||||
accelerator,
|
||||
high_priority ? ui::AcceleratorManager::kHighPriority
|
||||
: ui::AcceleratorManager::kNormalPriority,
|
||||
this);
|
||||
}
|
||||
|
||||
void CefWindowImpl::RemoveAccelerator(int command_id) {
|
||||
|
@@ -86,7 +86,8 @@ class CefWindowImpl
|
||||
int key_code,
|
||||
bool shift_pressed,
|
||||
bool ctrl_pressed,
|
||||
bool alt_pressed) override;
|
||||
bool alt_pressed,
|
||||
bool high_priority) override;
|
||||
void RemoveAccelerator(int command_id) override;
|
||||
void RemoveAllAccelerators() override;
|
||||
|
||||
|
@@ -296,6 +296,13 @@ class CefValueBase : public CefType, public CefValueController::Object {
|
||||
// True if access to the underlying value is read-only.
|
||||
inline bool read_only() const { return read_only_; }
|
||||
|
||||
// Convert a writable value to read-only. The reverse could be surprising and
|
||||
// is therefore not supported.
|
||||
void MarkReadOnly() {
|
||||
DCHECK(!read_only_);
|
||||
read_only_ = true;
|
||||
}
|
||||
|
||||
// True if the underlying value has been detached.
|
||||
inline bool detached() const { return !controller_.get(); }
|
||||
|
||||
|
@@ -606,6 +606,11 @@ CefRefPtr<CefBinaryValue> CefBinaryValueImpl::Copy() {
|
||||
return new CefBinaryValueImpl(const_value().Clone());
|
||||
}
|
||||
|
||||
const void* CefBinaryValueImpl::GetRawData() {
|
||||
CEF_VALUE_VERIFY_RETURN(false, nullptr);
|
||||
return const_value().GetBlob().data();
|
||||
}
|
||||
|
||||
size_t CefBinaryValueImpl::GetSize() {
|
||||
CEF_VALUE_VERIFY_RETURN(false, 0);
|
||||
return const_value().GetBlob().size();
|
||||
|
@@ -177,6 +177,7 @@ class CefBinaryValueImpl : public CefValueBase<CefBinaryValue, base::Value> {
|
||||
bool IsSame(CefRefPtr<CefBinaryValue> that) override;
|
||||
bool IsEqual(CefRefPtr<CefBinaryValue> that) override;
|
||||
CefRefPtr<CefBinaryValue> Copy() override;
|
||||
const void* GetRawData() override;
|
||||
size_t GetSize() override;
|
||||
size_t GetData(void* buffer, size_t buffer_size, size_t data_offset) override;
|
||||
|
||||
|
@@ -2368,6 +2368,61 @@ bool CefV8ValueImpl::NeuterArrayBuffer() {
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t CefV8ValueImpl::GetArrayBufferByteLength() {
|
||||
size_t rv = 0;
|
||||
CEF_V8_REQUIRE_ISOLATE_RETURN(rv);
|
||||
if (type_ != TYPE_OBJECT) {
|
||||
DCHECK(false) << "V8 value is not an object";
|
||||
return rv;
|
||||
}
|
||||
|
||||
v8::Isolate* isolate = handle_->isolate();
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
|
||||
v8::Local<v8::Context> context = isolate->GetCurrentContext();
|
||||
if (context.IsEmpty()) {
|
||||
DCHECK(false) << "not currently in a V8 context";
|
||||
return rv;
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> value = handle_->GetNewV8Handle(false);
|
||||
if (!value->IsArrayBuffer()) {
|
||||
DCHECK(false) << "V8 value is not an array buffer";
|
||||
return rv;
|
||||
}
|
||||
|
||||
v8::Local<v8::Object> obj = value->ToObject(context).ToLocalChecked();
|
||||
return v8::Local<v8::ArrayBuffer>::Cast(obj)->ByteLength();
|
||||
}
|
||||
|
||||
void* CefV8ValueImpl::GetArrayBufferData() {
|
||||
void* rv = nullptr;
|
||||
CEF_V8_REQUIRE_ISOLATE_RETURN(rv);
|
||||
if (type_ != TYPE_OBJECT) {
|
||||
DCHECK(false) << "V8 value is not an object";
|
||||
return rv;
|
||||
}
|
||||
|
||||
v8::Isolate* isolate = handle_->isolate();
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
|
||||
v8::Local<v8::Context> context = isolate->GetCurrentContext();
|
||||
if (context.IsEmpty()) {
|
||||
DCHECK(false) << "not currently in a V8 context";
|
||||
return rv;
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> value = handle_->GetNewV8Handle(false);
|
||||
if (!value->IsArrayBuffer()) {
|
||||
DCHECK(false) << "V8 value is not an array buffer";
|
||||
return rv;
|
||||
}
|
||||
|
||||
v8::Local<v8::Object> obj = value->ToObject(context).ToLocalChecked();
|
||||
v8::Local<v8::ArrayBuffer> arr = v8::Local<v8::ArrayBuffer>::Cast(obj);
|
||||
return arr->Data();
|
||||
}
|
||||
|
||||
CefString CefV8ValueImpl::GetFunctionName() {
|
||||
CefString rv;
|
||||
CEF_V8_REQUIRE_OBJECT_RETURN(rv);
|
||||
|
@@ -274,6 +274,8 @@ class CefV8ValueImpl : public CefV8Value {
|
||||
CefRefPtr<CefV8ArrayBufferReleaseCallback> GetArrayBufferReleaseCallback()
|
||||
override;
|
||||
bool NeuterArrayBuffer() override;
|
||||
size_t GetArrayBufferByteLength() override;
|
||||
void* GetArrayBufferData() override;
|
||||
CefString GetFunctionName() override;
|
||||
CefRefPtr<CefV8Handler> GetFunctionHandler() override;
|
||||
CefRefPtr<CefV8Value> ExecuteFunction(
|
||||
|
@@ -9,7 +9,7 @@
|
||||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=905b24443e08e2d3e2464d5f4138e97904be3e9e$
|
||||
// $hash=8da36dc268f2f9beb26abc105656f3b04b1d46ed$
|
||||
//
|
||||
|
||||
#include "libcef_dll/cpptoc/binary_value_cpptoc.h"
|
||||
@@ -140,6 +140,25 @@ binary_value_copy(struct _cef_binary_value_t* self) {
|
||||
return CefBinaryValueCppToC::Wrap(_retval);
|
||||
}
|
||||
|
||||
const void* CEF_CALLBACK
|
||||
binary_value_get_raw_data(struct _cef_binary_value_t* self) {
|
||||
shutdown_checker::AssertNotShutdown();
|
||||
|
||||
DCHECK(self);
|
||||
if (!self) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// This manual implementation can be removed once support for 'const void*'
|
||||
// is integrated into the CEF translator tool (issue #3591).
|
||||
|
||||
// Execute
|
||||
const void* _retval = CefBinaryValueCppToC::Get(self)->GetRawData();
|
||||
|
||||
// Return type: simple_byaddr
|
||||
return _retval;
|
||||
}
|
||||
|
||||
size_t CEF_CALLBACK binary_value_get_size(struct _cef_binary_value_t* self) {
|
||||
shutdown_checker::AssertNotShutdown();
|
||||
|
||||
@@ -193,6 +212,7 @@ CefBinaryValueCppToC::CefBinaryValueCppToC() {
|
||||
GetStruct()->is_same = binary_value_is_same;
|
||||
GetStruct()->is_equal = binary_value_is_equal;
|
||||
GetStruct()->copy = binary_value_copy;
|
||||
GetStruct()->get_raw_data = binary_value_get_raw_data;
|
||||
GetStruct()->get_size = binary_value_get_size;
|
||||
GetStruct()->get_data = binary_value_get_data;
|
||||
}
|
||||
|
@@ -9,7 +9,7 @@
|
||||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=497607653318fe0245cbe18c8911e39867e16249$
|
||||
// $hash=a5c3b05b23c536eba7ce2e7242c3840e93729b29$
|
||||
//
|
||||
|
||||
#include "libcef_dll/cpptoc/browser_host_cpptoc.h"
|
||||
@@ -1435,6 +1435,77 @@ int CEF_CALLBACK browser_host_is_audio_muted(struct _cef_browser_host_t* self) {
|
||||
return _retval;
|
||||
}
|
||||
|
||||
int CEF_CALLBACK browser_host_is_fullscreen(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)->IsFullscreen();
|
||||
|
||||
// Return type: bool
|
||||
return _retval;
|
||||
}
|
||||
|
||||
void CEF_CALLBACK browser_host_exit_fullscreen(struct _cef_browser_host_t* self,
|
||||
int will_cause_resize) {
|
||||
shutdown_checker::AssertNotShutdown();
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Execute
|
||||
CefBrowserHostCppToC::Get(self)->ExitFullscreen(will_cause_resize ? true
|
||||
: false);
|
||||
}
|
||||
|
||||
int CEF_CALLBACK
|
||||
browser_host_can_execute_chrome_command(struct _cef_browser_host_t* self,
|
||||
int command_id) {
|
||||
shutdown_checker::AssertNotShutdown();
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Execute
|
||||
bool _retval =
|
||||
CefBrowserHostCppToC::Get(self)->CanExecuteChromeCommand(command_id);
|
||||
|
||||
// Return type: bool
|
||||
return _retval;
|
||||
}
|
||||
|
||||
void CEF_CALLBACK
|
||||
browser_host_execute_chrome_command(struct _cef_browser_host_t* self,
|
||||
int command_id,
|
||||
cef_window_open_disposition_t disposition) {
|
||||
shutdown_checker::AssertNotShutdown();
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Execute
|
||||
CefBrowserHostCppToC::Get(self)->ExecuteChromeCommand(command_id,
|
||||
disposition);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// CONSTRUCTOR - Do not edit by hand.
|
||||
@@ -1512,6 +1583,11 @@ CefBrowserHostCppToC::CefBrowserHostCppToC() {
|
||||
GetStruct()->is_background_host = browser_host_is_background_host;
|
||||
GetStruct()->set_audio_muted = browser_host_set_audio_muted;
|
||||
GetStruct()->is_audio_muted = browser_host_is_audio_muted;
|
||||
GetStruct()->is_fullscreen = browser_host_is_fullscreen;
|
||||
GetStruct()->exit_fullscreen = browser_host_exit_fullscreen;
|
||||
GetStruct()->can_execute_chrome_command =
|
||||
browser_host_can_execute_chrome_command;
|
||||
GetStruct()->execute_chrome_command = browser_host_execute_chrome_command;
|
||||
}
|
||||
|
||||
// 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=e96fe0660b55afa20c3bb5fdebc85635ccc53d09$
|
||||
// $hash=4990c06888649a2cb06ba7028f16f9cd762f3ad0$
|
||||
//
|
||||
|
||||
#include "libcef_dll/cpptoc/life_span_handler_cpptoc.h"
|
||||
@@ -169,6 +169,126 @@ int CEF_CALLBACK life_span_handler_on_before_popup(
|
||||
return _retval;
|
||||
}
|
||||
|
||||
void CEF_CALLBACK life_span_handler_on_before_dev_tools_popup(
|
||||
struct _cef_life_span_handler_t* self,
|
||||
cef_browser_t* browser,
|
||||
cef_window_info_t* windowInfo,
|
||||
cef_client_t** client,
|
||||
struct _cef_browser_settings_t* settings,
|
||||
struct _cef_dictionary_value_t** extra_info,
|
||||
int* use_default_window) {
|
||||
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: windowInfo; type: struct_byref
|
||||
DCHECK(windowInfo);
|
||||
if (!windowInfo) {
|
||||
return;
|
||||
}
|
||||
if (!template_util::has_valid_size(windowInfo)) {
|
||||
DCHECK(false) << "invalid windowInfo->[base.]size";
|
||||
return;
|
||||
}
|
||||
// Verify param: client; type: refptr_same_byref
|
||||
DCHECK(client);
|
||||
if (!client) {
|
||||
return;
|
||||
}
|
||||
// Verify param: settings; type: struct_byref
|
||||
DCHECK(settings);
|
||||
if (!settings) {
|
||||
return;
|
||||
}
|
||||
if (!template_util::has_valid_size(settings)) {
|
||||
DCHECK(false) << "invalid settings->[base.]size";
|
||||
return;
|
||||
}
|
||||
// Verify param: extra_info; type: refptr_diff_byref
|
||||
DCHECK(extra_info);
|
||||
if (!extra_info) {
|
||||
return;
|
||||
}
|
||||
// Verify param: use_default_window; type: bool_byaddr
|
||||
DCHECK(use_default_window);
|
||||
if (!use_default_window) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Translate param: windowInfo; type: struct_byref
|
||||
CefWindowInfo windowInfoObj;
|
||||
if (windowInfo) {
|
||||
windowInfoObj.AttachTo(*windowInfo);
|
||||
}
|
||||
// Translate param: client; type: refptr_same_byref
|
||||
CefRefPtr<CefClient> clientPtr;
|
||||
if (client && *client) {
|
||||
clientPtr = CefClientCppToC::Unwrap(*client);
|
||||
}
|
||||
CefClient* clientOrig = clientPtr.get();
|
||||
// Translate param: settings; type: struct_byref
|
||||
CefBrowserSettings settingsObj;
|
||||
if (settings) {
|
||||
settingsObj.AttachTo(*settings);
|
||||
}
|
||||
// Translate param: extra_info; type: refptr_diff_byref
|
||||
CefRefPtr<CefDictionaryValue> extra_infoPtr;
|
||||
if (extra_info && *extra_info) {
|
||||
extra_infoPtr = CefDictionaryValueCToCpp::Wrap(*extra_info);
|
||||
}
|
||||
CefDictionaryValue* extra_infoOrig = extra_infoPtr.get();
|
||||
// Translate param: use_default_window; type: bool_byaddr
|
||||
bool use_default_windowBool =
|
||||
(use_default_window && *use_default_window) ? true : false;
|
||||
|
||||
// Execute
|
||||
CefLifeSpanHandlerCppToC::Get(self)->OnBeforeDevToolsPopup(
|
||||
CefBrowserCToCpp::Wrap(browser), windowInfoObj, clientPtr, settingsObj,
|
||||
extra_infoPtr, &use_default_windowBool);
|
||||
|
||||
// Restore param: windowInfo; type: struct_byref
|
||||
if (windowInfo) {
|
||||
windowInfoObj.DetachTo(*windowInfo);
|
||||
}
|
||||
// Restore param: client; type: refptr_same_byref
|
||||
if (client) {
|
||||
if (clientPtr.get()) {
|
||||
if (clientPtr.get() != clientOrig) {
|
||||
*client = CefClientCppToC::Wrap(clientPtr);
|
||||
}
|
||||
} else {
|
||||
*client = nullptr;
|
||||
}
|
||||
}
|
||||
// Restore param: settings; type: struct_byref
|
||||
if (settings) {
|
||||
settingsObj.DetachTo(*settings);
|
||||
}
|
||||
// Restore param: extra_info; type: refptr_diff_byref
|
||||
if (extra_info) {
|
||||
if (extra_infoPtr.get()) {
|
||||
if (extra_infoPtr.get() != extra_infoOrig) {
|
||||
*extra_info = CefDictionaryValueCToCpp::Unwrap(extra_infoPtr);
|
||||
}
|
||||
} else {
|
||||
*extra_info = nullptr;
|
||||
}
|
||||
}
|
||||
// Restore param: use_default_window; type: bool_byaddr
|
||||
if (use_default_window) {
|
||||
*use_default_window = use_default_windowBool ? true : false;
|
||||
}
|
||||
}
|
||||
|
||||
void CEF_CALLBACK
|
||||
life_span_handler_on_after_created(struct _cef_life_span_handler_t* self,
|
||||
cef_browser_t* browser) {
|
||||
@@ -244,6 +364,8 @@ life_span_handler_on_before_close(struct _cef_life_span_handler_t* self,
|
||||
|
||||
CefLifeSpanHandlerCppToC::CefLifeSpanHandlerCppToC() {
|
||||
GetStruct()->on_before_popup = life_span_handler_on_before_popup;
|
||||
GetStruct()->on_before_dev_tools_popup =
|
||||
life_span_handler_on_before_dev_tools_popup;
|
||||
GetStruct()->on_after_created = life_span_handler_on_after_created;
|
||||
GetStruct()->do_close = life_span_handler_do_close;
|
||||
GetStruct()->on_before_close = life_span_handler_on_before_close;
|
||||
|
@@ -9,7 +9,7 @@
|
||||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=3bc6db85e54dc87c1e592291be01820547e0989f$
|
||||
// $hash=4356ad718a385149741e4c8bbbe5d5290466ed40$
|
||||
//
|
||||
|
||||
#include "libcef_dll/cpptoc/shared_memory_region_cpptoc.h"
|
||||
@@ -64,6 +64,9 @@ shared_memory_region_memory(struct _cef_shared_memory_region_t* self) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// This manual implementation can be removed once support for 'void*'
|
||||
// is integrated into the CEF translator tool (issue #3591).
|
||||
|
||||
// Execute
|
||||
void* _retval = CefSharedMemoryRegionCppToC::Get(self)->Memory();
|
||||
|
||||
|
@@ -9,7 +9,7 @@
|
||||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=ecd6caa0c415b57e93bc66f3c7a4cfb547f022c1$
|
||||
// $hash=21d8fb47eb282f40fb9d602f44b8c1fd4ff44dea$
|
||||
//
|
||||
|
||||
#include "libcef_dll/cpptoc/v8value_cpptoc.h"
|
||||
@@ -138,16 +138,12 @@ CEF_EXPORT cef_v8value_t* cef_v8value_create_array_buffer(
|
||||
cef_v8array_buffer_release_callback_t* release_callback) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Verify param: buffer; type: simple_byaddr
|
||||
DCHECK(buffer);
|
||||
if (!buffer) {
|
||||
return NULL;
|
||||
}
|
||||
// Verify param: release_callback; type: refptr_diff
|
||||
DCHECK(release_callback);
|
||||
if (!release_callback) {
|
||||
return NULL;
|
||||
}
|
||||
// Unverified params: buffer
|
||||
|
||||
// Execute
|
||||
CefRefPtr<CefV8Value> _retval = CefV8Value::CreateArrayBuffer(
|
||||
@@ -948,6 +944,38 @@ int CEF_CALLBACK v8value_neuter_array_buffer(struct _cef_v8value_t* self) {
|
||||
return _retval;
|
||||
}
|
||||
|
||||
size_t CEF_CALLBACK
|
||||
v8value_get_array_buffer_byte_length(struct _cef_v8value_t* self) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Execute
|
||||
size_t _retval = CefV8ValueCppToC::Get(self)->GetArrayBufferByteLength();
|
||||
|
||||
// Return type: simple
|
||||
return _retval;
|
||||
}
|
||||
|
||||
void* CEF_CALLBACK v8value_get_array_buffer_data(struct _cef_v8value_t* self) {
|
||||
DCHECK(self);
|
||||
if (!self) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// This manual implementation can be removed once support for 'void*'
|
||||
// is integrated into the CEF translator tool (issue #3591).
|
||||
|
||||
// Execute
|
||||
void* _retval = CefV8ValueCppToC::Get(self)->GetArrayBufferData();
|
||||
|
||||
// Return type: simple_byaddr
|
||||
return _retval;
|
||||
}
|
||||
|
||||
cef_string_userfree_t CEF_CALLBACK
|
||||
v8value_get_function_name(struct _cef_v8value_t* self) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
@@ -1153,6 +1181,9 @@ CefV8ValueCppToC::CefV8ValueCppToC() {
|
||||
GetStruct()->get_array_buffer_release_callback =
|
||||
v8value_get_array_buffer_release_callback;
|
||||
GetStruct()->neuter_array_buffer = v8value_neuter_array_buffer;
|
||||
GetStruct()->get_array_buffer_byte_length =
|
||||
v8value_get_array_buffer_byte_length;
|
||||
GetStruct()->get_array_buffer_data = v8value_get_array_buffer_data;
|
||||
GetStruct()->get_function_name = v8value_get_function_name;
|
||||
GetStruct()->get_function_handler = v8value_get_function_handler;
|
||||
GetStruct()->execute_function = v8value_execute_function;
|
||||
|
@@ -9,7 +9,7 @@
|
||||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=23777aea864e9abf38c2e2c5d79a40d6bd22876d$
|
||||
// $hash=38a50bca35881beb6400f3ad5d81b0a5ec86331d$
|
||||
//
|
||||
|
||||
#include "libcef_dll/cpptoc/views/window_cpptoc.h"
|
||||
@@ -672,7 +672,8 @@ void CEF_CALLBACK window_set_accelerator(struct _cef_window_t* self,
|
||||
int key_code,
|
||||
int shift_pressed,
|
||||
int ctrl_pressed,
|
||||
int alt_pressed) {
|
||||
int alt_pressed,
|
||||
int high_priority) {
|
||||
shutdown_checker::AssertNotShutdown();
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
@@ -685,7 +686,8 @@ void CEF_CALLBACK window_set_accelerator(struct _cef_window_t* self,
|
||||
// Execute
|
||||
CefWindowCppToC::Get(self)->SetAccelerator(
|
||||
command_id, key_code, shift_pressed ? true : false,
|
||||
ctrl_pressed ? true : false, alt_pressed ? true : false);
|
||||
ctrl_pressed ? true : false, alt_pressed ? true : false,
|
||||
high_priority ? true : false);
|
||||
}
|
||||
|
||||
void CEF_CALLBACK window_remove_accelerator(struct _cef_window_t* self,
|
||||
|
@@ -9,7 +9,7 @@
|
||||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=caaf5dfe8d56c784e213b1590c21194f08084b70$
|
||||
// $hash=f42bab3d9e4ff45faf1fd8071646a8e5bed64177$
|
||||
//
|
||||
|
||||
#include "libcef_dll/ctocpp/binary_value_ctocpp.h"
|
||||
@@ -139,6 +139,24 @@ CefRefPtr<CefBinaryValue> CefBinaryValueCToCpp::Copy() {
|
||||
return CefBinaryValueCToCpp::Wrap(_retval);
|
||||
}
|
||||
|
||||
NO_SANITIZE("cfi-icall") const void* CefBinaryValueCToCpp::GetRawData() {
|
||||
shutdown_checker::AssertNotShutdown();
|
||||
|
||||
cef_binary_value_t* _struct = GetStruct();
|
||||
if (CEF_MEMBER_MISSING(_struct, get_raw_data)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// This manual implementation can be removed once support for 'const void*'
|
||||
// is integrated into the CEF translator tool (issue #3591).
|
||||
|
||||
// Execute
|
||||
const void* _retval = _struct->get_raw_data(_struct);
|
||||
|
||||
// Return type: simple_byaddr
|
||||
return _retval;
|
||||
}
|
||||
|
||||
NO_SANITIZE("cfi-icall") size_t CefBinaryValueCToCpp::GetSize() {
|
||||
shutdown_checker::AssertNotShutdown();
|
||||
|
||||
|
@@ -9,7 +9,7 @@
|
||||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=b6f011a6c26b4264084eb68dae0d63032c07013c$
|
||||
// $hash=2e0ac9b73ba6bdb4b07ee0f8c445974359c5862f$
|
||||
//
|
||||
|
||||
#ifndef CEF_LIBCEF_DLL_CTOCPP_BINARY_VALUE_CTOCPP_H_
|
||||
@@ -39,6 +39,7 @@ class CefBinaryValueCToCpp : public CefCToCppRefCounted<CefBinaryValueCToCpp,
|
||||
bool IsSame(CefRefPtr<CefBinaryValue> that) override;
|
||||
bool IsEqual(CefRefPtr<CefBinaryValue> that) override;
|
||||
CefRefPtr<CefBinaryValue> Copy() override;
|
||||
const void* GetRawData() override;
|
||||
size_t GetSize() override;
|
||||
size_t GetData(void* buffer, size_t buffer_size, size_t data_offset) override;
|
||||
};
|
||||
|
@@ -9,7 +9,7 @@
|
||||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=cd4e4aa1670f0c887090e23f5e7e3a01e5de9d13$
|
||||
// $hash=b06e3bbc86769bbc2485d4ab9530b5c39dc73243$
|
||||
//
|
||||
|
||||
#include "libcef_dll/ctocpp/browser_host_ctocpp.h"
|
||||
@@ -1229,6 +1229,73 @@ NO_SANITIZE("cfi-icall") bool CefBrowserHostCToCpp::IsAudioMuted() {
|
||||
return _retval ? true : false;
|
||||
}
|
||||
|
||||
NO_SANITIZE("cfi-icall") bool CefBrowserHostCToCpp::IsFullscreen() {
|
||||
shutdown_checker::AssertNotShutdown();
|
||||
|
||||
cef_browser_host_t* _struct = GetStruct();
|
||||
if (CEF_MEMBER_MISSING(_struct, is_fullscreen)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Execute
|
||||
int _retval = _struct->is_fullscreen(_struct);
|
||||
|
||||
// Return type: bool
|
||||
return _retval ? true : false;
|
||||
}
|
||||
|
||||
NO_SANITIZE("cfi-icall")
|
||||
void CefBrowserHostCToCpp::ExitFullscreen(bool will_cause_resize) {
|
||||
shutdown_checker::AssertNotShutdown();
|
||||
|
||||
cef_browser_host_t* _struct = GetStruct();
|
||||
if (CEF_MEMBER_MISSING(_struct, exit_fullscreen)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Execute
|
||||
_struct->exit_fullscreen(_struct, will_cause_resize);
|
||||
}
|
||||
|
||||
NO_SANITIZE("cfi-icall")
|
||||
bool CefBrowserHostCToCpp::CanExecuteChromeCommand(int command_id) {
|
||||
shutdown_checker::AssertNotShutdown();
|
||||
|
||||
cef_browser_host_t* _struct = GetStruct();
|
||||
if (CEF_MEMBER_MISSING(_struct, can_execute_chrome_command)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Execute
|
||||
int _retval = _struct->can_execute_chrome_command(_struct, command_id);
|
||||
|
||||
// Return type: bool
|
||||
return _retval ? true : false;
|
||||
}
|
||||
|
||||
NO_SANITIZE("cfi-icall")
|
||||
void CefBrowserHostCToCpp::ExecuteChromeCommand(
|
||||
int command_id,
|
||||
cef_window_open_disposition_t disposition) {
|
||||
shutdown_checker::AssertNotShutdown();
|
||||
|
||||
cef_browser_host_t* _struct = GetStruct();
|
||||
if (CEF_MEMBER_MISSING(_struct, execute_chrome_command)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Execute
|
||||
_struct->execute_chrome_command(_struct, command_id, disposition);
|
||||
}
|
||||
|
||||
// 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=b4e11c91197cd5d6ccbe3a0d96aaae3792a6e05c$
|
||||
// $hash=e07873b7e67c06fb54dafa370eca83d2c698ffb9$
|
||||
//
|
||||
|
||||
#ifndef CEF_LIBCEF_DLL_CTOCPP_BROWSER_HOST_CTOCPP_H_
|
||||
@@ -134,6 +134,11 @@ class CefBrowserHostCToCpp : public CefCToCppRefCounted<CefBrowserHostCToCpp,
|
||||
bool IsBackgroundHost() override;
|
||||
void SetAudioMuted(bool mute) override;
|
||||
bool IsAudioMuted() override;
|
||||
bool IsFullscreen() override;
|
||||
void ExitFullscreen(bool will_cause_resize) override;
|
||||
bool CanExecuteChromeCommand(int command_id) override;
|
||||
void ExecuteChromeCommand(int command_id,
|
||||
cef_window_open_disposition_t disposition) 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=d141b95304de99ab093db8f6c524a05e26f4edb5$
|
||||
// $hash=d85695db88a025b1f7e4e4604f3085da29d5eabf$
|
||||
//
|
||||
|
||||
#include "libcef_dll/ctocpp/life_span_handler_ctocpp.h"
|
||||
@@ -109,6 +109,76 @@ bool CefLifeSpanHandlerCToCpp::OnBeforePopup(
|
||||
return _retval ? true : false;
|
||||
}
|
||||
|
||||
NO_SANITIZE("cfi-icall")
|
||||
void CefLifeSpanHandlerCToCpp::OnBeforeDevToolsPopup(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefWindowInfo& windowInfo,
|
||||
CefRefPtr<CefClient>& client,
|
||||
CefBrowserSettings& settings,
|
||||
CefRefPtr<CefDictionaryValue>& extra_info,
|
||||
bool* use_default_window) {
|
||||
shutdown_checker::AssertNotShutdown();
|
||||
|
||||
cef_life_span_handler_t* _struct = GetStruct();
|
||||
if (CEF_MEMBER_MISSING(_struct, on_before_dev_tools_popup)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Verify param: browser; type: refptr_diff
|
||||
DCHECK(browser.get());
|
||||
if (!browser.get()) {
|
||||
return;
|
||||
}
|
||||
// Verify param: use_default_window; type: bool_byaddr
|
||||
DCHECK(use_default_window);
|
||||
if (!use_default_window) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Translate param: client; type: refptr_same_byref
|
||||
cef_client_t* clientStruct = NULL;
|
||||
if (client.get()) {
|
||||
clientStruct = CefClientCToCpp::Unwrap(client);
|
||||
}
|
||||
cef_client_t* clientOrig = clientStruct;
|
||||
// Translate param: extra_info; type: refptr_diff_byref
|
||||
cef_dictionary_value_t* extra_infoStruct = NULL;
|
||||
if (extra_info.get()) {
|
||||
extra_infoStruct = CefDictionaryValueCppToC::Wrap(extra_info);
|
||||
}
|
||||
cef_dictionary_value_t* extra_infoOrig = extra_infoStruct;
|
||||
// Translate param: use_default_window; type: bool_byaddr
|
||||
int use_default_windowInt = use_default_window ? *use_default_window : 0;
|
||||
|
||||
// Execute
|
||||
_struct->on_before_dev_tools_popup(_struct, CefBrowserCppToC::Wrap(browser),
|
||||
&windowInfo, &clientStruct, &settings,
|
||||
&extra_infoStruct, &use_default_windowInt);
|
||||
|
||||
// Restore param:client; type: refptr_same_byref
|
||||
if (clientStruct) {
|
||||
if (clientStruct != clientOrig) {
|
||||
client = CefClientCToCpp::Wrap(clientStruct);
|
||||
}
|
||||
} else {
|
||||
client = nullptr;
|
||||
}
|
||||
// Restore param:extra_info; type: refptr_diff_byref
|
||||
if (extra_infoStruct) {
|
||||
if (extra_infoStruct != extra_infoOrig) {
|
||||
extra_info = CefDictionaryValueCppToC::Unwrap(extra_infoStruct);
|
||||
}
|
||||
} else {
|
||||
extra_info = nullptr;
|
||||
}
|
||||
// Restore param:use_default_window; type: bool_byaddr
|
||||
if (use_default_window) {
|
||||
*use_default_window = use_default_windowInt ? true : false;
|
||||
}
|
||||
}
|
||||
|
||||
NO_SANITIZE("cfi-icall")
|
||||
void CefLifeSpanHandlerCToCpp::OnAfterCreated(CefRefPtr<CefBrowser> browser) {
|
||||
shutdown_checker::AssertNotShutdown();
|
||||
|
@@ -9,7 +9,7 @@
|
||||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=229117f1ecb1cc27b5ab5eebd79e64c30d73a855$
|
||||
// $hash=53f00e60e361c79c69a8f19474a234d5011454f5$
|
||||
//
|
||||
|
||||
#ifndef CEF_LIBCEF_DLL_CTOCPP_LIFE_SPAN_HANDLER_CTOCPP_H_
|
||||
@@ -49,6 +49,12 @@ class CefLifeSpanHandlerCToCpp
|
||||
CefBrowserSettings& settings,
|
||||
CefRefPtr<CefDictionaryValue>& extra_info,
|
||||
bool* no_javascript_access) override;
|
||||
void OnBeforeDevToolsPopup(CefRefPtr<CefBrowser> browser,
|
||||
CefWindowInfo& windowInfo,
|
||||
CefRefPtr<CefClient>& client,
|
||||
CefBrowserSettings& settings,
|
||||
CefRefPtr<CefDictionaryValue>& extra_info,
|
||||
bool* use_default_window) override;
|
||||
void OnAfterCreated(CefRefPtr<CefBrowser> browser) override;
|
||||
bool DoClose(CefRefPtr<CefBrowser> browser) override;
|
||||
void OnBeforeClose(CefRefPtr<CefBrowser> browser) override;
|
||||
|
@@ -9,7 +9,7 @@
|
||||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=31516110398f9fe682988645d74ac8789b712181$
|
||||
// $hash=a396f422ed18fe4aae90d4fef3750b4726279c7e$
|
||||
//
|
||||
|
||||
#include "libcef_dll/ctocpp/shared_memory_region_ctocpp.h"
|
||||
@@ -59,6 +59,9 @@ NO_SANITIZE("cfi-icall") void* CefSharedMemoryRegionCToCpp::Memory() {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// This manual implementation can be removed once support for 'void*'
|
||||
// is integrated into the CEF translator tool (issue #3591).
|
||||
|
||||
// Execute
|
||||
void* _retval = _struct->memory(_struct);
|
||||
|
||||
|
@@ -9,7 +9,7 @@
|
||||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=459c331b0c02f55c4b700761ad2132d7320fd467$
|
||||
// $hash=f67b0996d7e2133f3f28f2d8ba5446c5ff40aaba$
|
||||
//
|
||||
|
||||
#include "libcef_dll/ctocpp/v8value_ctocpp.h"
|
||||
@@ -147,16 +147,12 @@ CefRefPtr<CefV8Value> CefV8Value::CreateArrayBuffer(
|
||||
CefRefPtr<CefV8ArrayBufferReleaseCallback> release_callback) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Verify param: buffer; type: simple_byaddr
|
||||
DCHECK(buffer);
|
||||
if (!buffer) {
|
||||
return nullptr;
|
||||
}
|
||||
// Verify param: release_callback; type: refptr_diff
|
||||
DCHECK(release_callback.get());
|
||||
if (!release_callback.get()) {
|
||||
return nullptr;
|
||||
}
|
||||
// Unverified params: buffer
|
||||
|
||||
// Execute
|
||||
cef_v8value_t* _retval = cef_v8value_create_array_buffer(
|
||||
@@ -957,6 +953,37 @@ NO_SANITIZE("cfi-icall") bool CefV8ValueCToCpp::NeuterArrayBuffer() {
|
||||
return _retval ? true : false;
|
||||
}
|
||||
|
||||
NO_SANITIZE("cfi-icall") size_t CefV8ValueCToCpp::GetArrayBufferByteLength() {
|
||||
cef_v8value_t* _struct = GetStruct();
|
||||
if (CEF_MEMBER_MISSING(_struct, get_array_buffer_byte_length)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Execute
|
||||
size_t _retval = _struct->get_array_buffer_byte_length(_struct);
|
||||
|
||||
// Return type: simple
|
||||
return _retval;
|
||||
}
|
||||
|
||||
NO_SANITIZE("cfi-icall") void* CefV8ValueCToCpp::GetArrayBufferData() {
|
||||
cef_v8value_t* _struct = GetStruct();
|
||||
if (CEF_MEMBER_MISSING(_struct, get_array_buffer_data)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// This manual implementation can be removed once support for 'void*'
|
||||
// is integrated into the CEF translator tool (issue #3591).
|
||||
|
||||
// Execute
|
||||
void* _retval = _struct->get_array_buffer_data(_struct);
|
||||
|
||||
// Return type: simple_byaddr
|
||||
return _retval;
|
||||
}
|
||||
|
||||
NO_SANITIZE("cfi-icall") CefString CefV8ValueCToCpp::GetFunctionName() {
|
||||
cef_v8value_t* _struct = GetStruct();
|
||||
if (CEF_MEMBER_MISSING(_struct, get_function_name)) {
|
||||
|
@@ -9,7 +9,7 @@
|
||||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=cab5b018f6706a3c8496865e0c9f30fcbc94cdd8$
|
||||
// $hash=c81cc0910be6678c0512c5423b8fc5dc1df42743$
|
||||
//
|
||||
|
||||
#ifndef CEF_LIBCEF_DLL_CTOCPP_V8VALUE_CTOCPP_H_
|
||||
@@ -83,6 +83,8 @@ class CefV8ValueCToCpp
|
||||
CefRefPtr<CefV8ArrayBufferReleaseCallback> GetArrayBufferReleaseCallback()
|
||||
override;
|
||||
bool NeuterArrayBuffer() override;
|
||||
size_t GetArrayBufferByteLength() override;
|
||||
void* GetArrayBufferData() override;
|
||||
CefString GetFunctionName() override;
|
||||
CefRefPtr<CefV8Handler> GetFunctionHandler() override;
|
||||
CefRefPtr<CefV8Value> ExecuteFunction(
|
||||
|
@@ -9,7 +9,7 @@
|
||||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=b6b0a2a563b475163aa71b20af6ec2ac8c1f0cae$
|
||||
// $hash=c8f164d20875c8071837c04abb44e09672d894af$
|
||||
//
|
||||
|
||||
#include "libcef_dll/ctocpp/views/window_ctocpp.h"
|
||||
@@ -663,7 +663,8 @@ void CefWindowCToCpp::SetAccelerator(int command_id,
|
||||
int key_code,
|
||||
bool shift_pressed,
|
||||
bool ctrl_pressed,
|
||||
bool alt_pressed) {
|
||||
bool alt_pressed,
|
||||
bool high_priority) {
|
||||
shutdown_checker::AssertNotShutdown();
|
||||
|
||||
cef_window_t* _struct = GetStruct();
|
||||
@@ -675,7 +676,7 @@ void CefWindowCToCpp::SetAccelerator(int command_id,
|
||||
|
||||
// Execute
|
||||
_struct->set_accelerator(_struct, command_id, key_code, shift_pressed,
|
||||
ctrl_pressed, alt_pressed);
|
||||
ctrl_pressed, alt_pressed, high_priority);
|
||||
}
|
||||
|
||||
NO_SANITIZE("cfi-icall")
|
||||
|
@@ -9,7 +9,7 @@
|
||||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=2a7aaed7d4296e29dca74345cf2b2d4db221a738$
|
||||
// $hash=d0c31c38bf29c9b44f645e69a912b6b8a4030066$
|
||||
//
|
||||
|
||||
#ifndef CEF_LIBCEF_DLL_CTOCPP_VIEWS_WINDOW_CTOCPP_H_
|
||||
@@ -83,7 +83,8 @@ class CefWindowCToCpp
|
||||
int key_code,
|
||||
bool shift_pressed,
|
||||
bool ctrl_pressed,
|
||||
bool alt_pressed) override;
|
||||
bool alt_pressed,
|
||||
bool high_priority) override;
|
||||
void RemoveAccelerator(int command_id) override;
|
||||
void RemoveAllAccelerators() override;
|
||||
|
||||
|
@@ -9,11 +9,11 @@
|
||||
#include <set>
|
||||
|
||||
#include "include/base/cef_callback.h"
|
||||
#include "include/cef_shared_process_message_builder.h"
|
||||
#include "include/cef_task.h"
|
||||
#include "include/wrapper/cef_closure_task.h"
|
||||
#include "include/wrapper/cef_helpers.h"
|
||||
#include "libcef_dll/wrapper/cef_browser_info_map.h"
|
||||
#include "libcef_dll/wrapper/cef_message_router_utils.h"
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -47,126 +47,7 @@ bool ValidateConfig(CefMessageRouterConfig& config) {
|
||||
return true;
|
||||
}
|
||||
|
||||
struct MessageHeader {
|
||||
int context_id;
|
||||
int request_id;
|
||||
bool is_success;
|
||||
};
|
||||
|
||||
struct ParsedMessage {
|
||||
int context_id;
|
||||
int request_id;
|
||||
bool success;
|
||||
int error_code;
|
||||
CefString message;
|
||||
};
|
||||
|
||||
size_t GetByteLength(const CefString& value) {
|
||||
return value.size() * sizeof(CefString::char_type);
|
||||
}
|
||||
|
||||
size_t GetMessageSize(const CefString& response) {
|
||||
return sizeof(MessageHeader) + GetByteLength(response);
|
||||
}
|
||||
|
||||
void CopyResponseIntoMemory(void* memory, const CefString& response) {
|
||||
const size_t bytes = response.size() * sizeof(CefString::char_type);
|
||||
void* dest = static_cast<uint8_t*>(memory) + sizeof(MessageHeader);
|
||||
memcpy(dest, response.c_str(), bytes);
|
||||
}
|
||||
|
||||
CefString GetStringFromMemory(const void* memory, size_t size) {
|
||||
const size_t bytes = size - sizeof(MessageHeader);
|
||||
const size_t string_len = bytes / sizeof(CefString::char_type);
|
||||
const CefString::char_type* src =
|
||||
reinterpret_cast<const CefString::char_type*>(
|
||||
static_cast<const uint8_t*>(memory) + sizeof(MessageHeader));
|
||||
constexpr bool copy = true;
|
||||
CefString result;
|
||||
result.FromString(src, string_len, copy);
|
||||
return result;
|
||||
}
|
||||
|
||||
CefRefPtr<CefProcessMessage> BuildListMessage(const std::string& message_name,
|
||||
int context_id,
|
||||
int request_id,
|
||||
const CefString& response) {
|
||||
auto message = CefProcessMessage::Create(message_name);
|
||||
CefRefPtr<CefListValue> args = message->GetArgumentList();
|
||||
args->SetInt(0, context_id);
|
||||
args->SetInt(1, request_id);
|
||||
args->SetBool(2, true); // Indicates a success result.
|
||||
args->SetString(3, response);
|
||||
return message;
|
||||
}
|
||||
|
||||
CefRefPtr<CefProcessMessage> BuildBinaryMessage(const std::string& message_name,
|
||||
int context_id,
|
||||
int request_id,
|
||||
const CefString& response) {
|
||||
const size_t message_size = GetMessageSize(response);
|
||||
auto builder =
|
||||
CefSharedProcessMessageBuilder::Create(message_name, message_size);
|
||||
if (!builder->IsValid()) {
|
||||
LOG(ERROR) << "Failed to allocate shared memory region of size "
|
||||
<< message_size;
|
||||
// Use list message as a fallback
|
||||
return BuildListMessage(message_name, context_id, request_id, response);
|
||||
}
|
||||
|
||||
auto header = static_cast<MessageHeader*>(builder->Memory());
|
||||
header->context_id = context_id;
|
||||
header->request_id = request_id;
|
||||
header->is_success = true;
|
||||
|
||||
CopyResponseIntoMemory(builder->Memory(), response);
|
||||
|
||||
return builder->Build();
|
||||
}
|
||||
|
||||
CefRefPtr<CefProcessMessage> BuildMessage(size_t threshold,
|
||||
const std::string& message_name,
|
||||
int context_id,
|
||||
int request_id,
|
||||
const CefString& response) {
|
||||
if (GetByteLength(response) <= threshold) {
|
||||
return BuildListMessage(message_name, context_id, request_id, response);
|
||||
} else {
|
||||
return BuildBinaryMessage(message_name, context_id, request_id, response);
|
||||
}
|
||||
}
|
||||
|
||||
ParsedMessage ParseMessage(const CefRefPtr<CefProcessMessage>& message) {
|
||||
if (auto args = message->GetArgumentList()) {
|
||||
DCHECK_GT(args->GetSize(), 3U);
|
||||
|
||||
const int context_id = args->GetInt(0);
|
||||
const int request_id = args->GetInt(1);
|
||||
const bool is_success = args->GetBool(2);
|
||||
|
||||
if (is_success) {
|
||||
return ParsedMessage{context_id, request_id, is_success, 0,
|
||||
args->GetString(3)};
|
||||
}
|
||||
|
||||
DCHECK_EQ(args->GetSize(), 5U);
|
||||
return ParsedMessage{context_id, request_id, is_success, args->GetInt(3),
|
||||
args->GetString(4)};
|
||||
}
|
||||
|
||||
if (const auto region = message->GetSharedMemoryRegion()) {
|
||||
if (region->IsValid()) {
|
||||
DCHECK_GE(region->Size(), sizeof(MessageHeader));
|
||||
auto header = static_cast<const MessageHeader*>(region->Memory());
|
||||
DCHECK(header->is_success);
|
||||
return ParsedMessage{
|
||||
header->context_id, header->request_id, header->is_success, 0,
|
||||
GetStringFromMemory(region->Memory(), region->Size())};
|
||||
}
|
||||
}
|
||||
|
||||
return ParsedMessage{};
|
||||
}
|
||||
namespace cmru = cef_message_router_utils;
|
||||
|
||||
/**
|
||||
* @brief A helper template for generating ID values.
|
||||
@@ -204,11 +85,15 @@ class CefMessageRouterBrowserSideImpl : public CefMessageRouterBrowserSide {
|
||||
CallbackImpl(CefRefPtr<CefMessageRouterBrowserSideImpl> router,
|
||||
int browser_id,
|
||||
int64_t query_id,
|
||||
bool persistent)
|
||||
bool persistent,
|
||||
size_t message_size_threshold,
|
||||
const std::string& query_message_name)
|
||||
: router_(router),
|
||||
browser_id_(browser_id),
|
||||
query_id_(query_id),
|
||||
persistent_(persistent) {}
|
||||
persistent_(persistent),
|
||||
message_size_threshold_(message_size_threshold),
|
||||
query_message_name_(query_message_name) {}
|
||||
|
||||
CallbackImpl(const CallbackImpl&) = delete;
|
||||
CallbackImpl& operator=(const CallbackImpl&) = delete;
|
||||
@@ -221,44 +106,36 @@ class CefMessageRouterBrowserSideImpl : public CefMessageRouterBrowserSide {
|
||||
}
|
||||
|
||||
void Success(const CefString& response) override {
|
||||
if (!CefCurrentlyOn(TID_UI)) {
|
||||
// Must execute on the UI thread to access member variables.
|
||||
CefPostTask(TID_UI,
|
||||
base::BindOnce(&CallbackImpl::Success, this, response));
|
||||
return;
|
||||
}
|
||||
auto builder = cmru::CreateBrowserResponseBuilder(
|
||||
message_size_threshold_, query_message_name_, response);
|
||||
|
||||
if (router_) {
|
||||
CefPostTask(
|
||||
TID_UI,
|
||||
base::BindOnce(&CefMessageRouterBrowserSideImpl::OnCallbackSuccess,
|
||||
router_.get(), browser_id_, query_id_, response));
|
||||
// We need to post task here for two reasons:
|
||||
// 1) To safely access member variables.
|
||||
// 2) To let the router to persist the query information before
|
||||
// the Success callback is executed.
|
||||
CefPostTask(TID_UI,
|
||||
base::BindOnce(&CallbackImpl::SuccessImpl, this, builder));
|
||||
}
|
||||
|
||||
if (!persistent_) {
|
||||
// Non-persistent callbacks are only good for a single use.
|
||||
router_ = nullptr;
|
||||
}
|
||||
}
|
||||
void Success(const void* data, size_t size) override {
|
||||
auto builder = cmru::CreateBrowserResponseBuilder(
|
||||
message_size_threshold_, query_message_name_, data, size);
|
||||
|
||||
// We need to post task here for two reasons:
|
||||
// 1) To safely access member variables.
|
||||
// 2) To let the router to persist the query information before
|
||||
// the Success callback is executed.
|
||||
CefPostTask(TID_UI,
|
||||
base::BindOnce(&CallbackImpl::SuccessImpl, this, builder));
|
||||
}
|
||||
|
||||
void Failure(int error_code, const CefString& error_message) override {
|
||||
if (!CefCurrentlyOn(TID_UI)) {
|
||||
// Must execute on the UI thread to access member variables.
|
||||
CefPostTask(TID_UI, base::BindOnce(&CallbackImpl::Failure, this,
|
||||
error_code, error_message));
|
||||
return;
|
||||
}
|
||||
|
||||
if (router_) {
|
||||
CefPostTask(
|
||||
TID_UI,
|
||||
base::BindOnce(&CefMessageRouterBrowserSideImpl::OnCallbackFailure,
|
||||
router_.get(), browser_id_, query_id_, error_code,
|
||||
error_message));
|
||||
|
||||
// Failure always invalidates the callback.
|
||||
router_ = nullptr;
|
||||
}
|
||||
// We need to post task here for two reasons:
|
||||
// 1) To safely access member variables.
|
||||
// 2) To give previosly submitted tasks by the Success calls to execute
|
||||
// before we invalidate the callback.
|
||||
CefPostTask(TID_UI, base::BindOnce(&CallbackImpl::FailureImpl, this,
|
||||
error_code, error_message));
|
||||
}
|
||||
|
||||
void Detach() {
|
||||
@@ -267,10 +144,37 @@ class CefMessageRouterBrowserSideImpl : public CefMessageRouterBrowserSide {
|
||||
}
|
||||
|
||||
private:
|
||||
void SuccessImpl(const CefRefPtr<cmru::BrowserResponseBuilder>& builder) {
|
||||
if (!router_) {
|
||||
return;
|
||||
}
|
||||
|
||||
router_->OnCallbackSuccess(browser_id_, query_id_, builder);
|
||||
|
||||
if (!persistent_) {
|
||||
// Non-persistent callbacks are only good for a single use.
|
||||
router_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void FailureImpl(int error_code, const CefString& error_message) {
|
||||
if (!router_) {
|
||||
return;
|
||||
}
|
||||
|
||||
router_->OnCallbackFailure(browser_id_, query_id_, error_code,
|
||||
error_message);
|
||||
|
||||
// Failure always invalidates the callback.
|
||||
router_ = nullptr;
|
||||
}
|
||||
|
||||
CefRefPtr<CefMessageRouterBrowserSideImpl> router_;
|
||||
const int browser_id_;
|
||||
const int64_t query_id_;
|
||||
const bool persistent_;
|
||||
const size_t message_size_threshold_;
|
||||
const std::string query_message_name_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING(CallbackImpl);
|
||||
};
|
||||
@@ -388,13 +292,10 @@ class CefMessageRouterBrowserSideImpl : public CefMessageRouterBrowserSide {
|
||||
|
||||
const std::string& message_name = message->GetName();
|
||||
if (message_name == query_message_name_) {
|
||||
CefRefPtr<CefListValue> args = message->GetArgumentList();
|
||||
DCHECK_EQ(args->GetSize(), 4U);
|
||||
|
||||
const int context_id = args->GetInt(0);
|
||||
const int request_id = args->GetInt(1);
|
||||
const CefString& request = args->GetString(2);
|
||||
const bool persistent = args->GetBool(3);
|
||||
cmru::RendererMessage content = cmru::ParseRendererMessage(message);
|
||||
const int context_id = content.context_id;
|
||||
const int request_id = content.request_id;
|
||||
const bool persistent = content.is_persistent;
|
||||
|
||||
if (handler_set_.empty()) {
|
||||
// No handlers so cancel the query.
|
||||
@@ -405,40 +306,38 @@ class CefMessageRouterBrowserSideImpl : public CefMessageRouterBrowserSide {
|
||||
const int browser_id = browser->GetIdentifier();
|
||||
const int64_t query_id = query_id_generator_.GetNextId();
|
||||
|
||||
CefRefPtr<CallbackImpl> callback(
|
||||
new CallbackImpl(this, browser_id, query_id, persistent));
|
||||
CefRefPtr<CallbackImpl> callback =
|
||||
new CallbackImpl(this, browser_id, query_id, persistent,
|
||||
config_.message_size_threshold, query_message_name_);
|
||||
|
||||
// Make a copy of the handler list in case the user adds or removes a
|
||||
// handler while we're iterating.
|
||||
HandlerSet handler_set = handler_set_;
|
||||
const HandlerSet handlers = handler_set_;
|
||||
|
||||
bool handled = false;
|
||||
HandlerSet::const_iterator it_handler = handler_set.begin();
|
||||
for (; it_handler != handler_set.end(); ++it_handler) {
|
||||
handled = (*it_handler)
|
||||
->OnQuery(browser, frame, query_id, request, persistent,
|
||||
callback.get());
|
||||
if (handled) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
Handler* handler = std::visit(
|
||||
[&](const auto& arg) -> CefMessageRouterBrowserSide::Handler* {
|
||||
for (auto handler : handlers) {
|
||||
bool handled = handler->OnQuery(browser, frame, query_id, arg,
|
||||
persistent, callback.get());
|
||||
if (handled) {
|
||||
return handler;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
},
|
||||
content.payload);
|
||||
|
||||
// If the query isn't handled nothing should be keeping a reference to
|
||||
// the callback.
|
||||
DCHECK(handled || callback->HasOneRef());
|
||||
DCHECK(handler != nullptr || callback->HasOneRef());
|
||||
|
||||
if (handled) {
|
||||
if (handler) {
|
||||
// Persist the query information until the callback executes.
|
||||
// It's safe to do this here because the callback will execute
|
||||
// asynchronously.
|
||||
QueryInfo* info = new QueryInfo;
|
||||
info->browser = browser;
|
||||
info->frame = frame;
|
||||
info->context_id = context_id;
|
||||
info->request_id = request_id;
|
||||
info->persistent = persistent;
|
||||
info->callback = callback;
|
||||
info->handler = *(it_handler);
|
||||
QueryInfo* info =
|
||||
new QueryInfo{browser, frame, context_id, request_id,
|
||||
persistent, callback, handler};
|
||||
browser_query_info_map_.Add(browser_id, query_id, info);
|
||||
} else {
|
||||
// Invalidate the callback.
|
||||
@@ -527,15 +426,17 @@ class CefMessageRouterBrowserSideImpl : public CefMessageRouterBrowserSide {
|
||||
}
|
||||
|
||||
// Called by CallbackImpl on success.
|
||||
void OnCallbackSuccess(int browser_id,
|
||||
int64_t query_id,
|
||||
const CefString& response) {
|
||||
void OnCallbackSuccess(
|
||||
int browser_id,
|
||||
int64_t query_id,
|
||||
const CefRefPtr<cmru::BrowserResponseBuilder>& builder) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
|
||||
bool removed;
|
||||
QueryInfo* info = GetQueryInfo(browser_id, query_id, false, &removed);
|
||||
if (info) {
|
||||
SendQuerySuccess(info, response);
|
||||
SendQuerySuccess(info->browser, info->frame, info->context_id,
|
||||
info->request_id, builder);
|
||||
if (removed) {
|
||||
delete info;
|
||||
}
|
||||
@@ -558,19 +459,13 @@ class CefMessageRouterBrowserSideImpl : public CefMessageRouterBrowserSide {
|
||||
}
|
||||
}
|
||||
|
||||
void SendQuerySuccess(QueryInfo* info, const CefString& response) {
|
||||
SendQuerySuccess(info->browser, info->frame, info->context_id,
|
||||
info->request_id, response);
|
||||
}
|
||||
|
||||
void SendQuerySuccess(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
int context_id,
|
||||
int request_id,
|
||||
const CefString& response) {
|
||||
if (auto message =
|
||||
BuildMessage(config_.message_size_threshold, query_message_name_,
|
||||
context_id, request_id, response)) {
|
||||
void SendQuerySuccess(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
int context_id,
|
||||
int request_id,
|
||||
const CefRefPtr<cmru::BrowserResponseBuilder>& builder) {
|
||||
if (auto message = builder->Build(context_id, request_id)) {
|
||||
frame->SendProcessMessage(PID_RENDERER, message);
|
||||
}
|
||||
}
|
||||
@@ -758,10 +653,16 @@ class CefMessageRouterRendererSideImpl : public CefMessageRouterRendererSide {
|
||||
CefRefPtr<CefV8Value> arg = arguments[0];
|
||||
|
||||
CefRefPtr<CefV8Value> requestVal = arg->GetValue(kMemberRequest);
|
||||
if (!requestVal.get() || !requestVal->IsString()) {
|
||||
if (!requestVal.get()) {
|
||||
exception = "Invalid arguments; object member '" +
|
||||
std::string(kMemberRequest) + "' is required";
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!requestVal->IsString() && !requestVal->IsArrayBuffer()) {
|
||||
exception = "Invalid arguments; object member '" +
|
||||
std::string(kMemberRequest) +
|
||||
"' is required and must have type string";
|
||||
"' must have type string or ArrayBuffer";
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -804,9 +705,11 @@ class CefMessageRouterRendererSideImpl : public CefMessageRouterRendererSide {
|
||||
(persistentVal.get() && persistentVal->GetBoolValue());
|
||||
|
||||
const int request_id = router_->SendQuery(
|
||||
context->GetBrowser(), context->GetFrame(), context_id,
|
||||
requestVal->GetStringValue(), persistent, successVal, failureVal);
|
||||
context->GetBrowser(), context->GetFrame(), context_id, requestVal,
|
||||
persistent, successVal, failureVal);
|
||||
|
||||
retval = CefV8Value::CreateInt(request_id);
|
||||
|
||||
return true;
|
||||
} else if (name == config_.js_cancel_function) {
|
||||
if (arguments.size() != 1 || !arguments[0]->IsInt()) {
|
||||
@@ -958,29 +861,26 @@ class CefMessageRouterRendererSideImpl : public CefMessageRouterRendererSide {
|
||||
CefRefPtr<CefProcessMessage> message) override {
|
||||
CEF_REQUIRE_RENDERER_THREAD();
|
||||
|
||||
const std::string& message_name = message->GetName();
|
||||
if (message_name == query_message_name_) {
|
||||
auto content = ParseMessage(message);
|
||||
if (content.success) {
|
||||
CefPostTask(
|
||||
TID_RENDERER,
|
||||
base::BindOnce(
|
||||
&CefMessageRouterRendererSideImpl::ExecuteSuccessCallback, this,
|
||||
browser->GetIdentifier(), content.context_id,
|
||||
content.request_id, content.message));
|
||||
} else {
|
||||
CefPostTask(
|
||||
TID_RENDERER,
|
||||
base::BindOnce(
|
||||
&CefMessageRouterRendererSideImpl::ExecuteFailureCallback, this,
|
||||
browser->GetIdentifier(), content.context_id,
|
||||
content.request_id, content.error_code, content.message));
|
||||
}
|
||||
|
||||
return true;
|
||||
if (message->GetName() != query_message_name_) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
cmru::BrowserMessage content = cmru::ParseBrowserMessage(message);
|
||||
if (content.is_success) {
|
||||
std::visit(
|
||||
[&](const auto& arg) {
|
||||
ExecuteSuccessCallback(browser->GetIdentifier(), content.context_id,
|
||||
content.request_id, arg);
|
||||
},
|
||||
content.payload);
|
||||
|
||||
} else {
|
||||
ExecuteFailureCallback(browser->GetIdentifier(), content.context_id,
|
||||
content.request_id, content.error_code,
|
||||
std::get<CefString>(content.payload));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -1039,7 +939,7 @@ class CefMessageRouterRendererSideImpl : public CefMessageRouterRendererSide {
|
||||
int SendQuery(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
int context_id,
|
||||
const CefString& request,
|
||||
CefRefPtr<CefV8Value> request,
|
||||
bool persistent,
|
||||
CefRefPtr<CefV8Value> success_callback,
|
||||
CefRefPtr<CefV8Value> failure_callback) {
|
||||
@@ -1053,14 +953,9 @@ class CefMessageRouterRendererSideImpl : public CefMessageRouterRendererSide {
|
||||
browser_request_info_map_.Add(browser->GetIdentifier(),
|
||||
std::make_pair(context_id, request_id), info);
|
||||
|
||||
CefRefPtr<CefProcessMessage> message =
|
||||
CefProcessMessage::Create(query_message_name_);
|
||||
|
||||
CefRefPtr<CefListValue> args = message->GetArgumentList();
|
||||
args->SetInt(0, context_id);
|
||||
args->SetInt(1, request_id);
|
||||
args->SetString(2, request);
|
||||
args->SetBool(3, persistent);
|
||||
CefRefPtr<CefProcessMessage> message = cmru::BuildRendererMsg(
|
||||
config_.message_size_threshold, query_message_name_, context_id,
|
||||
request_id, request, persistent);
|
||||
|
||||
frame->SendProcessMessage(PID_BROWSER, message);
|
||||
|
||||
@@ -1162,6 +1057,41 @@ class CefMessageRouterRendererSideImpl : public CefMessageRouterRendererSide {
|
||||
}
|
||||
}
|
||||
|
||||
// Execute the onSuccess JavaScript callback.
|
||||
void ExecuteSuccessCallback(int browser_id,
|
||||
int context_id,
|
||||
int request_id,
|
||||
const CefRefPtr<CefBinaryBuffer>& response) {
|
||||
CEF_REQUIRE_RENDERER_THREAD();
|
||||
|
||||
bool removed;
|
||||
RequestInfo* info =
|
||||
GetRequestInfo(browser_id, context_id, request_id, false, &removed);
|
||||
if (!info) {
|
||||
return;
|
||||
}
|
||||
|
||||
CefRefPtr<CefV8Context> context = GetContextByID(context_id);
|
||||
if (context && info->success_callback && context->Enter()) {
|
||||
CefRefPtr<cmru::BinaryValueABRCallback> release_callback =
|
||||
new cmru::BinaryValueABRCallback(response);
|
||||
|
||||
CefRefPtr<CefV8Value> value = CefV8Value::CreateArrayBuffer(
|
||||
response->GetData(), response->GetSize(), release_callback);
|
||||
|
||||
context->Exit();
|
||||
|
||||
CefV8ValueList args;
|
||||
args.push_back(value);
|
||||
info->success_callback->ExecuteFunctionWithContext(context, nullptr,
|
||||
args);
|
||||
}
|
||||
|
||||
if (removed) {
|
||||
delete info;
|
||||
}
|
||||
}
|
||||
|
||||
// Execute the onFailure JavaScript callback.
|
||||
void ExecuteFailureCallback(int browser_id,
|
||||
int context_id,
|
||||
|
525
libcef_dll/wrapper/cef_message_router_utils.cc
Normal file
525
libcef_dll/wrapper/cef_message_router_utils.cc
Normal file
@@ -0,0 +1,525 @@
|
||||
// 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 "libcef_dll/wrapper/cef_message_router_utils.h"
|
||||
|
||||
#include "include/cef_shared_process_message_builder.h"
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace cef_message_router_utils {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr int kNoError = 0;
|
||||
|
||||
constexpr size_t kContextId = 0;
|
||||
constexpr size_t kRequestId = 1;
|
||||
constexpr size_t kRendererPayload = 2;
|
||||
constexpr size_t kIsSuccess = 2;
|
||||
constexpr size_t kBrowserPayload = 3;
|
||||
constexpr size_t kIsPersistent = 3;
|
||||
|
||||
struct BrowserMsgHeader {
|
||||
int context_id;
|
||||
int request_id;
|
||||
bool is_binary;
|
||||
};
|
||||
|
||||
static_assert(
|
||||
std::is_trivially_copyable_v<BrowserMsgHeader>,
|
||||
"Copying non-trivially-copyable object across memory spaces is dangerous");
|
||||
|
||||
struct RendererMsgHeader {
|
||||
int context_id;
|
||||
int request_id;
|
||||
bool is_persistent;
|
||||
bool is_binary;
|
||||
};
|
||||
|
||||
static_assert(
|
||||
std::is_trivially_copyable_v<RendererMsgHeader>,
|
||||
"Copying non-trivially-copyable object across memory spaces is dangerous");
|
||||
|
||||
//
|
||||
// This is a workaround for handling empty CefBinaryValues, as it's not possible
|
||||
// to create an empty one directly. We use this empty struct as a tag to invoke
|
||||
// the SetNull function within the BuildBrowserListMsg and BuildRendererListMsg
|
||||
// functions.
|
||||
//
|
||||
struct Empty {};
|
||||
|
||||
size_t GetByteLength(const CefString& value) {
|
||||
return value.size() * sizeof(CefString::char_type);
|
||||
}
|
||||
|
||||
size_t GetByteLength(const CefRefPtr<CefV8Value>& value) {
|
||||
return value->GetArrayBufferByteLength();
|
||||
}
|
||||
|
||||
const CefString& GetListRepresentation(const CefString& value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
CefRefPtr<CefBinaryValue> GetListRepresentation(
|
||||
const CefRefPtr<CefV8Value>& value) {
|
||||
return CefBinaryValue::Create(value->GetArrayBufferData(),
|
||||
value->GetArrayBufferByteLength());
|
||||
}
|
||||
|
||||
template <class Header, class T>
|
||||
size_t GetMessageSize(const T& value) {
|
||||
return sizeof(Header) + GetByteLength(value);
|
||||
}
|
||||
|
||||
template <class Header>
|
||||
void CopyIntoMemory(void* memory, const void* data, size_t bytes) {
|
||||
if (bytes > 0) {
|
||||
void* dest = static_cast<uint8_t*>(memory) + sizeof(Header);
|
||||
memcpy(dest, data, bytes);
|
||||
}
|
||||
}
|
||||
|
||||
template <class Header>
|
||||
void CopyIntoMemory(void* memory, const CefRefPtr<CefV8Value>& value) {
|
||||
CopyIntoMemory<Header>(memory, value->GetArrayBufferData(),
|
||||
value->GetArrayBufferByteLength());
|
||||
}
|
||||
|
||||
template <class Header>
|
||||
void CopyIntoMemory(void* memory, const CefString& value) {
|
||||
const size_t bytes = GetByteLength(value);
|
||||
CopyIntoMemory<Header>(memory, value.c_str(), bytes);
|
||||
}
|
||||
|
||||
template <class Header>
|
||||
CefString GetStringFromMemory(const void* memory, size_t size) {
|
||||
const size_t bytes = size - sizeof(Header);
|
||||
const size_t string_len = bytes / sizeof(CefString::char_type);
|
||||
const void* string_data =
|
||||
static_cast<const uint8_t*>(memory) + sizeof(Header);
|
||||
const CefString::char_type* src =
|
||||
static_cast<const CefString::char_type*>(string_data);
|
||||
CefString result;
|
||||
result.FromString(src, string_len, /*copy=*/true);
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
constexpr bool IsCefString() {
|
||||
return std::is_same_v<std::remove_cv_t<T>, CefString>;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
constexpr bool IsEmpty() {
|
||||
return std::is_same_v<std::remove_cv_t<T>, Empty>;
|
||||
}
|
||||
|
||||
template <class ResponseType>
|
||||
CefRefPtr<CefProcessMessage> BuildBrowserListMsg(const CefString& name,
|
||||
int context_id,
|
||||
int request_id,
|
||||
const ResponseType& response) {
|
||||
auto message = CefProcessMessage::Create(name);
|
||||
CefRefPtr<CefListValue> args = message->GetArgumentList();
|
||||
args->SetInt(kContextId, context_id);
|
||||
args->SetInt(kRequestId, request_id);
|
||||
args->SetBool(kIsSuccess, true);
|
||||
|
||||
if constexpr (IsCefString<ResponseType>()) {
|
||||
args->SetString(kBrowserPayload, response);
|
||||
} else if constexpr (IsEmpty<ResponseType>()) {
|
||||
args->SetNull(kBrowserPayload);
|
||||
} else {
|
||||
args->SetBinary(kBrowserPayload, response);
|
||||
}
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
class EmptyResponseBuilder final : public BrowserResponseBuilder {
|
||||
public:
|
||||
explicit EmptyResponseBuilder(const std::string& name) : name_(name) {}
|
||||
EmptyResponseBuilder(const EmptyResponseBuilder&) = delete;
|
||||
EmptyResponseBuilder& operator=(const EmptyResponseBuilder&) = delete;
|
||||
|
||||
CefRefPtr<CefProcessMessage> Build(int context_id, int request_id) override {
|
||||
return BuildBrowserListMsg(name_, context_id, request_id, Empty{});
|
||||
}
|
||||
|
||||
private:
|
||||
const CefString name_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING(EmptyResponseBuilder);
|
||||
};
|
||||
|
||||
class BinaryResponseBuilder final : public BrowserResponseBuilder {
|
||||
public:
|
||||
BinaryResponseBuilder(const std::string& name, const void* data, size_t size)
|
||||
: name_(name), value_(CefBinaryValue::Create(data, size)) {}
|
||||
BinaryResponseBuilder(const BinaryResponseBuilder&) = delete;
|
||||
BinaryResponseBuilder& operator=(const BinaryResponseBuilder&) = delete;
|
||||
|
||||
CefRefPtr<CefProcessMessage> Build(int context_id, int request_id) override {
|
||||
return BuildBrowserListMsg(name_, context_id, request_id, value_);
|
||||
}
|
||||
|
||||
private:
|
||||
const CefString name_;
|
||||
const CefRefPtr<CefBinaryValue> value_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING(BinaryResponseBuilder);
|
||||
};
|
||||
|
||||
class StringResponseBuilder final : public BrowserResponseBuilder {
|
||||
public:
|
||||
StringResponseBuilder(const std::string& name, const CefString& value)
|
||||
: name_(name), value_(value) {}
|
||||
StringResponseBuilder(const StringResponseBuilder&) = delete;
|
||||
StringResponseBuilder& operator=(const StringResponseBuilder&) = delete;
|
||||
|
||||
CefRefPtr<CefProcessMessage> Build(int context_id, int request_id) override {
|
||||
return BuildBrowserListMsg(name_, context_id, request_id, value_);
|
||||
}
|
||||
|
||||
private:
|
||||
const CefString name_;
|
||||
const CefString value_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING(StringResponseBuilder);
|
||||
};
|
||||
|
||||
// SharedProcessMessageResponseBuilder
|
||||
class SPMResponseBuilder final : public BrowserResponseBuilder {
|
||||
public:
|
||||
SPMResponseBuilder(const SPMResponseBuilder&) = delete;
|
||||
SPMResponseBuilder& operator=(const SPMResponseBuilder&) = delete;
|
||||
|
||||
static CefRefPtr<BrowserResponseBuilder> Create(const std::string& name,
|
||||
const void* data,
|
||||
size_t size) {
|
||||
const size_t message_size = sizeof(BrowserMsgHeader) + size;
|
||||
auto builder = CefSharedProcessMessageBuilder::Create(name, message_size);
|
||||
if (!builder->IsValid()) {
|
||||
LOG(ERROR) << "Failed to allocate shared memory region of size "
|
||||
<< message_size;
|
||||
return new BinaryResponseBuilder(name, data, size);
|
||||
}
|
||||
|
||||
CopyIntoMemory<BrowserMsgHeader>(builder->Memory(), data, size);
|
||||
return new SPMResponseBuilder(builder, /*is_binary=*/true);
|
||||
}
|
||||
|
||||
static CefRefPtr<BrowserResponseBuilder> Create(const std::string& name,
|
||||
const CefString& value) {
|
||||
const size_t message_size = GetMessageSize<BrowserMsgHeader>(value);
|
||||
auto builder = CefSharedProcessMessageBuilder::Create(name, message_size);
|
||||
if (!builder->IsValid()) {
|
||||
LOG(ERROR) << "Failed to allocate shared memory region of size "
|
||||
<< message_size;
|
||||
return new StringResponseBuilder(name, value);
|
||||
}
|
||||
|
||||
CopyIntoMemory<BrowserMsgHeader>(builder->Memory(), value);
|
||||
return new SPMResponseBuilder(builder, /*is_binary=*/false);
|
||||
}
|
||||
|
||||
CefRefPtr<CefProcessMessage> Build(int context_id, int request_id) override {
|
||||
auto header = static_cast<BrowserMsgHeader*>(builder_->Memory());
|
||||
header->context_id = context_id;
|
||||
header->request_id = request_id;
|
||||
header->is_binary = is_binary_;
|
||||
return builder_->Build();
|
||||
}
|
||||
|
||||
private:
|
||||
explicit SPMResponseBuilder(
|
||||
const CefRefPtr<CefSharedProcessMessageBuilder>& builder,
|
||||
bool is_binary)
|
||||
: builder_(builder), is_binary_(is_binary) {}
|
||||
|
||||
CefRefPtr<CefSharedProcessMessageBuilder> builder_;
|
||||
const bool is_binary_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING(SPMResponseBuilder);
|
||||
};
|
||||
|
||||
class EmptyBinaryBuffer final : public CefBinaryBuffer {
|
||||
public:
|
||||
EmptyBinaryBuffer() = default;
|
||||
EmptyBinaryBuffer(const EmptyBinaryBuffer&) = delete;
|
||||
EmptyBinaryBuffer& operator=(const EmptyBinaryBuffer&) = delete;
|
||||
|
||||
const void* GetData() const override { return nullptr; }
|
||||
void* GetData() override { return nullptr; }
|
||||
size_t GetSize() const override { return 0; }
|
||||
|
||||
private:
|
||||
IMPLEMENT_REFCOUNTING(EmptyBinaryBuffer);
|
||||
};
|
||||
|
||||
class BinaryValueBuffer final : public CefBinaryBuffer {
|
||||
public:
|
||||
BinaryValueBuffer(CefRefPtr<CefProcessMessage> message,
|
||||
CefRefPtr<CefBinaryValue> value)
|
||||
: message_(std::move(message)), value_(std::move(value)) {}
|
||||
BinaryValueBuffer(const BinaryValueBuffer&) = delete;
|
||||
BinaryValueBuffer& operator=(const BinaryValueBuffer&) = delete;
|
||||
|
||||
const void* GetData() const override { return value_->GetRawData(); }
|
||||
void* GetData() override {
|
||||
// This is not UB as long as underlying storage is vector<uint8_t>
|
||||
return const_cast<void*>(value_->GetRawData());
|
||||
}
|
||||
size_t GetSize() const override { return value_->GetSize(); }
|
||||
|
||||
private:
|
||||
const CefRefPtr<CefProcessMessage> message_;
|
||||
const CefRefPtr<CefBinaryValue> value_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING(BinaryValueBuffer);
|
||||
};
|
||||
|
||||
class SharedMemoryRegionBuffer final : public CefBinaryBuffer {
|
||||
public:
|
||||
SharedMemoryRegionBuffer(const CefRefPtr<CefSharedMemoryRegion>& region,
|
||||
size_t offset)
|
||||
: region_(region),
|
||||
data_(static_cast<uint8_t*>(region->Memory()) + offset),
|
||||
size_(region->Size() - offset) {}
|
||||
SharedMemoryRegionBuffer(const SharedMemoryRegionBuffer&) = delete;
|
||||
SharedMemoryRegionBuffer& operator=(const SharedMemoryRegionBuffer&) = delete;
|
||||
|
||||
const void* GetData() const override { return data_; }
|
||||
void* GetData() override { return data_; }
|
||||
size_t GetSize() const override { return size_; }
|
||||
|
||||
private:
|
||||
const CefRefPtr<CefSharedMemoryRegion> region_;
|
||||
void* const data_;
|
||||
const size_t size_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING(SharedMemoryRegionBuffer);
|
||||
};
|
||||
|
||||
template <class RequestType>
|
||||
CefRefPtr<CefProcessMessage> BuildRendererListMsg(const std::string& name,
|
||||
int context_id,
|
||||
int request_id,
|
||||
const RequestType& request,
|
||||
bool persistent) {
|
||||
auto message = CefProcessMessage::Create(name);
|
||||
CefRefPtr<CefListValue> args = message->GetArgumentList();
|
||||
args->SetInt(kContextId, context_id);
|
||||
args->SetInt(kRequestId, request_id);
|
||||
|
||||
if constexpr (IsCefString<RequestType>()) {
|
||||
args->SetString(kRendererPayload, request);
|
||||
} else if constexpr (IsEmpty<RequestType>()) {
|
||||
args->SetNull(kRendererPayload);
|
||||
} else {
|
||||
args->SetBinary(kRendererPayload, request);
|
||||
}
|
||||
|
||||
args->SetBool(kIsPersistent, persistent);
|
||||
return message;
|
||||
}
|
||||
|
||||
template <class RequestType>
|
||||
CefRefPtr<CefProcessMessage> BuildRendererSharedMsg(const std::string& name,
|
||||
int context_id,
|
||||
int request_id,
|
||||
const RequestType& request,
|
||||
bool persistent) {
|
||||
const size_t message_size = GetMessageSize<RendererMsgHeader>(request);
|
||||
auto builder = CefSharedProcessMessageBuilder::Create(name, message_size);
|
||||
if (!builder->IsValid()) {
|
||||
LOG(ERROR) << "Failed to allocate shared memory region of size "
|
||||
<< message_size;
|
||||
return BuildRendererListMsg(name, context_id, request_id,
|
||||
GetListRepresentation(request), persistent);
|
||||
}
|
||||
|
||||
auto header = static_cast<RendererMsgHeader*>(builder->Memory());
|
||||
header->context_id = context_id;
|
||||
header->request_id = request_id;
|
||||
header->is_persistent = persistent;
|
||||
header->is_binary = !IsCefString<RequestType>();
|
||||
|
||||
CopyIntoMemory<RendererMsgHeader>(builder->Memory(), request);
|
||||
|
||||
return builder->Build();
|
||||
}
|
||||
|
||||
CefRefPtr<CefProcessMessage> BuildRendererMsg(size_t threshold,
|
||||
const std::string& name,
|
||||
int context_id,
|
||||
int request_id,
|
||||
const CefString& request,
|
||||
bool persistent) {
|
||||
if (GetByteLength(request) < threshold) {
|
||||
return BuildRendererListMsg(name, context_id, request_id, request,
|
||||
persistent);
|
||||
}
|
||||
|
||||
return BuildRendererSharedMsg(name, context_id, request_id, request,
|
||||
persistent);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
CefRefPtr<BrowserResponseBuilder> CreateBrowserResponseBuilder(
|
||||
size_t threshold,
|
||||
const std::string& name,
|
||||
const CefString& response) {
|
||||
if (GetByteLength(response) < threshold) {
|
||||
return new StringResponseBuilder(name, response);
|
||||
}
|
||||
|
||||
return SPMResponseBuilder::Create(name, response);
|
||||
}
|
||||
|
||||
CefRefPtr<BrowserResponseBuilder> CreateBrowserResponseBuilder(
|
||||
size_t threshold,
|
||||
const std::string& name,
|
||||
const void* data,
|
||||
size_t size) {
|
||||
if (size == 0) {
|
||||
return new EmptyResponseBuilder(name);
|
||||
}
|
||||
|
||||
if (size < threshold) {
|
||||
return new BinaryResponseBuilder(name, data, size);
|
||||
}
|
||||
|
||||
return SPMResponseBuilder::Create(name, data, size);
|
||||
}
|
||||
|
||||
CefRefPtr<CefProcessMessage> BuildRendererMsg(
|
||||
size_t threshold,
|
||||
const std::string& name,
|
||||
int context_id,
|
||||
int request_id,
|
||||
const CefRefPtr<CefV8Value>& request,
|
||||
bool persistent) {
|
||||
if (request->IsString()) {
|
||||
return BuildRendererMsg(threshold, name, context_id, request_id,
|
||||
request->GetStringValue(), persistent);
|
||||
}
|
||||
|
||||
const auto size = request->GetArrayBufferByteLength();
|
||||
if (size == 0) {
|
||||
return BuildRendererListMsg(name, context_id, request_id, Empty{},
|
||||
persistent);
|
||||
}
|
||||
|
||||
if (size < threshold) {
|
||||
return BuildRendererListMsg(name, context_id, request_id,
|
||||
GetListRepresentation(request), persistent);
|
||||
}
|
||||
|
||||
return BuildRendererSharedMsg(name, context_id, request_id, request,
|
||||
persistent);
|
||||
}
|
||||
|
||||
BrowserMessage ParseBrowserMessage(
|
||||
const CefRefPtr<CefProcessMessage>& message) {
|
||||
if (auto args = message->GetArgumentList()) {
|
||||
DCHECK_GT(args->GetSize(), 3U);
|
||||
|
||||
const int context_id = args->GetInt(kContextId);
|
||||
const int request_id = args->GetInt(kRequestId);
|
||||
const bool is_success = args->GetBool(kIsSuccess);
|
||||
|
||||
if (is_success) {
|
||||
DCHECK_EQ(args->GetSize(), 4U);
|
||||
const auto payload_type = args->GetType(kBrowserPayload);
|
||||
if (payload_type == CefValueType::VTYPE_STRING) {
|
||||
return {context_id, request_id, is_success, kNoError,
|
||||
args->GetString(kBrowserPayload)};
|
||||
}
|
||||
|
||||
if (payload_type == CefValueType::VTYPE_BINARY) {
|
||||
return {
|
||||
context_id, request_id, is_success, kNoError,
|
||||
new BinaryValueBuffer(message, args->GetBinary(kBrowserPayload))};
|
||||
}
|
||||
|
||||
DCHECK(payload_type == CefValueType::VTYPE_NULL);
|
||||
return {context_id, request_id, is_success, kNoError,
|
||||
new EmptyBinaryBuffer()};
|
||||
}
|
||||
|
||||
DCHECK_EQ(args->GetSize(), 5U);
|
||||
return {context_id, request_id, is_success, args->GetInt(3),
|
||||
args->GetString(4)};
|
||||
}
|
||||
|
||||
const auto region = message->GetSharedMemoryRegion();
|
||||
if (region && region->IsValid()) {
|
||||
DCHECK_GE(region->Size(), sizeof(BrowserMsgHeader));
|
||||
auto header = static_cast<const BrowserMsgHeader*>(region->Memory());
|
||||
|
||||
if (header->is_binary) {
|
||||
return {header->context_id, header->request_id, true, kNoError,
|
||||
new SharedMemoryRegionBuffer(region, sizeof(BrowserMsgHeader))};
|
||||
}
|
||||
return {header->context_id, header->request_id, true, kNoError,
|
||||
GetStringFromMemory<BrowserMsgHeader>(region->Memory(),
|
||||
region->Size())};
|
||||
}
|
||||
|
||||
NOTREACHED();
|
||||
return {};
|
||||
}
|
||||
|
||||
RendererMessage ParseRendererMessage(
|
||||
const CefRefPtr<CefProcessMessage>& message) {
|
||||
if (auto args = message->GetArgumentList()) {
|
||||
DCHECK_EQ(args->GetSize(), 4U);
|
||||
|
||||
const int context_id = args->GetInt(kContextId);
|
||||
const int request_id = args->GetInt(kRequestId);
|
||||
const auto payload_type = args->GetType(kRendererPayload);
|
||||
const bool persistent = args->GetBool(kIsPersistent);
|
||||
|
||||
if (payload_type == CefValueType::VTYPE_STRING) {
|
||||
return {context_id, request_id, persistent,
|
||||
args->GetString(kRendererPayload)};
|
||||
}
|
||||
|
||||
if (payload_type == CefValueType::VTYPE_BINARY) {
|
||||
return {
|
||||
context_id, request_id, persistent,
|
||||
new BinaryValueBuffer(message, args->GetBinary(kRendererPayload))};
|
||||
}
|
||||
|
||||
DCHECK(payload_type == CefValueType::VTYPE_NULL);
|
||||
return {context_id, request_id, persistent, new EmptyBinaryBuffer()};
|
||||
}
|
||||
|
||||
const auto region = message->GetSharedMemoryRegion();
|
||||
if (region && region->IsValid()) {
|
||||
DCHECK_GE(region->Size(), sizeof(RendererMsgHeader));
|
||||
auto header = static_cast<const RendererMsgHeader*>(region->Memory());
|
||||
|
||||
if (header->is_binary) {
|
||||
return {header->context_id, header->request_id, header->is_persistent,
|
||||
new SharedMemoryRegionBuffer(region, sizeof(RendererMsgHeader))};
|
||||
}
|
||||
|
||||
return {
|
||||
header->context_id,
|
||||
header->request_id,
|
||||
header->is_persistent,
|
||||
GetStringFromMemory<RendererMsgHeader>(region->Memory(),
|
||||
region->Size()),
|
||||
};
|
||||
}
|
||||
|
||||
NOTREACHED();
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace cef_message_router_utils
|
92
libcef_dll/wrapper/cef_message_router_utils.h
Normal file
92
libcef_dll/wrapper/cef_message_router_utils.h
Normal file
@@ -0,0 +1,92 @@
|
||||
// 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.
|
||||
|
||||
#ifndef CEF_LIBCEF_DLL_WRAPPER_CEF_MESSAGE_ROUTER_UTILS_H_
|
||||
#define CEF_LIBCEF_DLL_WRAPPER_CEF_MESSAGE_ROUTER_UTILS_H_
|
||||
#pragma once
|
||||
|
||||
#include <variant>
|
||||
|
||||
#include "include/wrapper/cef_message_router.h"
|
||||
|
||||
namespace cef_message_router_utils {
|
||||
|
||||
///
|
||||
/// This class handles the task of copying user data, such as CefString or
|
||||
/// binary values like (void*, size_t), directly to an appropriate buffer based
|
||||
/// on the user data type and size.
|
||||
///
|
||||
/// There are four specializations of this abstract class. The appropriate
|
||||
/// specialization is chosen by the `CreateBrowserResponseBuilder` function,
|
||||
/// based on the provided data type and size. For instance, for a "short"
|
||||
/// CefString, a StringResponseBuilder specialization is used, and for an empty
|
||||
/// binary value - EmptyResponseBuilder.
|
||||
///
|
||||
class BrowserResponseBuilder : public CefBaseRefCounted {
|
||||
public:
|
||||
///
|
||||
/// Creates a new CefProcessMessage from the data provided to the builder.
|
||||
/// Returns nullptr for invalid instances. Invalidates this builder instance.
|
||||
///
|
||||
virtual CefRefPtr<CefProcessMessage> Build(int context_id,
|
||||
int request_id) = 0;
|
||||
};
|
||||
|
||||
struct BrowserMessage {
|
||||
int context_id;
|
||||
int request_id;
|
||||
bool is_success;
|
||||
int error_code;
|
||||
std::variant<CefString, CefRefPtr<CefBinaryBuffer>> payload;
|
||||
};
|
||||
|
||||
struct RendererMessage {
|
||||
int context_id;
|
||||
int request_id;
|
||||
bool is_persistent;
|
||||
std::variant<CefString, CefRefPtr<const CefBinaryBuffer>> payload;
|
||||
};
|
||||
|
||||
class BinaryValueABRCallback final : public CefV8ArrayBufferReleaseCallback {
|
||||
public:
|
||||
explicit BinaryValueABRCallback(CefRefPtr<CefBinaryBuffer> value)
|
||||
: value_(std::move(value)) {}
|
||||
BinaryValueABRCallback(const BinaryValueABRCallback&) = delete;
|
||||
BinaryValueABRCallback& operator=(const BinaryValueABRCallback&) = delete;
|
||||
|
||||
void ReleaseBuffer(void* buffer) override {}
|
||||
|
||||
private:
|
||||
const CefRefPtr<CefBinaryBuffer> value_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING(BinaryValueABRCallback);
|
||||
};
|
||||
|
||||
CefRefPtr<BrowserResponseBuilder> CreateBrowserResponseBuilder(
|
||||
size_t threshold,
|
||||
const std::string& name,
|
||||
const CefString& response);
|
||||
|
||||
CefRefPtr<BrowserResponseBuilder> CreateBrowserResponseBuilder(
|
||||
size_t threshold,
|
||||
const std::string& name,
|
||||
const void* data,
|
||||
size_t size);
|
||||
|
||||
CefRefPtr<CefProcessMessage> BuildRendererMsg(
|
||||
size_t threshold,
|
||||
const std::string& name,
|
||||
int context_id,
|
||||
int request_id,
|
||||
const CefRefPtr<CefV8Value>& request,
|
||||
bool persistent);
|
||||
|
||||
BrowserMessage ParseBrowserMessage(const CefRefPtr<CefProcessMessage>& message);
|
||||
|
||||
RendererMessage ParseRendererMessage(
|
||||
const CefRefPtr<CefProcessMessage>& message);
|
||||
|
||||
} // namespace cef_message_router_utils
|
||||
|
||||
#endif // CEF_LIBCEF_DLL_WRAPPER_CEF_MESSAGE_ROUTER_UTILS_H_
|
@@ -117,6 +117,10 @@ patches = [
|
||||
# Windows: Fix incorrect DIPToScreenRect usage in DesktopWindowTreeHostWin
|
||||
# when |has_external_parent_| is true.
|
||||
# https://github.com/chromiumembedded/cef/issues/3359
|
||||
#
|
||||
# chrome: Allow override of Widget::Activate() to support activation of
|
||||
# DevTools windows with external parent.
|
||||
# https://github.com/chromiumembedded/cef/issues/3282
|
||||
'name': 'views_widget',
|
||||
},
|
||||
{
|
||||
@@ -674,5 +678,10 @@ patches = [
|
||||
# https://chromium-review.googlesource.com/c/chromium/src/+/4829483
|
||||
# https://bugs.chromium.org/p/chromium/issues/detail?id=1470837#c22
|
||||
'name': 'rfh_navigation_4829483'
|
||||
},
|
||||
{
|
||||
# linux: Disable compiler TLS in libxml2.
|
||||
# https://github.com/chromiumembedded/cef/issues/3616
|
||||
'name': 'linux_libxml_tls_3616'
|
||||
}
|
||||
]
|
||||
|
@@ -20,10 +20,10 @@ index 401eb0cd40ee2..5e7ac0b6d9d0a 100644
|
||||
|
||||
// Make an exception to allow most visited tiles to commit in
|
||||
diff --git content/browser/renderer_host/navigation_request.cc content/browser/renderer_host/navigation_request.cc
|
||||
index 68b50260715c2..79d9cd4558848 100644
|
||||
index 8ba07ea436976..12baff0903754 100644
|
||||
--- content/browser/renderer_host/navigation_request.cc
|
||||
+++ content/browser/renderer_host/navigation_request.cc
|
||||
@@ -7463,10 +7463,22 @@ NavigationRequest::GetOriginForURLLoaderFactoryBeforeResponseWithDebugInfo(
|
||||
@@ -7464,10 +7464,22 @@ NavigationRequest::GetOriginForURLLoaderFactoryBeforeResponseWithDebugInfo(
|
||||
bool use_opaque_origin =
|
||||
(sandbox_flags & network::mojom::WebSandboxFlags::kOrigin) ==
|
||||
network::mojom::WebSandboxFlags::kOrigin;
|
||||
@@ -47,7 +47,7 @@ index 68b50260715c2..79d9cd4558848 100644
|
||||
}
|
||||
|
||||
return origin_and_debug_info;
|
||||
@@ -7572,6 +7584,15 @@ NavigationRequest::GetOriginForURLLoaderFactoryAfterResponseWithDebugInfo() {
|
||||
@@ -7573,6 +7585,15 @@ NavigationRequest::GetOriginForURLLoaderFactoryAfterResponseWithDebugInfo() {
|
||||
DetermineInitiatorRelationship(initiator_rfh,
|
||||
frame_tree_node_->current_frame_host()));
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
diff --git chrome/browser/BUILD.gn chrome/browser/BUILD.gn
|
||||
index 157ee5cadc0a7..9906a3cc24dd0 100644
|
||||
index 7cb8d3fc03da2..e643e73f80930 100644
|
||||
--- chrome/browser/BUILD.gn
|
||||
+++ chrome/browser/BUILD.gn
|
||||
@@ -11,6 +11,7 @@ import("//build/config/compiler/pgo/pgo.gni")
|
||||
@@ -18,7 +18,7 @@ index 157ee5cadc0a7..9906a3cc24dd0 100644
|
||||
"//chrome:extra_resources",
|
||||
"//chrome:resources",
|
||||
"//chrome:strings",
|
||||
@@ -2694,6 +2696,10 @@ static_library("browser") {
|
||||
@@ -2696,6 +2698,10 @@ static_library("browser") {
|
||||
]
|
||||
}
|
||||
|
||||
|
@@ -12,8 +12,70 @@ index 2480282a19d12..dbd1fbf8a15b5 100644
|
||||
|
||||
return false;
|
||||
}
|
||||
diff --git chrome/browser/devtools/devtools_window.cc chrome/browser/devtools/devtools_window.cc
|
||||
index 4d99a769d6069..0ebd577182dc6 100644
|
||||
--- chrome/browser/devtools/devtools_window.cc
|
||||
+++ chrome/browser/devtools/devtools_window.cc
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "chrome/browser/profiles/profile.h"
|
||||
#include "chrome/browser/task_manager/web_contents_tags.h"
|
||||
#include "chrome/browser/ui/browser.h"
|
||||
+#include "chrome/browser/ui/browser_finder.h"
|
||||
#include "chrome/browser/ui/browser_list.h"
|
||||
#include "chrome/browser/ui/browser_tabstrip.h"
|
||||
#include "chrome/browser/ui/browser_window.h"
|
||||
@@ -1162,6 +1163,13 @@ DevToolsWindow* DevToolsWindow::Create(
|
||||
!browser->is_type_normal()) {
|
||||
can_dock = false;
|
||||
}
|
||||
+
|
||||
+#if BUILDFLAG(ENABLE_CEF)
|
||||
+ if (can_dock && browser && browser->cef_delegate()) {
|
||||
+ // Don't dock DevTools for CEF-managed browsers.
|
||||
+ can_dock = false;
|
||||
+ }
|
||||
+#endif
|
||||
}
|
||||
|
||||
// Create WebContents with devtools.
|
||||
@@ -1738,12 +1746,29 @@ void DevToolsWindow::CreateDevToolsBrowser() {
|
||||
Browser::CreationStatus::kOk) {
|
||||
return;
|
||||
}
|
||||
- browser_ =
|
||||
- Browser::Create(Browser::CreateParams::CreateForDevTools(profile_));
|
||||
- browser_->tab_strip_model()->AddWebContents(
|
||||
- OwnedMainWebContents::TakeWebContents(
|
||||
- std::move(owned_main_web_contents_)),
|
||||
- -1, ui::PAGE_TRANSITION_AUTO_TOPLEVEL, AddTabTypes::ADD_ACTIVE);
|
||||
+
|
||||
+ auto opener = chrome::FindBrowserWithWebContents(GetInspectedWebContents());
|
||||
+ auto devtools_contents = OwnedMainWebContents::TakeWebContents(
|
||||
+ std::move(owned_main_web_contents_));
|
||||
+
|
||||
+#if BUILDFLAG(ENABLE_CEF)
|
||||
+ if (opener && opener->cef_delegate()) {
|
||||
+ // If a Browser is created, it will take ownership of |devtools_contents|.
|
||||
+ browser_ = opener->cef_delegate()->CreateDevToolsBrowser(
|
||||
+ profile_, opener, devtools_contents);
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
+ if (!browser_) {
|
||||
+ auto create_params = Browser::CreateParams::CreateForDevTools(profile_);
|
||||
+ create_params.opener = opener;
|
||||
+
|
||||
+ browser_ = Browser::Create(std::move(create_params));
|
||||
+ browser_->tab_strip_model()->AddWebContents(
|
||||
+ std::move(devtools_contents),
|
||||
+ -1, ui::PAGE_TRANSITION_AUTO_TOPLEVEL, AddTabTypes::ADD_ACTIVE);
|
||||
+ }
|
||||
+
|
||||
OverrideAndSyncDevToolsRendererPrefs();
|
||||
}
|
||||
|
||||
diff --git chrome/browser/ui/BUILD.gn chrome/browser/ui/BUILD.gn
|
||||
index eca90c39e0d44..2157b6d86ab02 100644
|
||||
index d5bc836ec888d..4da459c08e7af 100644
|
||||
--- chrome/browser/ui/BUILD.gn
|
||||
+++ chrome/browser/ui/BUILD.gn
|
||||
@@ -9,6 +9,7 @@ import("//build/config/compiler/compiler.gni")
|
||||
@@ -61,7 +123,7 @@ index eca90c39e0d44..2157b6d86ab02 100644
|
||||
"views/apps/app_info_dialog/app_info_dialog_container.cc",
|
||||
"views/apps/app_info_dialog/app_info_dialog_container.h",
|
||||
"views/apps/app_info_dialog/app_info_dialog_views.cc",
|
||||
@@ -6392,6 +6398,7 @@ static_library("ui") {
|
||||
@@ -6393,6 +6399,7 @@ static_library("ui") {
|
||||
if (enable_printing) {
|
||||
deps += [
|
||||
"//components/printing/browser",
|
||||
@@ -333,7 +395,7 @@ index 9ba2025634365..b6ceaa7f0b531 100644
|
||||
case TYPE_NORMAL:
|
||||
return NormalBrowserSupportsWindowFeature(feature, check_can_support);
|
||||
diff --git chrome/browser/ui/browser.h chrome/browser/ui/browser.h
|
||||
index db37e861d2546..c47dfc31131f7 100644
|
||||
index db37e861d2546..ea85b9966267d 100644
|
||||
--- chrome/browser/ui/browser.h
|
||||
+++ chrome/browser/ui/browser.h
|
||||
@@ -22,6 +22,7 @@
|
||||
@@ -364,7 +426,7 @@ index db37e861d2546..c47dfc31131f7 100644
|
||||
+ scoped_refptr<cef::BrowserDelegate::CreateParams> cef_params;
|
||||
+
|
||||
+ // Specify the Browser that is opening this popup.
|
||||
+ // Currently only used with TYPE_PICTURE_IN_PICTURE.
|
||||
+ // Currently only used with TYPE_PICTURE_IN_PICTURE and TYPE_DEVTOOLS.
|
||||
+ raw_ptr<Browser, DanglingUntriaged> opener = nullptr;
|
||||
+#endif
|
||||
+
|
||||
|
@@ -1,8 +1,8 @@
|
||||
diff --git chrome/browser/renderer_context_menu/render_view_context_menu.cc chrome/browser/renderer_context_menu/render_view_context_menu.cc
|
||||
index 9ed9d3b43c45b..845bb4ff858ef 100644
|
||||
index b4a12d129fa52..a8caaab873d3c 100644
|
||||
--- chrome/browser/renderer_context_menu/render_view_context_menu.cc
|
||||
+++ chrome/browser/renderer_context_menu/render_view_context_menu.cc
|
||||
@@ -344,6 +344,13 @@ base::OnceCallback<void(RenderViewContextMenu*)>* GetMenuShownCallback() {
|
||||
@@ -345,6 +345,13 @@ base::OnceCallback<void(RenderViewContextMenu*)>* GetMenuShownCallback() {
|
||||
return callback.get();
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ index 9ed9d3b43c45b..845bb4ff858ef 100644
|
||||
enum class UmaEnumIdLookupType {
|
||||
GeneralEnumId,
|
||||
ContextSpecificEnumId,
|
||||
@@ -593,6 +600,10 @@ int FindUMAEnumValueForCommand(int id, UmaEnumIdLookupType type) {
|
||||
@@ -594,6 +601,10 @@ int FindUMAEnumValueForCommand(int id, UmaEnumIdLookupType type) {
|
||||
if (ContextMenuMatcher::IsExtensionsCustomCommandId(id))
|
||||
return 1;
|
||||
|
||||
@@ -27,7 +27,7 @@ index 9ed9d3b43c45b..845bb4ff858ef 100644
|
||||
id = CollapseCommandsForUMA(id);
|
||||
const auto& map = GetIdcToUmaMap(type);
|
||||
auto it = map.find(id);
|
||||
@@ -816,6 +827,14 @@ RenderViewContextMenu::RenderViewContextMenu(
|
||||
@@ -817,6 +828,14 @@ RenderViewContextMenu::RenderViewContextMenu(
|
||||
pdf_ocr_submenu_model_ = std::make_unique<ui::SimpleMenuModel>(this);
|
||||
#endif // BUILDFLAG(ENABLE_SCREEN_AI_SERVICE)
|
||||
|
||||
@@ -42,7 +42,7 @@ index 9ed9d3b43c45b..845bb4ff858ef 100644
|
||||
observers_.AddObserver(&autofill_context_menu_manager_);
|
||||
}
|
||||
|
||||
@@ -1278,6 +1297,12 @@ void RenderViewContextMenu::InitMenu() {
|
||||
@@ -1280,6 +1299,12 @@ void RenderViewContextMenu::InitMenu() {
|
||||
autofill::PopupHidingReason::kContextMenuOpened);
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,7 @@ index 9ed9d3b43c45b..845bb4ff858ef 100644
|
||||
}
|
||||
|
||||
Profile* RenderViewContextMenu::GetProfile() const {
|
||||
@@ -3334,6 +3359,12 @@ void RenderViewContextMenu::RegisterExecutePluginActionCallbackForTesting(
|
||||
@@ -3315,6 +3340,12 @@ void RenderViewContextMenu::RegisterExecutePluginActionCallbackForTesting(
|
||||
execute_plugin_action_callback_ = std::move(cb);
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ index 9ed9d3b43c45b..845bb4ff858ef 100644
|
||||
RenderViewContextMenu::GetHandlersForLinkUrl() {
|
||||
custom_handlers::ProtocolHandlerRegistry::ProtocolHandlerList handlers =
|
||||
diff --git chrome/browser/renderer_context_menu/render_view_context_menu.h chrome/browser/renderer_context_menu/render_view_context_menu.h
|
||||
index 45f2a2a82cb03..5abee00109363 100644
|
||||
index 2d38d86a07d98..3f16e2bf696c1 100644
|
||||
--- chrome/browser/renderer_context_menu/render_view_context_menu.h
|
||||
+++ chrome/browser/renderer_context_menu/render_view_context_menu.h
|
||||
@@ -152,6 +152,12 @@ class RenderViewContextMenu
|
||||
@@ -85,7 +85,7 @@ index 45f2a2a82cb03..5abee00109363 100644
|
||||
protected:
|
||||
Profile* GetProfile() const;
|
||||
|
||||
@@ -437,6 +443,9 @@ class RenderViewContextMenu
|
||||
@@ -441,6 +447,9 @@ class RenderViewContextMenu
|
||||
// built.
|
||||
bool is_protocol_submenu_valid_ = false;
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
diff --git chrome/browser/themes/theme_service.cc chrome/browser/themes/theme_service.cc
|
||||
index dbd628982e216..d77a39111e254 100644
|
||||
index d0e1d573c1fca..65ab5fc0a6388 100644
|
||||
--- chrome/browser/themes/theme_service.cc
|
||||
+++ chrome/browser/themes/theme_service.cc
|
||||
@@ -29,6 +29,7 @@
|
||||
@@ -10,7 +10,7 @@ index dbd628982e216..d77a39111e254 100644
|
||||
#include "chrome/browser/browser_features.h"
|
||||
#include "chrome/browser/extensions/extension_service.h"
|
||||
#include "chrome/browser/extensions/theme_installed_infobar_delegate.h"
|
||||
@@ -69,6 +70,10 @@
|
||||
@@ -70,6 +71,10 @@
|
||||
#include "ui/color/color_provider_manager.h"
|
||||
#include "ui/native_theme/native_theme.h"
|
||||
|
||||
@@ -21,7 +21,7 @@ index dbd628982e216..d77a39111e254 100644
|
||||
#if BUILDFLAG(ENABLE_EXTENSIONS)
|
||||
#include "base/scoped_observation.h"
|
||||
#include "extensions/browser/extension_registry_observer.h"
|
||||
@@ -270,11 +275,19 @@ void ThemeService::Init() {
|
||||
@@ -271,11 +276,19 @@ void ThemeService::Init() {
|
||||
// OnExtensionServiceReady. Otherwise, the ThemeObserver won't be
|
||||
// constructed in time to observe the corresponding events.
|
||||
#if BUILDFLAG(ENABLE_EXTENSIONS)
|
||||
|
@@ -233,7 +233,7 @@ index a509d0b37e953..0d48c4a1f1daf 100644
|
||||
+#endif
|
||||
}
|
||||
diff --git chrome/browser/chrome_content_browser_client.cc chrome/browser/chrome_content_browser_client.cc
|
||||
index 54053dfc9b86d..19c11cf71046d 100644
|
||||
index 9b845c0e331c4..6a2128ae2b562 100644
|
||||
--- chrome/browser/chrome_content_browser_client.cc
|
||||
+++ chrome/browser/chrome_content_browser_client.cc
|
||||
@@ -42,6 +42,7 @@
|
||||
@@ -295,7 +295,7 @@ index 54053dfc9b86d..19c11cf71046d 100644
|
||||
}
|
||||
|
||||
std::vector<base::FilePath>
|
||||
@@ -7652,10 +7664,10 @@ void ChromeContentBrowserClient::OnKeepaliveRequestStarted(
|
||||
@@ -7653,10 +7665,10 @@ void ChromeContentBrowserClient::OnKeepaliveRequestStarted(
|
||||
const auto now = base::TimeTicks::Now();
|
||||
const auto timeout = GetKeepaliveTimerTimeout(context);
|
||||
keepalive_deadline_ = std::max(keepalive_deadline_, now + timeout);
|
||||
@@ -308,7 +308,7 @@ index 54053dfc9b86d..19c11cf71046d 100644
|
||||
FROM_HERE, keepalive_deadline_ - now,
|
||||
base::BindOnce(
|
||||
&ChromeContentBrowserClient::OnKeepaliveTimerFired,
|
||||
@@ -7674,7 +7686,8 @@ void ChromeContentBrowserClient::OnKeepaliveRequestFinished() {
|
||||
@@ -7675,7 +7687,8 @@ void ChromeContentBrowserClient::OnKeepaliveRequestFinished() {
|
||||
--num_keepalive_requests_;
|
||||
if (num_keepalive_requests_ == 0) {
|
||||
DVLOG(1) << "Stopping the keepalive timer";
|
||||
@@ -318,7 +318,7 @@ index 54053dfc9b86d..19c11cf71046d 100644
|
||||
// This deletes the keep alive handle attached to the timer function and
|
||||
// unblock the shutdown sequence.
|
||||
}
|
||||
@@ -7816,7 +7829,7 @@ void ChromeContentBrowserClient::OnKeepaliveTimerFired(
|
||||
@@ -7817,7 +7830,7 @@ void ChromeContentBrowserClient::OnKeepaliveTimerFired(
|
||||
const auto now = base::TimeTicks::Now();
|
||||
const auto then = keepalive_deadline_;
|
||||
if (now < then) {
|
||||
|
@@ -231,7 +231,7 @@ index 59024587ef6b7..0c30aa71768cf 100644
|
||||
|
||||
void FindBarHost::RegisterAccelerators() {
|
||||
diff --git chrome/browser/ui/views/frame/browser_frame.cc chrome/browser/ui/views/frame/browser_frame.cc
|
||||
index bb4b3821bcfda..9734fe4aaffcf 100644
|
||||
index bb4b3821bcfda..4014f61a7057f 100644
|
||||
--- chrome/browser/ui/views/frame/browser_frame.cc
|
||||
+++ chrome/browser/ui/views/frame/browser_frame.cc
|
||||
@@ -114,15 +114,23 @@ ui::ColorProviderKey::SchemeVariant GetSchemeVariant(
|
||||
@@ -260,7 +260,7 @@ index bb4b3821bcfda..9734fe4aaffcf 100644
|
||||
}
|
||||
|
||||
BrowserFrame::~BrowserFrame() {}
|
||||
@@ -228,6 +236,12 @@ void BrowserFrame::LayoutWebAppWindowTitle(
|
||||
@@ -228,10 +236,20 @@ void BrowserFrame::LayoutWebAppWindowTitle(
|
||||
}
|
||||
|
||||
int BrowserFrame::GetTopInset() const {
|
||||
@@ -273,7 +273,15 @@ index bb4b3821bcfda..9734fe4aaffcf 100644
|
||||
return browser_frame_view_->GetTopInset(false);
|
||||
}
|
||||
|
||||
@@ -240,6 +254,8 @@ BrowserNonClientFrameView* BrowserFrame::GetFrameView() const {
|
||||
void BrowserFrame::UpdateThrobber(bool running) {
|
||||
+ if (!browser_frame_view_) {
|
||||
+ // Not supported with CEF Views-hosted DevTools windows.
|
||||
+ return;
|
||||
+ }
|
||||
browser_frame_view_->UpdateThrobber(running);
|
||||
}
|
||||
|
||||
@@ -240,6 +258,8 @@ BrowserNonClientFrameView* BrowserFrame::GetFrameView() const {
|
||||
}
|
||||
|
||||
bool BrowserFrame::UseCustomFrame() const {
|
||||
@@ -282,7 +290,7 @@ index bb4b3821bcfda..9734fe4aaffcf 100644
|
||||
return native_browser_frame_->UseCustomFrame();
|
||||
}
|
||||
|
||||
@@ -253,20 +269,30 @@ bool BrowserFrame::ShouldDrawFrameHeader() const {
|
||||
@@ -253,20 +273,30 @@ bool BrowserFrame::ShouldDrawFrameHeader() const {
|
||||
|
||||
void BrowserFrame::GetWindowPlacement(gfx::Rect* bounds,
|
||||
ui::WindowShowState* show_state) const {
|
||||
@@ -313,7 +321,7 @@ index bb4b3821bcfda..9734fe4aaffcf 100644
|
||||
browser_frame_view_->OnBrowserViewInitViewsComplete();
|
||||
}
|
||||
|
||||
@@ -367,6 +393,8 @@ ui::ColorProviderKey::ThemeInitializerSupplier* BrowserFrame::GetCustomTheme()
|
||||
@@ -367,6 +397,8 @@ ui::ColorProviderKey::ThemeInitializerSupplier* BrowserFrame::GetCustomTheme()
|
||||
}
|
||||
|
||||
void BrowserFrame::OnNativeWidgetWorkspaceChanged() {
|
||||
@@ -322,7 +330,7 @@ index bb4b3821bcfda..9734fe4aaffcf 100644
|
||||
chrome::SaveWindowWorkspace(browser_view_->browser(), GetWorkspace());
|
||||
chrome::SaveWindowVisibleOnAllWorkspaces(browser_view_->browser(),
|
||||
IsVisibleOnAllWorkspaces());
|
||||
@@ -478,6 +506,8 @@ void BrowserFrame::OnNativeThemeUpdated(ui::NativeTheme* observed_theme) {
|
||||
@@ -478,6 +510,8 @@ void BrowserFrame::OnNativeThemeUpdated(ui::NativeTheme* observed_theme) {
|
||||
|
||||
ui::ColorProviderKey BrowserFrame::GetColorProviderKey() const {
|
||||
auto key = Widget::GetColorProviderKey();
|
||||
@@ -331,7 +339,7 @@ index bb4b3821bcfda..9734fe4aaffcf 100644
|
||||
|
||||
key.app_controller = browser_view_->browser()->app_controller();
|
||||
|
||||
@@ -632,5 +662,8 @@ bool BrowserFrame::RegenerateFrameOnThemeChange(
|
||||
@@ -632,5 +666,8 @@ bool BrowserFrame::RegenerateFrameOnThemeChange(
|
||||
}
|
||||
|
||||
bool BrowserFrame::IsIncognitoBrowser() const {
|
||||
@@ -711,7 +719,7 @@ index 8267a265a8e10..ee08f18e96a34 100644
|
||||
|
||||
ContentsWebView::~ContentsWebView() {
|
||||
diff --git chrome/browser/ui/views/frame/picture_in_picture_browser_frame_view.cc chrome/browser/ui/views/frame/picture_in_picture_browser_frame_view.cc
|
||||
index b9b50af047993..30793a69c4942 100644
|
||||
index b9b50af047993..70ece4c81ff04 100644
|
||||
--- chrome/browser/ui/views/frame/picture_in_picture_browser_frame_view.cc
|
||||
+++ chrome/browser/ui/views/frame/picture_in_picture_browser_frame_view.cc
|
||||
@@ -573,6 +573,11 @@ PictureInPictureBrowserFrameView::PictureInPictureBrowserFrameView(
|
||||
@@ -726,7 +734,7 @@ index b9b50af047993..30793a69c4942 100644
|
||||
}
|
||||
|
||||
PictureInPictureBrowserFrameView::~PictureInPictureBrowserFrameView() {
|
||||
@@ -669,17 +674,20 @@ gfx::Rect PictureInPictureBrowserFrameView::GetWindowBoundsForClientBounds(
|
||||
@@ -669,18 +674,42 @@ gfx::Rect PictureInPictureBrowserFrameView::GetWindowBoundsForClientBounds(
|
||||
|
||||
int PictureInPictureBrowserFrameView::NonClientHitTest(
|
||||
const gfx::Point& point) {
|
||||
@@ -735,18 +743,14 @@ index b9b50af047993..30793a69c4942 100644
|
||||
- GetBackToTabControlsBounds().Contains(point) ||
|
||||
- GetCloseControlsBounds().Contains(point)) {
|
||||
- return HTCLIENT;
|
||||
- }
|
||||
-
|
||||
- for (size_t i = 0; i < content_setting_views_.size(); i++) {
|
||||
- if (GetContentSettingViewBounds(i).Contains(point)) {
|
||||
+ const bool frameless = !top_bar_container_view_->GetVisible();
|
||||
+ if (!frameless) {
|
||||
+ // Allow interacting with the buttons.
|
||||
+ if (GetLocationIconViewBounds().Contains(point) ||
|
||||
+ GetBackToTabControlsBounds().Contains(point) ||
|
||||
+ GetCloseControlsBounds().Contains(point)) {
|
||||
return HTCLIENT;
|
||||
}
|
||||
+ return HTCLIENT;
|
||||
+ }
|
||||
+
|
||||
+ for (size_t i = 0; i < content_setting_views_.size(); i++) {
|
||||
+ if (GetContentSettingViewBounds(i).Contains(point)) {
|
||||
@@ -755,11 +759,9 @@ index b9b50af047993..30793a69c4942 100644
|
||||
+ }
|
||||
}
|
||||
|
||||
// Allow dragging and resizing the window.
|
||||
@@ -689,6 +697,27 @@ int PictureInPictureBrowserFrameView::NonClientHitTest(
|
||||
if (window_component != HTNOWHERE)
|
||||
return window_component;
|
||||
|
||||
- for (size_t i = 0; i < content_setting_views_.size(); i++) {
|
||||
- if (GetContentSettingViewBounds(i).Contains(point)) {
|
||||
- return HTCLIENT;
|
||||
+#if BUILDFLAG(ENABLE_CEF)
|
||||
+ if (frameless) {
|
||||
+ // Match logic in BrowserView::ShouldDescendIntoChildForEventHandling.
|
||||
@@ -777,13 +779,12 @@ index b9b50af047993..30793a69c4942 100644
|
||||
+ point_in_contents_web_view_coords.y())) {
|
||||
+ return HTCAPTION;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
}
|
||||
+#endif // BUILDFLAG(ENABLE_CEF)
|
||||
+
|
||||
// Allow interacting with the web contents.
|
||||
int frame_component = frame()->client_view()->NonClientHitTest(point);
|
||||
if (frame_component != HTNOWHERE)
|
||||
|
||||
// Allow dragging and resizing the window.
|
||||
int window_component = GetHTComponentForFrame(
|
||||
@@ -747,7 +776,8 @@ void PictureInPictureBrowserFrameView::Layout() {
|
||||
gfx::Rect content_area = GetLocalBounds();
|
||||
content_area.Inset(FrameBorderInsets());
|
||||
|
@@ -12,10 +12,10 @@ index 34cacda8ef225..e0465b8ac1185 100644
|
||||
version.Set("V8-Version", V8_VERSION_STRING);
|
||||
std::string host = info.GetHeaderValue("host");
|
||||
diff --git content/browser/loader/navigation_url_loader_impl.cc content/browser/loader/navigation_url_loader_impl.cc
|
||||
index 3b58e4f2de295..e0348501c83d8 100644
|
||||
index 3558cbc360714..267abf8a9abd5 100644
|
||||
--- content/browser/loader/navigation_url_loader_impl.cc
|
||||
+++ content/browser/loader/navigation_url_loader_impl.cc
|
||||
@@ -774,6 +774,17 @@ NavigationURLLoaderImpl::PrepareForNonInterceptedRequest() {
|
||||
@@ -753,6 +753,17 @@ NavigationURLLoaderImpl::PrepareForNonInterceptedRequest() {
|
||||
resource_request_->has_user_gesture, initiating_origin,
|
||||
initiator_document_.AsRenderFrameHostIfValid(), &loader_factory);
|
||||
|
||||
@@ -145,7 +145,7 @@ index 3c3ebfeec280e..b239506a39b43 100644
|
||||
base::BindRepeating(&RenderThreadImpl::OnRendererInterfaceReceiver,
|
||||
base::Unretained(this)));
|
||||
diff --git content/renderer/renderer_blink_platform_impl.cc content/renderer/renderer_blink_platform_impl.cc
|
||||
index cddb519c4c893..68b5fc0f60d9c 100644
|
||||
index 4ed1a50637e40..ce57912529596 100644
|
||||
--- content/renderer/renderer_blink_platform_impl.cc
|
||||
+++ content/renderer/renderer_blink_platform_impl.cc
|
||||
@@ -941,6 +941,15 @@ SkBitmap* RendererBlinkPlatformImpl::GetSadPageBitmap() {
|
||||
|
13
patch/patches/linux_libxml_tls_3616.patch
Normal file
13
patch/patches/linux_libxml_tls_3616.patch
Normal file
@@ -0,0 +1,13 @@
|
||||
diff --git third_party/libxml/linux/config.h third_party/libxml/linux/config.h
|
||||
index c064071ce1545..65110af9a78f5 100644
|
||||
--- third_party/libxml/linux/config.h
|
||||
+++ third_party/libxml/linux/config.h
|
||||
@@ -171,7 +171,7 @@
|
||||
/* #undef XML_SOCKLEN_T */
|
||||
|
||||
/* TLS specifier */
|
||||
-#define XML_THREAD_LOCAL _Thread_local
|
||||
+/* #undef XML_THREAD_LOCAL */
|
||||
|
||||
/* Define for Solaris 2.5.1 so the uint32_t typedef from <sys/synch.h>,
|
||||
<pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
|
@@ -41,10 +41,10 @@ index afefe3cd83dee..6668463247644 100644
|
||||
|
||||
} // namespace content
|
||||
diff --git content/browser/renderer_host/render_widget_host_impl.cc content/browser/renderer_host/render_widget_host_impl.cc
|
||||
index 7a99c04fcf5bb..2ed7d26f2d047 100644
|
||||
index d7b85d4a6adbe..6bd3035c313b3 100644
|
||||
--- content/browser/renderer_host/render_widget_host_impl.cc
|
||||
+++ content/browser/renderer_host/render_widget_host_impl.cc
|
||||
@@ -3261,6 +3261,11 @@ void RenderWidgetHostImpl::OnInvalidInputEventSource() {
|
||||
@@ -3271,6 +3271,11 @@ void RenderWidgetHostImpl::OnInvalidInputEventSource() {
|
||||
GetProcess(), bad_message::INPUT_ROUTER_INVALID_EVENT_SOURCE);
|
||||
}
|
||||
|
||||
|
@@ -12,10 +12,10 @@ index 5cb6e6463767d..84a9de1dfc6f0 100644
|
||||
RenderFrameHostImpl::FromFrameToken(
|
||||
process_id, initiator_frame_token->value())) {
|
||||
diff --git content/browser/renderer_host/render_frame_host_impl.cc content/browser/renderer_host/render_frame_host_impl.cc
|
||||
index f9295c24641e9..118e86979c5c7 100644
|
||||
index 44ab3ea5a90eb..9962e033ab103 100644
|
||||
--- content/browser/renderer_host/render_frame_host_impl.cc
|
||||
+++ content/browser/renderer_host/render_frame_host_impl.cc
|
||||
@@ -10086,6 +10086,7 @@ void RenderFrameHostImpl::CommitNavigation(
|
||||
@@ -10100,6 +10100,7 @@ void RenderFrameHostImpl::CommitNavigation(
|
||||
auto browser_calc_origin_to_commit =
|
||||
navigation_request->GetOriginToCommitWithDebugInfo();
|
||||
if (!process_lock.is_error_page() && !is_mhtml_subframe &&
|
||||
|
@@ -21,7 +21,7 @@ index 0a6c1f498b8fc..79e0cf27a7715 100644
|
||||
// If the corresponding Connector policy isn't set, don't perform scans.
|
||||
if (!service || !service->IsConnectorEnabled(connector))
|
||||
diff --git chrome/browser/net/profile_network_context_service.cc chrome/browser/net/profile_network_context_service.cc
|
||||
index 1200475275e91..d32195f01c7ed 100644
|
||||
index 6271f349464b9..caa45362f52cc 100644
|
||||
--- chrome/browser/net/profile_network_context_service.cc
|
||||
+++ chrome/browser/net/profile_network_context_service.cc
|
||||
@@ -22,6 +22,7 @@
|
||||
@@ -45,7 +45,7 @@ index 1200475275e91..d32195f01c7ed 100644
|
||||
|
||||
DisableQuicIfNotAllowed();
|
||||
|
||||
@@ -480,6 +483,9 @@ void ProfileNetworkContextService::OnTruncatedCookieBlockingChanged() {
|
||||
@@ -490,6 +493,9 @@ void ProfileNetworkContextService::OnTruncatedCookieBlockingChanged() {
|
||||
|
||||
void ProfileNetworkContextService::OnFirstPartySetsEnabledChanged(
|
||||
bool enabled) {
|
||||
@@ -55,7 +55,7 @@ index 1200475275e91..d32195f01c7ed 100644
|
||||
// Update all FPS Access Delegates on the FPS service to be `enabled`.
|
||||
first_party_sets::FirstPartySetsPolicyServiceFactory::GetForBrowserContext(
|
||||
profile_)
|
||||
@@ -866,9 +872,26 @@ void ProfileNetworkContextService::ConfigureNetworkContextParamsInternal(
|
||||
@@ -881,9 +887,26 @@ void ProfileNetworkContextService::ConfigureNetworkContextParamsInternal(
|
||||
network_context_params->cookie_manager_params =
|
||||
CreateCookieManagerParams(profile_, *cookie_settings_);
|
||||
|
||||
@@ -83,7 +83,7 @@ index 1200475275e91..d32195f01c7ed 100644
|
||||
PrefService* local_state = g_browser_process->local_state();
|
||||
// Configure the HTTP cache path and size.
|
||||
base::FilePath base_cache_path;
|
||||
@@ -877,15 +900,14 @@ void ProfileNetworkContextService::ConfigureNetworkContextParamsInternal(
|
||||
@@ -892,15 +915,14 @@ void ProfileNetworkContextService::ConfigureNetworkContextParamsInternal(
|
||||
local_state->GetFilePath(prefs::kDiskCacheDir);
|
||||
if (!disk_cache_dir.empty())
|
||||
base_cache_path = disk_cache_dir.Append(base_cache_path.BaseName());
|
||||
@@ -103,7 +103,7 @@ index 1200475275e91..d32195f01c7ed 100644
|
||||
network_context_params->file_paths->data_directory =
|
||||
path.Append(chrome::kNetworkDataDirname);
|
||||
network_context_params->file_paths->unsandboxed_data_path = path;
|
||||
@@ -1038,6 +1060,7 @@ void ProfileNetworkContextService::ConfigureNetworkContextParamsInternal(
|
||||
@@ -1053,6 +1075,7 @@ void ProfileNetworkContextService::ConfigureNetworkContextParamsInternal(
|
||||
network_context_params->block_trust_tokens =
|
||||
anti_abuse_content_setting == CONTENT_SETTING_BLOCK;
|
||||
|
||||
@@ -111,7 +111,7 @@ index 1200475275e91..d32195f01c7ed 100644
|
||||
network_context_params->first_party_sets_access_delegate_params =
|
||||
network::mojom::FirstPartySetsAccessDelegateParams::New();
|
||||
network_context_params->first_party_sets_access_delegate_params->enabled =
|
||||
@@ -1054,6 +1077,7 @@ void ProfileNetworkContextService::ConfigureNetworkContextParamsInternal(
|
||||
@@ -1069,6 +1092,7 @@ void ProfileNetworkContextService::ConfigureNetworkContextParamsInternal(
|
||||
GetForBrowserContext(profile_);
|
||||
DCHECK(fps_service);
|
||||
fps_service->AddRemoteAccessDelegate(std::move(fps_access_delegate_remote));
|
||||
@@ -223,7 +223,7 @@ index 61fd008fc067e..73909be088278 100644
|
||||
// reset to null.
|
||||
const CookieAccessDelegate* cookie_access_delegate() const {
|
||||
diff --git services/network/cookie_manager.cc services/network/cookie_manager.cc
|
||||
index 6c804ec1092af..605ff3b32b0b8 100644
|
||||
index b43998a09b981..6249ece59ae77 100644
|
||||
--- services/network/cookie_manager.cc
|
||||
+++ services/network/cookie_manager.cc
|
||||
@@ -297,14 +297,9 @@ void CookieManager::AllowFileSchemeCookies(
|
||||
|
@@ -414,7 +414,7 @@ index 2f552f72074e3..3f057242d198c 100644
|
||||
}
|
||||
|
||||
diff --git ui/views/widget/widget.h ui/views/widget/widget.h
|
||||
index 419b75d0608b2..d772dc17d165c 100644
|
||||
index 419b75d0608b2..57bb1fca770ed 100644
|
||||
--- ui/views/widget/widget.h
|
||||
+++ ui/views/widget/widget.h
|
||||
@@ -351,6 +351,8 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate,
|
||||
@@ -426,6 +426,15 @@ index 419b75d0608b2..d772dc17d165c 100644
|
||||
// Specifies the initial bounds of the Widget. Default is empty, which means
|
||||
// the NativeWidget may specify a default size. If the parent is specified,
|
||||
// |bounds| is in the parent's coordinate system. If the parent is not
|
||||
@@ -742,7 +744,7 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate,
|
||||
void ShowInactive();
|
||||
|
||||
// Activates the widget, assuming it already exists and is visible.
|
||||
- void Activate();
|
||||
+ virtual void Activate();
|
||||
|
||||
// Deactivates the widget, making the next window in the Z order the active
|
||||
// window.
|
||||
diff --git ui/views/widget/widget_delegate.h ui/views/widget/widget_delegate.h
|
||||
index 6d87be86ae8b3..02fe7a11958d0 100644
|
||||
--- ui/views/widget/widget_delegate.h
|
||||
|
@@ -11,7 +11,7 @@ index 8a18ecf567cd3..9697d43bbbfb9 100644
|
||||
// Cancels and hides the current popup (datetime, select...) if any.
|
||||
virtual void CancelPagePopup() = 0;
|
||||
diff --git third_party/blink/renderer/core/exported/web_view_impl.cc third_party/blink/renderer/core/exported/web_view_impl.cc
|
||||
index acb43e9f5471e..d78498411ec92 100644
|
||||
index 866af04a935f8..0223a58e5d475 100644
|
||||
--- third_party/blink/renderer/core/exported/web_view_impl.cc
|
||||
+++ third_party/blink/renderer/core/exported/web_view_impl.cc
|
||||
@@ -249,8 +249,13 @@ void WebView::SetUseExternalPopupMenus(bool use_external_popup_menus) {
|
||||
|
60
tests/cefclient/browser/binary_transfer_test.cc
Normal file
60
tests/cefclient/browser/binary_transfer_test.cc
Normal file
@@ -0,0 +1,60 @@
|
||||
// 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/binary_transfer_test.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
|
||||
namespace {
|
||||
|
||||
const char kTestUrlPath[] = "/binary_transfer";
|
||||
|
||||
// Handle messages in the browser process.
|
||||
class Handler final : public CefMessageRouterBrowserSide::Handler {
|
||||
public:
|
||||
// Called due to cefQuery execution in binary_transfer.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 (!client::test_runner::IsTestURL(url, kTestUrlPath)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
callback->Success(request);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Called due to cefQuery execution in binary_transfer.html.
|
||||
bool OnQuery(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
int64_t query_id,
|
||||
CefRefPtr<const CefBinaryBuffer> request,
|
||||
bool persistent,
|
||||
CefRefPtr<Callback> callback) override {
|
||||
// Only handle messages from the test URL.
|
||||
const std::string& url = frame->GetURL();
|
||||
if (!client::test_runner::IsTestURL(url, kTestUrlPath)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
callback->Success(request->GetData(), request->GetSize());
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace client::binary_transfer_test {
|
||||
|
||||
void CreateMessageHandlers(test_runner::MessageHandlerSet& handlers) {
|
||||
handlers.insert(new Handler());
|
||||
}
|
||||
|
||||
} // namespace client::binary_transfer_test
|
17
tests/cefclient/browser/binary_transfer_test.h
Normal file
17
tests/cefclient/browser/binary_transfer_test.h
Normal file
@@ -0,0 +1,17 @@
|
||||
// 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.
|
||||
|
||||
#ifndef CEF_TESTS_CEFCLIENT_BROWSER_BINARY_TRANSFER_TEST_H_
|
||||
#define CEF_TESTS_CEFCLIENT_BROWSER_BINARY_TRANSFER_TEST_H_
|
||||
#pragma once
|
||||
|
||||
#include "tests/cefclient/browser/test_runner.h"
|
||||
|
||||
namespace client::binary_transfer_test {
|
||||
|
||||
void CreateMessageHandlers(test_runner::MessageHandlerSet& handlers);
|
||||
|
||||
} // namespace client::binary_transfer_test
|
||||
|
||||
#endif // CEF_TESTS_CEFCLIENT_BROWSER_BINARY_TRANSFER_TEST_H_
|
@@ -583,7 +583,7 @@ bool ClientHandler::OnChromeCommand(CefRefPtr<CefBrowser> browser,
|
||||
} else if (!with_controls_) {
|
||||
// If controls are hidden, block all commands that don't target the current
|
||||
// tab or aren't specifically allowed.
|
||||
block = disposition != WOD_CURRENT_TAB || !allowed;
|
||||
block = disposition != CEF_WOD_CURRENT_TAB || !allowed;
|
||||
}
|
||||
|
||||
if (block) {
|
||||
@@ -644,11 +644,12 @@ void ClientHandler::OnBeforeContextMenu(CefRefPtr<CefBrowser> browser,
|
||||
model->AddSeparator();
|
||||
}
|
||||
|
||||
// Add DevTools items to all context menus.
|
||||
model->AddItem(CLIENT_ID_SHOW_DEVTOOLS, "&Show DevTools");
|
||||
model->AddItem(CLIENT_ID_CLOSE_DEVTOOLS, "Close DevTools");
|
||||
|
||||
if (!use_chrome_runtime) {
|
||||
// TODO(chrome-runtime): Add support for this.
|
||||
// Add DevTools items to all context menus.
|
||||
model->AddItem(CLIENT_ID_SHOW_DEVTOOLS, "&Show DevTools");
|
||||
model->AddItem(CLIENT_ID_CLOSE_DEVTOOLS, "Close DevTools");
|
||||
// Chrome runtime already gives us an "Inspect" menu item.
|
||||
model->AddSeparator();
|
||||
model->AddItem(CLIENT_ID_INSPECT_ELEMENT, "Inspect Element");
|
||||
}
|
||||
@@ -938,15 +939,36 @@ bool ClientHandler::OnBeforePopup(
|
||||
bool* no_javascript_access) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
|
||||
if (target_disposition == WOD_NEW_PICTURE_IN_PICTURE) {
|
||||
if (target_disposition == CEF_WOD_NEW_PICTURE_IN_PICTURE) {
|
||||
// Use default handling for document picture-in-picture popups.
|
||||
client = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Return true to cancel the popup window.
|
||||
return !CreatePopupWindow(browser, false, popupFeatures, windowInfo, client,
|
||||
settings);
|
||||
// Potentially create a new RootWindow for the popup browser that will be
|
||||
// created asynchronously.
|
||||
CreatePopupWindow(browser, /*is_devtools=*/false, popupFeatures, windowInfo,
|
||||
client, settings);
|
||||
|
||||
// Allow popup creation.
|
||||
return false;
|
||||
}
|
||||
|
||||
void ClientHandler::OnBeforeDevToolsPopup(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefWindowInfo& windowInfo,
|
||||
CefRefPtr<CefClient>& client,
|
||||
CefBrowserSettings& settings,
|
||||
CefRefPtr<CefDictionaryValue>& extra_info,
|
||||
bool* use_default_window) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
|
||||
// Potentially create a new RootWindow for the DevTools popup browser that
|
||||
// will be created immediately after this method returns.
|
||||
if (!CreatePopupWindow(browser, /*is_devtools=*/true, CefPopupFeatures(),
|
||||
windowInfo, client, settings)) {
|
||||
*use_default_window = true;
|
||||
}
|
||||
}
|
||||
|
||||
void ClientHandler::OnAfterCreated(CefRefPtr<CefBrowser> browser) {
|
||||
@@ -1081,8 +1103,8 @@ bool ClientHandler::OnOpenURLFromTab(
|
||||
const CefString& target_url,
|
||||
CefRequestHandler::WindowOpenDisposition target_disposition,
|
||||
bool user_gesture) {
|
||||
if (target_disposition == WOD_NEW_BACKGROUND_TAB ||
|
||||
target_disposition == WOD_NEW_FOREGROUND_TAB) {
|
||||
if (target_disposition == CEF_WOD_NEW_BACKGROUND_TAB ||
|
||||
target_disposition == CEF_WOD_NEW_FOREGROUND_TAB) {
|
||||
// Handle middle-click and ctrl + left-click by opening the URL in a new
|
||||
// browser window.
|
||||
auto config = std::make_unique<RootWindowConfig>();
|
||||
@@ -1303,25 +1325,21 @@ void ClientHandler::ShowDevTools(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefClient> client;
|
||||
CefBrowserSettings settings;
|
||||
|
||||
MainContext::Get()->PopulateBrowserSettings(&settings);
|
||||
|
||||
CefRefPtr<CefBrowserHost> host = browser->GetHost();
|
||||
|
||||
// Test if the DevTools browser already exists.
|
||||
bool has_devtools = host->HasDevTools();
|
||||
if (!has_devtools) {
|
||||
// Create a new RootWindow for the DevTools browser that will be created
|
||||
// by ShowDevTools().
|
||||
has_devtools = CreatePopupWindow(browser, true, CefPopupFeatures(),
|
||||
windowInfo, client, settings);
|
||||
if (!MainContext::Get()->UseChromeRuntime() && !host->HasDevTools()) {
|
||||
// Potentially create a new RootWindow for the DevTools browser that will be
|
||||
// created by ShowDevTools(). For Chrome runtime this occurs in
|
||||
// OnBeforeDevToolsPopup instead.
|
||||
CreatePopupWindow(browser, /*is_devtools=*/true, CefPopupFeatures(),
|
||||
windowInfo, client, settings);
|
||||
}
|
||||
|
||||
if (has_devtools) {
|
||||
// Create the DevTools browser if it doesn't already exist.
|
||||
// Otherwise, focus the existing DevTools browser and inspect the element
|
||||
// at |inspect_element_at| if non-empty.
|
||||
host->ShowDevTools(windowInfo, client, settings, inspect_element_at);
|
||||
}
|
||||
// Create the DevTools browser if it doesn't already exist.
|
||||
// Otherwise, focus the existing DevTools browser and inspect the element
|
||||
// at |inspect_element_at| if non-empty.
|
||||
host->ShowDevTools(windowInfo, client, settings, inspect_element_at);
|
||||
}
|
||||
|
||||
void ClientHandler::CloseDevTools(CefRefPtr<CefBrowser> browser) {
|
||||
@@ -1407,11 +1425,10 @@ bool ClientHandler::CreatePopupWindow(CefRefPtr<CefBrowser> browser,
|
||||
|
||||
// The popup browser will be parented to a new native window.
|
||||
// Don't show URL bar and navigation buttons on DevTools windows.
|
||||
MainContext::Get()->GetRootWindowManager()->CreateRootWindowAsPopup(
|
||||
// May return nullptr if UseDefaultPopup() returns true.
|
||||
return !!MainContext::Get()->GetRootWindowManager()->CreateRootWindowAsPopup(
|
||||
with_controls_ && !is_devtools, is_osr_, popupFeatures, windowInfo,
|
||||
client, settings);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ClientHandler::NotifyBrowserCreated(CefRefPtr<CefBrowser> browser) {
|
||||
|
@@ -224,6 +224,12 @@ class ClientHandler : public CefClient,
|
||||
CefBrowserSettings& settings,
|
||||
CefRefPtr<CefDictionaryValue>& extra_info,
|
||||
bool* no_javascript_access) override;
|
||||
void OnBeforeDevToolsPopup(CefRefPtr<CefBrowser> browser,
|
||||
CefWindowInfo& windowInfo,
|
||||
CefRefPtr<CefClient>& client,
|
||||
CefBrowserSettings& settings,
|
||||
CefRefPtr<CefDictionaryValue>& extra_info,
|
||||
bool* use_default_window) override;
|
||||
void OnAfterCreated(CefRefPtr<CefBrowser> browser) override;
|
||||
bool DoClose(CefRefPtr<CefBrowser> browser) override;
|
||||
void OnBeforeClose(CefRefPtr<CefBrowser> browser) override;
|
||||
@@ -348,9 +354,8 @@ class ClientHandler : public CefClient,
|
||||
friend class ClientDownloadImageCallback;
|
||||
|
||||
// Create a new popup window using the specified information. |is_devtools|
|
||||
// will be true if the window will be used for DevTools. Return true to
|
||||
// proceed with popup browser creation or false to cancel the popup browser.
|
||||
// May be called on any thead.
|
||||
// will be true if the window will be used for DevTools. Returns true if a
|
||||
// RootWindow was created for the popup.
|
||||
bool CreatePopupWindow(CefRefPtr<CefBrowser> browser,
|
||||
bool is_devtools,
|
||||
const CefPopupFeatures& popupFeatures,
|
||||
|
@@ -42,6 +42,10 @@ class MainContext {
|
||||
// Returns true if the Chrome runtime will be used.
|
||||
virtual bool UseChromeRuntime() = 0;
|
||||
|
||||
// Returns true if a native parent window is being used with the Chrome
|
||||
// runtime.
|
||||
virtual bool UseChromeRuntimeNative() = 0;
|
||||
|
||||
// Returns true if the Views framework will be used.
|
||||
virtual bool UseViews() = 0;
|
||||
|
||||
|
@@ -111,8 +111,9 @@ MainContextImpl::MainContextImpl(CefRefPtr<CefCommandLine> command_line,
|
||||
}
|
||||
|
||||
#if defined(OS_WIN) || defined(OS_LINUX)
|
||||
if (use_chrome_runtime_ && !use_views_ &&
|
||||
!command_line->HasSwitch(switches::kUseNative)) {
|
||||
use_chrome_runtime_native_ =
|
||||
use_chrome_runtime_ && command_line->HasSwitch(switches::kUseNative);
|
||||
if (use_chrome_runtime_ && !use_views_ && !use_chrome_runtime_native_) {
|
||||
LOG(WARNING) << "Chrome runtime defaults to the Views framework.";
|
||||
use_views_ = true;
|
||||
}
|
||||
@@ -174,6 +175,10 @@ bool MainContextImpl::UseChromeRuntime() {
|
||||
return use_chrome_runtime_;
|
||||
}
|
||||
|
||||
bool MainContextImpl::UseChromeRuntimeNative() {
|
||||
return use_chrome_runtime_native_;
|
||||
}
|
||||
|
||||
bool MainContextImpl::UseViews() {
|
||||
return use_views_;
|
||||
}
|
||||
|
@@ -29,6 +29,7 @@ class MainContextImpl : public MainContext {
|
||||
std::string GetMainURL() override;
|
||||
cef_color_t GetBackgroundColor() override;
|
||||
bool UseChromeRuntime() override;
|
||||
bool UseChromeRuntimeNative() override;
|
||||
bool UseViews() override;
|
||||
bool UseWindowlessRendering() override;
|
||||
bool TouchEventsEnabled() override;
|
||||
@@ -74,6 +75,7 @@ class MainContextImpl : public MainContext {
|
||||
bool use_windowless_rendering_;
|
||||
int windowless_frame_rate_ = 0;
|
||||
bool use_chrome_runtime_;
|
||||
bool use_chrome_runtime_native_ = false;
|
||||
bool use_views_;
|
||||
|
||||
std::unique_ptr<RootWindowManager> root_window_manager_;
|
||||
|
@@ -44,31 +44,32 @@
|
||||
#define ID_TESTS_UNMUTE_AUDIO 32717
|
||||
#define ID_TESTS_LAST 32717
|
||||
#define IDC_STATIC -1
|
||||
#define IDS_BINDING_HTML 1000
|
||||
#define IDS_DIALOGS_HTML 1001
|
||||
#define IDS_DRAGGABLE_HTML 1002
|
||||
#define IDS_IPC_PERFORMANCE_HTML 1003
|
||||
#define IDS_LOCALSTORAGE_HTML 1004
|
||||
#define IDS_LOGO_PNG 1005
|
||||
#define IDS_MEDIA_ROUTER_HTML 1006
|
||||
#define IDS_MENU_ICON_1X_PNG 1007
|
||||
#define IDS_MENU_ICON_2X_PNG 1008
|
||||
#define IDS_OSRTEST_HTML 1009
|
||||
#define IDS_OTHER_TESTS_HTML 1010
|
||||
#define IDS_PDF_HTML 1011
|
||||
#define IDS_PDF_PDF 1012
|
||||
#define IDS_PERFORMANCE_HTML 1013
|
||||
#define IDS_PERFORMANCE2_HTML 1014
|
||||
#define IDS_PREFERENCES_HTML 1015
|
||||
#define IDS_RESPONSE_FILTER_HTML 1016
|
||||
#define IDS_SERVER_HTML 1017
|
||||
#define IDS_TRANSPARENCY_HTML 1018
|
||||
#define IDS_URLREQUEST_HTML 1019
|
||||
#define IDS_WEBSOCKET_HTML 1020
|
||||
#define IDS_WINDOW_HTML 1021
|
||||
#define IDS_WINDOW_ICON_1X_PNG 1022
|
||||
#define IDS_WINDOW_ICON_2X_PNG 1023
|
||||
#define IDS_XMLHTTPREQUEST_HTML 1024
|
||||
#define IDS_BINARY_TRANSFER_HTML 1000
|
||||
#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_EXTENSIONS_SET_PAGE_COLOR_ICON_PNG 1030
|
||||
#define IDS_EXTENSIONS_SET_PAGE_COLOR_MANIFEST_JSON 1031
|
||||
|
@@ -13,7 +13,8 @@ int GetResourceId(const char* resource_name) {
|
||||
static struct _resource_map {
|
||||
const char* name;
|
||||
int id;
|
||||
} resource_map[] = {{"binding.html", IDS_BINDING_HTML},
|
||||
} resource_map[] = {{"binary_transfer.html", IDS_BINARY_TRANSFER_HTML},
|
||||
{"binding.html", IDS_BINDING_HTML},
|
||||
{"dialogs.html", IDS_DIALOGS_HTML},
|
||||
{"draggable.html", IDS_DRAGGABLE_HTML},
|
||||
{"extensions/set_page_color/icon.png",
|
||||
|
@@ -28,6 +28,9 @@ enum class WindowType {
|
||||
|
||||
// The window is a modal dialog.
|
||||
DIALOG,
|
||||
|
||||
// The window is a DevTools popup.
|
||||
DEVTOOLS,
|
||||
};
|
||||
|
||||
// Used to configure how a RootWindow is created.
|
||||
|
@@ -249,7 +249,7 @@ void RootWindowViews::OnViewsWindowClosing(CefRefPtr<ViewsWindow> window) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
DCHECK(window_);
|
||||
|
||||
if (config_->window_type != WindowType::NORMAL) {
|
||||
if (!window_->SupportsWindowRestore()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -516,7 +516,7 @@ void RootWindowViews::InitOnUIThread(
|
||||
// Initial state was specified via the config object.
|
||||
initial_bounds_ = config_->bounds;
|
||||
initial_show_state_ = config_->show_state;
|
||||
} else if (config_->window_type == WindowType::NORMAL) {
|
||||
} else if (ViewsWindow::SupportsWindowRestore(config_->window_type)) {
|
||||
// Initial state may be specified via the command-line or global
|
||||
// preferences.
|
||||
std::optional<CefRect> bounds;
|
||||
|
@@ -16,6 +16,7 @@
|
||||
#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/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"
|
||||
@@ -842,6 +843,9 @@ bool IsTestURL(const std::string& url, const std::string& path) {
|
||||
void CreateMessageHandlers(MessageHandlerSet& handlers) {
|
||||
handlers.insert(new PromptHandler);
|
||||
|
||||
// Create the binary trasfer test handlers.
|
||||
binary_transfer_test::CreateMessageHandlers(handlers);
|
||||
|
||||
// Create the binding test handlers.
|
||||
binding_test::CreateMessageHandlers(handlers);
|
||||
|
||||
|
@@ -399,10 +399,21 @@ void ViewsWindow::OnExtensionsChanged(const ExtensionSet& extensions) {
|
||||
base::BindOnce(&ViewsWindow::OnExtensionIconsLoaded, this, extensions));
|
||||
}
|
||||
|
||||
// static
|
||||
bool ViewsWindow::SupportsWindowRestore(WindowType type) {
|
||||
// Only support window restore with normal windows.
|
||||
return type == WindowType::NORMAL;
|
||||
}
|
||||
|
||||
bool ViewsWindow::SupportsWindowRestore() const {
|
||||
return SupportsWindowRestore(type_);
|
||||
}
|
||||
|
||||
bool ViewsWindow::GetWindowRestorePreferences(
|
||||
cef_show_state_t& show_state,
|
||||
std::optional<CefRect>& dip_bounds) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
DCHECK(SupportsWindowRestore());
|
||||
if (!window_) {
|
||||
return false;
|
||||
}
|
||||
@@ -460,7 +471,9 @@ CefRefPtr<CefBrowserViewDelegate> ViewsWindow::GetDelegateForPopupBrowserView(
|
||||
DCHECK(popup_delegate != delegate_);
|
||||
|
||||
// Create a new ViewsWindow for the popup BrowserView.
|
||||
return new ViewsWindow(WindowType::NORMAL, popup_delegate, nullptr);
|
||||
return new ViewsWindow(
|
||||
is_devtools ? WindowType::DEVTOOLS : WindowType::NORMAL, popup_delegate,
|
||||
nullptr);
|
||||
}
|
||||
|
||||
bool ViewsWindow::OnPopupBrowserViewCreated(
|
||||
@@ -651,6 +664,18 @@ void ViewsWindow::OnWindowFullscreenTransition(CefRefPtr<CefWindow> window,
|
||||
if (should_change && with_controls_) {
|
||||
ShowTopControls(!window->IsFullscreen());
|
||||
}
|
||||
|
||||
// With Alloy runtime we need to explicitly exit browser fullscreen when
|
||||
// exiting window fullscreen. Chrome runtime handles this internally.
|
||||
if (!MainContext::Get()->UseChromeRuntime() && should_change &&
|
||||
!window->IsFullscreen()) {
|
||||
CefRefPtr<CefBrowser> browser = browser_view_->GetBrowser();
|
||||
if (browser && browser->GetHost()->IsFullscreen()) {
|
||||
// Will not cause a resize because the fullscreen transition has already
|
||||
// begun.
|
||||
browser->GetHost()->ExitFullscreen(/*will_cause_resize=*/false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ViewsWindow::OnWindowCreated(CefRefPtr<CefWindow> window) {
|
||||
@@ -664,12 +689,12 @@ void ViewsWindow::OnWindowCreated(CefRefPtr<CefWindow> window) {
|
||||
|
||||
delegate_->OnViewsWindowCreated(this);
|
||||
|
||||
if (type_ == WindowType::NORMAL) {
|
||||
if (type_ == WindowType::NORMAL || type_ == WindowType::DEVTOOLS) {
|
||||
const CefRect bounds = delegate_->GetInitialBounds();
|
||||
if (bounds.IsEmpty()) {
|
||||
// Size the Window and center it at the default size.
|
||||
window_->CenterWindow(CefSize(kDefaultWidth, kDefaultHeight));
|
||||
} else {
|
||||
} else if (SupportsWindowRestore()) {
|
||||
// Remember the bounds from the previous application run in case the user
|
||||
// does not move or resize the window during this application run.
|
||||
last_visible_bounds_ = bounds;
|
||||
@@ -746,7 +771,7 @@ void ViewsWindow::OnWindowActivationChanged(CefRefPtr<CefWindow> window,
|
||||
|
||||
void ViewsWindow::OnWindowBoundsChanged(CefRefPtr<CefWindow> window,
|
||||
const CefRect& new_bounds) {
|
||||
if (type_ == WindowType::NORMAL && !window->IsMinimized() &&
|
||||
if (SupportsWindowRestore() && !window->IsMinimized() &&
|
||||
!window->IsMaximized() && !window->IsFullscreen()) {
|
||||
// Track the last visible bounds for window restore purposes.
|
||||
last_visible_bounds_ = new_bounds;
|
||||
@@ -833,20 +858,18 @@ bool ViewsWindow::GetTitlebarHeight(CefRefPtr<CefWindow> window,
|
||||
|
||||
bool ViewsWindow::CanResize(CefRefPtr<CefWindow> window) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
// Only allow resize of normal windows.
|
||||
return type_ == WindowType::NORMAL;
|
||||
// Only allow resize of normal and DevTools windows.
|
||||
return type_ == WindowType::NORMAL || type_ == WindowType::DEVTOOLS;
|
||||
}
|
||||
|
||||
bool ViewsWindow::CanMaximize(CefRefPtr<CefWindow> window) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
// Only allow maximize of normal windows.
|
||||
return type_ == WindowType::NORMAL;
|
||||
return CanResize(window);
|
||||
}
|
||||
|
||||
bool ViewsWindow::CanMinimize(CefRefPtr<CefWindow> window) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
// Only allow minimize of normal windows.
|
||||
return type_ == WindowType::NORMAL;
|
||||
return CanResize(window);
|
||||
}
|
||||
|
||||
bool ViewsWindow::OnAccelerator(CefRefPtr<CefWindow> window, int command_id) {
|
||||
@@ -1271,12 +1294,11 @@ void ViewsWindow::AddControls() {
|
||||
}
|
||||
|
||||
void ViewsWindow::AddAccelerators() {
|
||||
// Trigger accelerators without first forwarding to web content.
|
||||
browser_view_->SetPreferAccelerators(true);
|
||||
|
||||
// Specify the accelerators to handle. OnAccelerator will be called when the
|
||||
// accelerator is triggered.
|
||||
window_->SetAccelerator(ID_QUIT, 'X', false, false, true);
|
||||
window_->SetAccelerator(ID_QUIT, 'X', /*shift_pressed=*/false,
|
||||
/*ctrl_pressed=*/false, /*alt_pressed=*/true,
|
||||
/*high_priority=*/true);
|
||||
}
|
||||
|
||||
void ViewsWindow::SetMenuFocusable(bool focusable) {
|
||||
|
@@ -127,6 +127,8 @@ class ViewsWindow : public CefBrowserViewDelegate,
|
||||
void OnBeforeContextMenu(CefRefPtr<CefMenuModel> model);
|
||||
void OnExtensionsChanged(const ExtensionSet& extensions);
|
||||
|
||||
static bool SupportsWindowRestore(WindowType type);
|
||||
bool SupportsWindowRestore() const;
|
||||
bool GetWindowRestorePreferences(cef_show_state_t& show_state,
|
||||
std::optional<CefRect>& dip_bounds);
|
||||
void SetTitlebarHeight(const std::optional<float>& height);
|
||||
|
498
tests/cefclient/resources/binary_transfer.html
Normal file
498
tests/cefclient/resources/binary_transfer.html
Normal file
@@ -0,0 +1,498 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Binary vs String Transfer Benchmark</title>
|
||||
<script src="https://cdn.plot.ly/plotly-2.26.0.min.js"></script>
|
||||
<style>
|
||||
body {
|
||||
font-family: Tahoma, Serif;
|
||||
font-size: 10pt;
|
||||
}
|
||||
.info {
|
||||
font-size: 12pt;
|
||||
}
|
||||
.left {
|
||||
text-align: left;
|
||||
}
|
||||
.right {
|
||||
text-align: right;
|
||||
}
|
||||
.positive {
|
||||
color: green;
|
||||
font-weight: bold;
|
||||
}
|
||||
.negative {
|
||||
color: red;
|
||||
font-weight: bold;
|
||||
}
|
||||
.center {
|
||||
text-align: center;
|
||||
}
|
||||
table.resultTable {
|
||||
border: 1px solid black;
|
||||
border-collapse: collapse;
|
||||
empty-cells: show;
|
||||
width: 100%;
|
||||
}
|
||||
table.resultTable td {
|
||||
padding: 2px 4px;
|
||||
border: 1px solid black;
|
||||
}
|
||||
table.resultTable > thead > tr {
|
||||
font-weight: bold;
|
||||
background: lightblue;
|
||||
}
|
||||
table.resultTable > tbody > tr:nth-child(odd) {
|
||||
background: white;
|
||||
}
|
||||
table.resultTable > tbody > tr:nth-child(even) {
|
||||
background: lightgray;
|
||||
}
|
||||
.hide {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body background-color="white">
|
||||
<h1>Binary vs String Transfer Benchmark</h1>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<p class="info">
|
||||
This benchmark evaluates the message transfer speed between the
|
||||
renderer process and the browser process. <br />It compares the
|
||||
performance of binary and string message transfer.
|
||||
</p>
|
||||
<p class="info">
|
||||
<b>Note:</b> There is no progress indication of the tests because it
|
||||
significantly influences measurements. <br />It usually takes 30
|
||||
seconds (for 300 samples) to complete the tests.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
Samples:
|
||||
<input
|
||||
id="sSamples"
|
||||
type="text"
|
||||
value="300"
|
||||
required
|
||||
pattern="[0-9]+"
|
||||
/>
|
||||
<button id="sRun" autofocus onclick="runTestSuite()">Run</button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<div style="padding-top: 10px; padding-bottom: 10px">
|
||||
<table id="resultTable" class="resultTable">
|
||||
<thead>
|
||||
<tr>
|
||||
<td class="center" style="width: 8%">Message Size</td>
|
||||
<td class="center" style="width: 8%">
|
||||
String Round Trip Avg, ms
|
||||
</td>
|
||||
<td class="center" style="width: 8%">
|
||||
Binary Round Trip Avg, ms
|
||||
</td>
|
||||
<td class="center" style="width: 10%">Relative Trip Difference</td>
|
||||
<td class="center" style="width: 8%">String Speed, MB/s</td>
|
||||
<td class="center" style="width: 8%">Binary Speed, MB/s</td>
|
||||
<td class="center" style="width: 10%">Relative Speed Difference</td>
|
||||
<td class="center" style="width: 8%">String Standard Deviation</td>
|
||||
<td class="center" style="width: 8%">Binary Standard Deviation</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<!-- result rows here -->
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div id="round_trip_avg_chart">
|
||||
<!-- Average round trip linear chart will be drawn inside this DIV -->
|
||||
</div>
|
||||
|
||||
<div id="box_plot_chart">
|
||||
<!-- Box plot of round trip time will be drawn inside this DIV -->
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
let tests = [];
|
||||
let box_plot_test_data = [];
|
||||
let round_trip_avg_plot_data = [];
|
||||
|
||||
function nextTestSuite(testIndex) {
|
||||
const nextTestIndex = testIndex + 1;
|
||||
setTimeout(execTestSuite, 0, nextTestIndex);
|
||||
}
|
||||
|
||||
function generateRandomString(size) {
|
||||
// Symbols that will be encoded as two bytes in UTF-8
|
||||
// so we compare transfer of the same amount of bytes
|
||||
const characters =
|
||||
"АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдеёжзийклмнопрстуфхцчшщъыьэюя";
|
||||
let randomString = "";
|
||||
for (let i = 0; i < size; i++) {
|
||||
const randomIndex = Math.floor(Math.random() * characters.length);
|
||||
randomString += characters.charAt(randomIndex);
|
||||
}
|
||||
return randomString;
|
||||
}
|
||||
|
||||
function generateRandomArrayBuffer(size) {
|
||||
const buffer = new ArrayBuffer(size);
|
||||
const uint8Array = new Uint8Array(buffer);
|
||||
for (let i = 0; i < uint8Array.length; i++) {
|
||||
uint8Array[i] = Math.floor(Math.random() * 256);
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
function reportError(errorCode, errorMessage) {
|
||||
console.error(`ErrorCode:${errorCode} Message:${errorMessage}`);
|
||||
}
|
||||
|
||||
function sendString(size, testIndex) {
|
||||
const request = generateRandomString(size);
|
||||
const startTime = performance.now();
|
||||
const onSuccess = (response) => {
|
||||
const roundTrip = performance.now() - startTime;
|
||||
const test = tests[testIndex];
|
||||
test.totalRoundTrip += roundTrip;
|
||||
test.sample++;
|
||||
box_plot_test_data[testIndex].x.push(roundTrip);
|
||||
setTimeout(execTest, 0, testIndex);
|
||||
};
|
||||
|
||||
window.cefQuery({
|
||||
request: request,
|
||||
onSuccess: onSuccess,
|
||||
onFailure: reportError,
|
||||
});
|
||||
}
|
||||
|
||||
function sendArrayBuffer(size, testIndex) {
|
||||
const request = generateRandomArrayBuffer(size);
|
||||
const startTime = performance.now();
|
||||
const onSuccess = (response) => {
|
||||
const roundTrip = performance.now() - startTime;
|
||||
const test = tests[testIndex];
|
||||
test.totalRoundTrip += roundTrip;
|
||||
test.sample++;
|
||||
box_plot_test_data[testIndex].x.push(roundTrip);
|
||||
setTimeout(execTest, 0, testIndex);
|
||||
};
|
||||
|
||||
window.cefQuery({
|
||||
request: request,
|
||||
onSuccess: onSuccess,
|
||||
onFailure: reportError,
|
||||
});
|
||||
}
|
||||
|
||||
function getStandardDeviation(array, mean) {
|
||||
const n = array.length;
|
||||
if (n < 5) return null;
|
||||
return Math.sqrt(
|
||||
array.map((x) => Math.pow(x - mean, 2)).reduce((a, b) => a + b) /
|
||||
(n - 1)
|
||||
);
|
||||
}
|
||||
|
||||
function execTest(testIndex) {
|
||||
const test = tests[testIndex];
|
||||
if (test.sample >= test.totalSamples) {
|
||||
return nextTestSuite(testIndex);
|
||||
}
|
||||
test.func(test.length, test.index);
|
||||
}
|
||||
|
||||
function column(prepared, value) {
|
||||
return (
|
||||
"<td class='right'>" + (!prepared ? "-" : value.toFixed(3)) + "</td>"
|
||||
);
|
||||
}
|
||||
|
||||
function relativeDiffColumn(prepared, value, isBiggerBetter) {
|
||||
if (!prepared) return "<td class='right'>-</td>";
|
||||
|
||||
const isPositive = value >= 0 == isBiggerBetter;
|
||||
return [
|
||||
"<td class='right ",
|
||||
isPositive ? "positive" : "negative",
|
||||
"'>",
|
||||
value > 0 ? "+" : "",
|
||||
value.toFixed(2),
|
||||
"%</td>",
|
||||
].join("");
|
||||
}
|
||||
|
||||
function displayResult(test) {
|
||||
const id = "testResultRow_" + test.index;
|
||||
|
||||
const markup = [
|
||||
"<tr id='",
|
||||
id,
|
||||
"'>",
|
||||
"<td class='left'>",
|
||||
test.name,
|
||||
"</td>",
|
||||
column(test.prepared, test.avgRoundTrip),
|
||||
column(test.prepared, test.avgRoundTripBin),
|
||||
relativeDiffColumn(test.prepared, test.relativeTripDiff, false),
|
||||
column(test.prepared, test.speed),
|
||||
column(test.prepared, test.speedBinary),
|
||||
relativeDiffColumn(test.prepared, test.relativeSpeedDiff, true),
|
||||
"<td class='right'>",
|
||||
!test.prepared || test.stdDeviation == null
|
||||
? "-"
|
||||
: test.stdDeviation.toFixed(3),
|
||||
"</td>",
|
||||
"<td class='right'>",
|
||||
!test.prepared || test.stdDeviationBinary == null
|
||||
? "-"
|
||||
: test.stdDeviationBinary.toFixed(3),
|
||||
"</td>",
|
||||
"</tr>",
|
||||
].join("");
|
||||
|
||||
const row = document.getElementById(id);
|
||||
if (row) {
|
||||
row.outerHTML = markup;
|
||||
} else {
|
||||
const tbody = document.getElementById("resultTable").tBodies[0];
|
||||
tbody.insertAdjacentHTML("beforeEnd", markup);
|
||||
}
|
||||
}
|
||||
function relativeDiff(left, right) {
|
||||
if (right != 0) {
|
||||
return ((left - right) / right) * 100;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
function buildTestResults(tests) {
|
||||
testResults = [];
|
||||
|
||||
let oldRoundTrip = {
|
||||
x: [],
|
||||
y: [],
|
||||
type: "scatter",
|
||||
name: "String",
|
||||
};
|
||||
|
||||
let newRoundTrip = {
|
||||
x: [],
|
||||
y: [],
|
||||
type: "scatter",
|
||||
name: "Binary",
|
||||
};
|
||||
|
||||
for (let i = 0; i < tests.length / 2; i++) {
|
||||
const index = testResults.length;
|
||||
|
||||
// Tests are in pairs - String and Binary
|
||||
const test = tests[i * 2];
|
||||
const testBin = tests[i * 2 + 1];
|
||||
|
||||
const avgRoundTrip = test.totalRoundTrip / test.totalSamples;
|
||||
const avgRoundTripBin = testBin.totalRoundTrip / testBin.totalSamples;
|
||||
const relativeTripDiff = relativeDiff(avgRoundTripBin, avgRoundTrip);
|
||||
|
||||
// In MB/s
|
||||
const speed = test.byteSize / (avgRoundTrip * 1000);
|
||||
const speedBinary = testBin.byteSize / (avgRoundTripBin * 1000);
|
||||
const relativeSpeedDiff = relativeDiff(speedBinary, speed);
|
||||
|
||||
const stdDeviation = getStandardDeviation(
|
||||
box_plot_test_data[test.index].x,
|
||||
avgRoundTrip
|
||||
);
|
||||
const stdDeviationBinary = getStandardDeviation(
|
||||
box_plot_test_data[testBin.index].x,
|
||||
avgRoundTripBin
|
||||
);
|
||||
|
||||
testResults.push({
|
||||
name: humanFileSize(test.byteSize),
|
||||
index: index,
|
||||
prepared: true,
|
||||
avgRoundTrip: avgRoundTrip,
|
||||
avgRoundTripBin: avgRoundTripBin,
|
||||
relativeTripDiff: relativeTripDiff,
|
||||
speed: speed,
|
||||
speedBinary: speedBinary,
|
||||
relativeSpeedDiff: relativeSpeedDiff,
|
||||
stdDeviation: stdDeviation,
|
||||
stdDeviationBinary: stdDeviationBinary,
|
||||
});
|
||||
|
||||
oldRoundTrip.x.push(test.byteSize);
|
||||
newRoundTrip.x.push(test.byteSize);
|
||||
oldRoundTrip.y.push(avgRoundTrip);
|
||||
newRoundTrip.y.push(avgRoundTripBin);
|
||||
}
|
||||
|
||||
round_trip_avg_plot_data = [oldRoundTrip, newRoundTrip];
|
||||
return testResults;
|
||||
}
|
||||
|
||||
function buildEmptyTestResults(tests) {
|
||||
testResults = [];
|
||||
for (let i = 0; i < tests.length / 2; i++) {
|
||||
const index = testResults.length;
|
||||
const test = tests[i * 2];
|
||||
|
||||
testResults.push({
|
||||
name: humanFileSize(test.byteSize),
|
||||
index: index,
|
||||
prepared: false,
|
||||
});
|
||||
}
|
||||
return testResults;
|
||||
}
|
||||
|
||||
function resetTestsResults(totalSamples) {
|
||||
if (totalSamples <= 0) totalSamples = 1;
|
||||
|
||||
// Reset tests results
|
||||
tests.forEach((test) => {
|
||||
test.sample = 0;
|
||||
test.totalRoundTrip = 0;
|
||||
test.totalSamples = totalSamples;
|
||||
});
|
||||
|
||||
testResults = buildEmptyTestResults(tests);
|
||||
testResults.forEach((result) => displayResult(result));
|
||||
|
||||
round_trip_avg_plot_data = [];
|
||||
box_plot_test_data.forEach((data) => {
|
||||
data.x = [];
|
||||
});
|
||||
}
|
||||
|
||||
function queueTest(name, byteSize, length, testFunc) {
|
||||
const testIndex = tests.length;
|
||||
test = {
|
||||
name: name,
|
||||
byteSize: byteSize,
|
||||
length: length,
|
||||
index: testIndex,
|
||||
sample: 0,
|
||||
totalRoundTrip: 0,
|
||||
func: testFunc,
|
||||
};
|
||||
tests.push(test);
|
||||
|
||||
box_plot_test_data.push({
|
||||
x: [],
|
||||
type: "box",
|
||||
boxpoints: "all",
|
||||
name: name,
|
||||
jitter: 0.3,
|
||||
pointpos: -1.8,
|
||||
});
|
||||
}
|
||||
|
||||
function execTestSuite(testIndex) {
|
||||
if (testIndex < tests.length) {
|
||||
execTest(testIndex);
|
||||
} else {
|
||||
testsRunFinished();
|
||||
}
|
||||
}
|
||||
|
||||
function startTests() {
|
||||
// Let the updated table render before starting the tests
|
||||
setTimeout(execTestSuite, 200, 0);
|
||||
}
|
||||
|
||||
function execQueuedTests(totalSamples) {
|
||||
resetTestsResults(totalSamples);
|
||||
startTests();
|
||||
}
|
||||
|
||||
function setSettingsState(disabled) {
|
||||
document.getElementById("sSamples").disabled = disabled;
|
||||
document.getElementById("sRun").disabled = disabled;
|
||||
}
|
||||
|
||||
function testsRunFinished() {
|
||||
testResults = buildTestResults(tests);
|
||||
testResults.forEach((result) => displayResult(result));
|
||||
|
||||
const round_trip_layout = {
|
||||
title: "Average round trip, μs (Smaller Better)",
|
||||
};
|
||||
Plotly.newPlot(
|
||||
"round_trip_avg_chart",
|
||||
round_trip_avg_plot_data,
|
||||
round_trip_layout
|
||||
);
|
||||
|
||||
const box_plot_layout = {
|
||||
title: "Round Trip Time, μs",
|
||||
};
|
||||
Plotly.newPlot("box_plot_chart", box_plot_test_data, box_plot_layout);
|
||||
setSettingsState(false);
|
||||
}
|
||||
|
||||
function humanFileSize(bytes) {
|
||||
const step = 1024;
|
||||
const originalBytes = bytes;
|
||||
|
||||
if (Math.abs(bytes) < step) {
|
||||
return bytes + " B";
|
||||
}
|
||||
|
||||
const units = [" KB", " MB", " GB"];
|
||||
let u = -1;
|
||||
let count = 0;
|
||||
|
||||
do {
|
||||
bytes /= step;
|
||||
u += 1;
|
||||
count += 1;
|
||||
} while (Math.abs(bytes) >= step && u < units.length - 1);
|
||||
|
||||
return bytes.toString() + units[u];
|
||||
}
|
||||
|
||||
window.runTestSuite = () => {
|
||||
Plotly.purge("round_trip_avg_chart");
|
||||
Plotly.purge("box_plot_chart");
|
||||
setSettingsState(true);
|
||||
const totalSamples = parseInt(
|
||||
document.getElementById("sSamples").value
|
||||
);
|
||||
execQueuedTests(totalSamples);
|
||||
};
|
||||
|
||||
const totalSamples = parseInt(document.getElementById("sSamples").value);
|
||||
queueTest("Empty String", 0, 0, sendString);
|
||||
queueTest("Empty Binary", 0, 0, sendArrayBuffer);
|
||||
for (let byteSize = 8; byteSize <= 512 * 1024; byteSize *= 2) {
|
||||
// Byte size of a string is twice its length because of UTF-16 encoding
|
||||
const stringLen = byteSize / 2;
|
||||
queueTest(
|
||||
humanFileSize(byteSize) + " String",
|
||||
byteSize,
|
||||
stringLen,
|
||||
sendString
|
||||
);
|
||||
queueTest(
|
||||
humanFileSize(byteSize) + " Binary",
|
||||
byteSize,
|
||||
byteSize,
|
||||
sendArrayBuffer
|
||||
);
|
||||
}
|
||||
resetTestsResults(totalSamples);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@@ -9,6 +9,7 @@
|
||||
<li><a href="http://webkit.org/blog-files/3d-transforms/poster-circle.html">Accelerated Layers</a></li>
|
||||
<li><a href="https://jigsaw.w3.org/HTTP/Basic/">Authentication (Basic)</a> - credentials returned via GetAuthCredentials</li>
|
||||
<li><a href="https://jigsaw.w3.org/HTTP/Digest/">Authentication (Digest)</a> - credentials returned via GetAuthCredentials</li>
|
||||
<li><a href="binary_transfer">Binary vs String Transfer Benchmark</a></li>
|
||||
<li><a href="http://html5advent2011.digitpaint.nl/3/index.html">Cursors</a></li>
|
||||
<li><a href="dialogs">Dialogs</a></li>
|
||||
<li><a href="http://html5demos.com/drag">Drag & Drop</a></li>
|
||||
|
@@ -29,6 +29,7 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
// Binary
|
||||
//
|
||||
|
||||
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"
|
||||
@@ -228,4 +229,3 @@ END
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
||||
|
@@ -2,6 +2,12 @@
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<title>Window Test</title>
|
||||
<style>
|
||||
/* Background becomes pink in fullscreen mode. */
|
||||
:fullscreen {
|
||||
background: pink;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
function setup() {
|
||||
if (location.hostname == 'tests' || location.hostname == 'localhost')
|
||||
@@ -38,10 +44,18 @@ function restore() {
|
||||
setTimeout(function() { send_message('Restore'); }, 1000);
|
||||
}
|
||||
|
||||
function fullscreen() {
|
||||
function fullscreenWindow() {
|
||||
send_message('Fullscreen');
|
||||
}
|
||||
|
||||
function fullscreenBrowser() {
|
||||
if (document.fullscreenElement) {
|
||||
document.exitFullscreen();
|
||||
} else {
|
||||
document.getElementById('form').requestFullscreen();
|
||||
}
|
||||
}
|
||||
|
||||
function position() {
|
||||
var x = parseInt(document.getElementById('x').value);
|
||||
var y = parseInt(document.getElementById('y').value);
|
||||
@@ -68,7 +82,8 @@ Click a button to perform the associated window action.
|
||||
<br/><input type="button" onclick="minimize();" value="Minimize">
|
||||
<br/><input type="button" onclick="maximize();" value="Maximize">
|
||||
<br/><input type="button" onclick="restore();" value="Restore"> (minimizes and then restores the window as topmost)
|
||||
<br/><input type="button" onclick="fullscreen();" value="Toggle Fullscreen"> (works with Views)
|
||||
<br/><input type="button" onclick="fullscreenWindow();" value="Toggle Window Fullscreen"> (works with Views)
|
||||
<br/><input type="button" onclick="fullscreenBrowser();" value="Toggle Browser Fullscreen"> (uses <a href="https://developer.mozilla.org/en-US/docs/Web/API/Fullscreen_API" target="_new">Fullscreen API</a>; background turns pink)
|
||||
<br/><input type="button" onclick="position();" value="Set Position">
|
||||
X: <input type="text" size="4" id="x" value="200">
|
||||
Y: <input type="text" size="4" id="y" value="100">
|
||||
|
136
tests/ceftests/message_router_binary_unittest.cc
Normal file
136
tests/ceftests/message_router_binary_unittest.cc
Normal file
@@ -0,0 +1,136 @@
|
||||
// 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/ceftests/message_router_unittest_utils.h"
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr size_t kMsgSizeThresholdInBytes = 16000;
|
||||
|
||||
class BinaryTestHandler final : public SingleLoadTestHandler {
|
||||
public:
|
||||
explicit BinaryTestHandler(size_t message_size)
|
||||
: message_size_(message_size) {}
|
||||
|
||||
std::string GetMainHTML() override {
|
||||
return "<html><body><script>\n"
|
||||
"function generateRandomArrayBuffer(size) {\n"
|
||||
" const buffer = new ArrayBuffer(size);\n"
|
||||
" const uint8Array = new Uint8Array(buffer);\n"
|
||||
" for (let i = 0; i < uint8Array.length; i++) {\n"
|
||||
" uint8Array[i] = Math.floor(Math.random() * 256);\n"
|
||||
" }\n"
|
||||
" return buffer;\n"
|
||||
"}\n"
|
||||
"function isEqualArrayBuffers(left, right) {\n"
|
||||
" if (left.byteLength !== right.byteLength) { return false; }\n"
|
||||
" const leftView = new DataView(left);\n"
|
||||
" const rightView = new DataView(right);\n"
|
||||
" for (let i = 0; i < left.byteLength; i++) {\n"
|
||||
" if (leftView.getUint8(i) !== rightView.getUint8(i)) {\n"
|
||||
" return false;\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" return true;\n"
|
||||
"}\n"
|
||||
"const request = generateRandomArrayBuffer(" +
|
||||
std::to_string(message_size_) +
|
||||
")\n"
|
||||
"window." +
|
||||
std::string(kJSQueryFunc) +
|
||||
"({\n request: request,\n"
|
||||
" persistent: false,\n"
|
||||
" onSuccess: (response) => {\n"
|
||||
" if (!isEqualArrayBuffers(request, response)) {\n"
|
||||
" window.mrtNotify('error-ArrayBuffersDiffer');\n"
|
||||
" } else {\n"
|
||||
" window.mrtNotify('success');\n"
|
||||
" }\n"
|
||||
" },\n"
|
||||
" onFailure: (errorCode, errorMessage) => {\n"
|
||||
" window.mrtNotify('error-onFailureCalled');\n"
|
||||
" }\n"
|
||||
"});\n</script></body></html>";
|
||||
}
|
||||
|
||||
void OnNotify(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
const std::string& message) override {
|
||||
AssertMainBrowser(browser);
|
||||
AssertMainFrame(frame);
|
||||
|
||||
// OnNotify only be called once.
|
||||
EXPECT_FALSE(got_notify_);
|
||||
got_notify_.yes();
|
||||
|
||||
EXPECT_EQ("success", message);
|
||||
|
||||
DestroyTest();
|
||||
}
|
||||
|
||||
bool OnQuery(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
int64_t query_id,
|
||||
CefRefPtr<const CefBinaryBuffer> request,
|
||||
bool persistent,
|
||||
CefRefPtr<Callback> callback) override {
|
||||
AssertMainBrowser(browser);
|
||||
AssertMainFrame(frame);
|
||||
EXPECT_NE(0, query_id);
|
||||
EXPECT_FALSE(persistent);
|
||||
EXPECT_EQ(message_size_, request->GetSize());
|
||||
|
||||
got_on_query_.yes();
|
||||
|
||||
callback->Success(request->GetData(), request->GetSize());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void DestroyTest() override {
|
||||
EXPECT_TRUE(got_notify_);
|
||||
EXPECT_TRUE(got_on_query_);
|
||||
|
||||
TestHandler::DestroyTest();
|
||||
}
|
||||
|
||||
private:
|
||||
const size_t message_size_;
|
||||
TrackCallback got_on_query_;
|
||||
TrackCallback got_notify_;
|
||||
};
|
||||
|
||||
using TestHandlerPtr = CefRefPtr<BinaryTestHandler>;
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST(MessageRouterTest, BinaryMessageEmpty) {
|
||||
const auto message_size = 0;
|
||||
TestHandlerPtr handler = new BinaryTestHandler(message_size);
|
||||
handler->SetMessageSizeThreshold(kMsgSizeThresholdInBytes);
|
||||
|
||||
handler->ExecuteTest();
|
||||
|
||||
ReleaseAndWaitForDestructor(handler);
|
||||
}
|
||||
|
||||
TEST(MessageRouterTest, BinaryMessageUnderThresholdSize) {
|
||||
const auto under_threshold = kMsgSizeThresholdInBytes - 1;
|
||||
TestHandlerPtr handler = new BinaryTestHandler(under_threshold);
|
||||
handler->SetMessageSizeThreshold(kMsgSizeThresholdInBytes);
|
||||
|
||||
handler->ExecuteTest();
|
||||
|
||||
ReleaseAndWaitForDestructor(handler);
|
||||
}
|
||||
|
||||
TEST(MessageRouterTest, BinaryMessageOverThresholdSize) {
|
||||
const auto over_threshold = kMsgSizeThresholdInBytes + 1;
|
||||
TestHandlerPtr handler = new BinaryTestHandler(over_threshold);
|
||||
handler->SetMessageSizeThreshold(kMsgSizeThresholdInBytes);
|
||||
|
||||
handler->ExecuteTest();
|
||||
|
||||
ReleaseAndWaitForDestructor(handler);
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user