Compare commits

...

17 Commits
6533 ... 6045

Author SHA1 Message Date
Marshall Greenblatt
55e15c8dee cmake: Fix docs for CMake and Xcode version 2023-12-06 13:20:07 -05:00
Marshall Greenblatt
9d567e22ba linux: Disable compiler TLS in libxml2 (fixes #3616) 2023-12-06 12:51:27 -05:00
Marshall Greenblatt
848712f89e tests: Remove accidental C++20 dependency (see #3611) 2023-12-06 12:50:19 -05:00
Marshall Greenblatt
5d1e039e05 Update to Chromium version 119.0.6045.199 2023-11-29 16:37:39 +00:00
Marshall Greenblatt
c76a3b9f2e Update to Chromium version 119.0.6045.159 2023-11-15 15:42:47 +00:00
Marshall Greenblatt
2d7731bda2 tools: Fix typo in make_distrib.py 2023-11-14 12:38:38 -05:00
Nik Pavlov
ae23bbc63c Remove virtual attribute from CefStringBase destructor (fixes #3587) 2023-11-14 12:38:38 -05:00
Marshall Greenblatt
81e35b9277 chrome: Support Chrome and DevTools command execution (fixes #3282, fixes #3600)
Add new CefBrowserHost::[Can]ExecuteChromeCommand methods for executing
arbitrary Chrome commands.

Add support for existing CefBrowserHost::ShowDevTools, CloseDevTools and
HasDevTools methods.

DevTools windows now support the same Views callbacks as normal popup
windows with the new CefLifeSpanHandler::OnBeforeDevToolsPopup callback
as the DevTools-specific equivalent of OnBeforePopup.

Always create DevTools as an undocked window to support use of
ShowDevTools with default Chrome browser windows.

To test:

Run `ceftests --enable-chrome-runtime [--use-views]
     --gtest_filter=V8Test.OnUncaughtExceptionDevTools`

OR:

1. Run `cefclient --enable-chrome-runtime [--use-native]`
2. Select "Show DevTools", "Close DevTools" or "Inspect" from the
   right-click menu.
3. Notice that the DevTools window is Views-hosted (or native-hosted)
   and works as expected.

Add --use-default-popup to get a default styled popup in step 3.
2023-11-14 12:38:38 -05:00
Marshall Greenblatt
f768881e64 Update to Chromium version 119.0.6045.124 2023-11-10 16:45:57 +00:00
Marshall Greenblatt
9499fd03b6 views: Support per-accelerator priority config (fixes #3598) 2023-11-08 14:31:25 -05:00
Marshall Greenblatt
f2646ea38e Add workaround for https://crbug.com/1500371 (see #3597) 2023-11-07 18:02:23 -05:00
Marshall Greenblatt
c49b21c407 mac: Update CSS on fullscreen window exit (fixes #3597) 2023-11-07 18:02:17 -05:00
Marshall Greenblatt
fe622e7aa0 chrome: Hit-test PiP draggable regions before resize border (see #3566) 2023-11-06 16:02:02 -05:00
Marshall Greenblatt
26778307c8 Update to Chromium version 119.0.6045.105 2023-11-01 21:50:59 +00:00
Marshall Greenblatt
ef03e9636e Update to Chromium version 119.0.6045.59 2023-10-27 17:21:24 +00:00
Nik Pavlov
612d63af73 Add binary format support to CefMessageRouter (fixes #3502) 2023-10-25 14:23:04 -04:00
Marshall Greenblatt
e8fb169bed Update to Chromium version 119.0.6045.33 2023-10-24 11:52:47 -04:00
109 changed files with 3724 additions and 871 deletions

View File

@@ -7,5 +7,6 @@
# https://bitbucket.org/chromiumembedded/cef/wiki/BranchesAndBuilding # 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'
} }

View File

@@ -12,7 +12,7 @@
# distribution include: # distribution include:
# #
# Linux: Ninja, GCC 7.5.0+, Unix Makefiles # 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 # Windows: Ninja, Visual Studio 2022
# #
# Ninja is a cross-platform open-source tool for running fast builds using # 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. # 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: # - Linux requirements:
# Currently supported distributions include Debian 10 (Buster), Ubuntu 18 # Currently supported distributions include Debian 10 (Buster), Ubuntu 18
@@ -48,7 +48,7 @@
# libgtk3.0-dev (required by the cefclient target only) # libgtk3.0-dev (required by the cefclient target only)
# #
# - MacOS requirements: # - 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 # 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 # installed. Newer Xcode versions may not have been been tested and are not
# recommended. # recommended.

View File

@@ -147,6 +147,8 @@
'libcef_dll/wrapper/cef_byte_read_handler.cc', 'libcef_dll/wrapper/cef_byte_read_handler.cc',
'libcef_dll/wrapper/cef_closure_task.cc', 'libcef_dll/wrapper/cef_closure_task.cc',
'libcef_dll/wrapper/cef_message_router.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_resource_manager.cc',
'libcef_dll/wrapper/cef_scoped_temp_dir.cc', 'libcef_dll/wrapper/cef_scoped_temp_dir.cc',
'libcef_dll/wrapper/cef_stream_resource_handler.cc', 'libcef_dll/wrapper/cef_stream_resource_handler.cc',
@@ -218,6 +220,8 @@
'tests/shared/browser/util_win.h', 'tests/shared/browser/util_win.h',
], ],
'cefclient_sources_browser': [ '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.cc',
'tests/cefclient/browser/binding_test.h', 'tests/cefclient/browser/binding_test.h',
'tests/cefclient/browser/browser_window.cc', 'tests/cefclient/browser/browser_window.cc',
@@ -309,6 +313,7 @@
'tests/cefclient/resources/dialogs.html', 'tests/cefclient/resources/dialogs.html',
'tests/cefclient/resources/draggable.html', 'tests/cefclient/resources/draggable.html',
'tests/cefclient/resources/ipc_performance.html', 'tests/cefclient/resources/ipc_performance.html',
'tests/cefclient/resources/binary_transfer.html',
'tests/cefclient/resources/localstorage.html', 'tests/cefclient/resources/localstorage.html',
'tests/cefclient/resources/logo.png', 'tests/cefclient/resources/logo.png',
'tests/cefclient/resources/media_router.html', 'tests/cefclient/resources/media_router.html',
@@ -496,6 +501,7 @@
'tests/ceftests/jsdialog_unittest.cc', 'tests/ceftests/jsdialog_unittest.cc',
'tests/ceftests/life_span_unittest.cc', 'tests/ceftests/life_span_unittest.cc',
'tests/ceftests/media_access_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_harness_unittest.cc',
'tests/ceftests/message_router_multi_query_unittest.cc', 'tests/ceftests/message_router_multi_query_unittest.cc',
'tests/ceftests/message_router_single_query_unittest.cc', 'tests/ceftests/message_router_single_query_unittest.cc',
@@ -603,6 +609,7 @@
'tests/ceftests/dom_unittest.cc', 'tests/ceftests/dom_unittest.cc',
'tests/ceftests/frame_unittest.cc', 'tests/ceftests/frame_unittest.cc',
'tests/ceftests/media_access_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_harness_unittest.cc',
'tests/ceftests/message_router_multi_query_unittest.cc', 'tests/ceftests/message_router_multi_query_unittest.cc',
'tests/ceftests/message_router_single_query_unittest.cc', 'tests/ceftests/message_router_single_query_unittest.cc',

View File

@@ -33,7 +33,7 @@
// by hand. See the translator.README.txt file in the tools directory for // by hand. See the translator.README.txt file in the tools directory for
// more information. // more information.
// //
// $hash=db4fce1215cb4f69346ef2d048974ba34187b2b1$ // $hash=eed525e9abcbf8e8b959067e0056ca470c5210c7$
// //
#ifndef CEF_INCLUDE_CAPI_CEF_BROWSER_CAPI_H_ #ifndef CEF_INCLUDE_CAPI_CEF_BROWSER_CAPI_H_
@@ -932,6 +932,48 @@ typedef struct _cef_browser_host_t {
/// be called on the UI thread. /// be called on the UI thread.
/// ///
int(CEF_CALLBACK* is_audio_muted)(struct _cef_browser_host_t* self); 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; } cef_browser_host_t;
/// ///

View File

@@ -33,7 +33,7 @@
// by hand. See the translator.README.txt file in the tools directory for // by hand. See the translator.README.txt file in the tools directory for
// more information. // more information.
// //
// $hash=1c807597b96889f44a1e5199e860e8db4948b473$ // $hash=32a0c21a71aa7137fa9660b942f597705bc8b05e$
// //
#ifndef CEF_INCLUDE_CAPI_CEF_LIFE_SPAN_HANDLER_CAPI_H_ #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, struct _cef_dictionary_value_t** extra_info,
int* no_javascript_access); 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 /// 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 /// actions with |browser|. cef_frame_handler_t callbacks related to initial

View File

@@ -33,7 +33,7 @@
// by hand. See the translator.README.txt file in the tools directory for // by hand. See the translator.README.txt file in the tools directory for
// more information. // more information.
// //
// $hash=42de7c0e6f5ec529d9182fe4cbf2c1edfacd7392$ // $hash=865ca5bff4a0867d0c25cb41bd2aa808cf3fddbd$
// //
#ifndef CEF_INCLUDE_CAPI_CEF_V8_CAPI_H_ #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); 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. /// Returns the function name.
/// ///

View File

@@ -33,7 +33,7 @@
// by hand. See the translator.README.txt file in the tools directory for // by hand. See the translator.README.txt file in the tools directory for
// more information. // more information.
// //
// $hash=1b8f7f620685c30b91c8fa656e1a01d182684ae6$ // $hash=7b8fee9d4a0530782ed62f5741820708f110e24e$
// //
#ifndef CEF_INCLUDE_CAPI_CEF_VALUES_CAPI_H_ #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*(CEF_CALLBACK* copy)(
struct _cef_binary_value_t* self); 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. /// Returns the data size.
/// ///

View File

@@ -33,7 +33,7 @@
// by hand. See the translator.README.txt file in the tools directory for // by hand. See the translator.README.txt file in the tools directory for
// more information. // more information.
// //
// $hash=f72e94f6bd63b6ea623c4d3170b5ad4333c136d6$ // $hash=bc80e7f1e467a4e0943dcbf7ea6d08366817d5ca$
// //
#ifndef CEF_INCLUDE_CAPI_VIEWS_CEF_BROWSER_VIEW_CAPI_H_ #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); struct _cef_browser_view_t* self);
/// ///
/// Sets whether accelerators registered with cef_window_t::SetAccelerator are /// Sets whether normal priority accelerators are first forwarded to the web
/// triggered before or after the event is sent to the cef_browser_t. If /// content (`keydown` event handler) or cef_keyboard_handler_t. Normal
/// |prefer_accelerators| is true (1) then the matching accelerator will be /// priority accelerators can be registered via cef_window_t::SetAccelerator
/// triggered immediately and the event will not be sent to the cef_browser_t. /// (with |high_priority|=false (0)) or internally for standard accelerators
/// If |prefer_accelerators| is false (0) then the matching accelerator will /// supported by the Chrome runtime. If |prefer_accelerators| is true (1) then
/// only be triggered if the event is not handled by web content or by /// the matching accelerator will be triggered immediately (calling
/// cef_keyboard_handler_t. The default value is false (0). /// 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, void(CEF_CALLBACK* set_prefer_accelerators)(struct _cef_browser_view_t* self,
int prefer_accelerators); int prefer_accelerators);

View File

@@ -33,7 +33,7 @@
// by hand. See the translator.README.txt file in the tools directory for // by hand. See the translator.README.txt file in the tools directory for
// more information. // more information.
// //
// $hash=4b43fe0b493d860e8b28d7a6d892db49d1135b34$ // $hash=a48904fcd0f6be07e27839922d8feb07271ed2b5$
// //
#ifndef CEF_INCLUDE_CAPI_VIEWS_CEF_WINDOW_CAPI_H_ #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| /// 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 /// cef_window_delegate_t::OnAccelerator will be called if the keyboard
/// combination is triggered while this window has focus. /// 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, void(CEF_CALLBACK* set_accelerator)(struct _cef_window_t* self,
int command_id, int command_id,
int key_code, int key_code,
int shift_pressed, int shift_pressed,
int ctrl_pressed, int ctrl_pressed,
int alt_pressed); int alt_pressed,
int high_priority);
/// ///
/// Remove the keyboard accelerator for the specified |command_id|. /// Remove the keyboard accelerator for the specified |command_id|.

View File

@@ -42,13 +42,13 @@
// way that may cause binary incompatibility with other builds. The universal // way that may cause binary incompatibility with other builds. The universal
// hash value will change if any platform is affected whereas the platform hash // hash value will change if any platform is affected whereas the platform hash
// values will change only if that particular platform is affected. // 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) #if defined(OS_WIN)
#define CEF_API_HASH_PLATFORM "4a22d727f3f1f625844191f0f5adf297a2f17fa7" #define CEF_API_HASH_PLATFORM "e094f42b7a60d2c8c9bcb3db51907a3b42f51d04"
#elif defined(OS_MAC) #elif defined(OS_MAC)
#define CEF_API_HASH_PLATFORM "84a450a85c81d6cb16dda55d7f07047264d1e205" #define CEF_API_HASH_PLATFORM "6ce44bd7182aa7e9544f5ca33c310f2a096ab638"
#elif defined(OS_LINUX) #elif defined(OS_LINUX)
#define CEF_API_HASH_PLATFORM "b7cbd7d044e02cb1854184cc1d5d621605b8476b" #define CEF_API_HASH_PLATFORM "8e9886cd490aefc89283d65f5f7d104a51e2d289"
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus

View File

@@ -964,6 +964,48 @@ class CefBrowserHost : public virtual CefBaseRefCounted {
/// ///
/*--cef()--*/ /*--cef()--*/
virtual bool IsAudioMuted() = 0; 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_ #endif // CEF_INCLUDE_CEF_BROWSER_H_

View File

@@ -94,6 +94,33 @@ class CefLifeSpanHandler : public virtual CefBaseRefCounted {
return false; 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 /// Called after a new browser is created. It is now safe to begin performing
/// actions with |browser|. CefFrameHandler callbacks related to initial main /// actions with |browser|. CefFrameHandler callbacks related to initial main

View File

@@ -520,7 +520,7 @@ class CefV8Value : public virtual CefBaseRefCounted {
/// or CefV8Accessor callback, or in combination with calling Enter() and /// or CefV8Accessor callback, or in combination with calling Enter() and
/// Exit() on a stored CefV8Context reference. /// Exit() on a stored CefV8Context reference.
/// ///
/*--cef()--*/ /*--cef(optional_param=buffer)--*/
static CefRefPtr<CefV8Value> CreateArrayBuffer( static CefRefPtr<CefV8Value> CreateArrayBuffer(
void* buffer, void* buffer,
size_t length, size_t length,
@@ -866,6 +866,20 @@ class CefV8Value : public virtual CefBaseRefCounted {
/*--cef()--*/ /*--cef()--*/
virtual bool NeuterArrayBuffer() = 0; 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. // FUNCTION METHODS - These methods are only available on functions.
/// ///

View File

@@ -278,6 +278,13 @@ class CefBinaryValue : public virtual CefBaseRefCounted {
/*--cef()--*/ /*--cef()--*/
virtual CefRefPtr<CefBinaryValue> Copy() = 0; 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. /// Returns the data size.
/// ///

View File

@@ -353,7 +353,7 @@ struct CefStringTraitsUTF16 {
/// modifying CEF strings from multiple threads. /// modifying CEF strings from multiple threads.
/// ///
template <class traits> template <class traits>
class CefStringBase { class CefStringBase final {
public: public:
typedef typename traits::char_type char_type; typedef typename traits::char_type char_type;
typedef typename traits::struct_type struct_type; typedef typename traits::struct_type struct_type;
@@ -442,7 +442,7 @@ class CefStringBase {
Attach(const_cast<struct_type*>(src), false); Attach(const_cast<struct_type*>(src), false);
} }
virtual ~CefStringBase() { ClearAndFree(); } ~CefStringBase() { ClearAndFree(); }
/// The following methods are named for compatibility with the standard /// The following methods are named for compatibility with the standard
/// library string template types. /// library string template types.

View File

@@ -1004,52 +1004,52 @@ typedef enum {
/// renumbered. /// renumbered.
/// ///
typedef enum { typedef enum {
WOD_UNKNOWN, CEF_WOD_UNKNOWN,
/// ///
/// Current tab. This is the default in most cases. /// 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. /// 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. /// 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. /// Middle mouse button or meta/ctrl key while clicking.
/// ///
WOD_NEW_BACKGROUND_TAB, CEF_WOD_NEW_BACKGROUND_TAB,
/// ///
/// New popup window. /// New popup window.
/// ///
WOD_NEW_POPUP, CEF_WOD_NEW_POPUP,
/// ///
/// Shift key while clicking. /// Shift key while clicking.
/// ///
WOD_NEW_WINDOW, CEF_WOD_NEW_WINDOW,
/// ///
/// Alt key while clicking. /// Alt key while clicking.
/// ///
WOD_SAVE_TO_DISK, CEF_WOD_SAVE_TO_DISK,
/// ///
/// New off-the-record (incognito) window. /// New off-the-record (incognito) window.
/// ///
WOD_OFF_THE_RECORD, CEF_WOD_OFF_THE_RECORD,
/// ///
/// Special case error condition from the renderer. /// Special case error condition from the renderer.
/// ///
WOD_IGNORE_ACTION, CEF_WOD_IGNORE_ACTION,
/// ///
/// Activates an existing tab containing the url, rather than navigating. /// 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 /// no session history; and behaves like CURRENT_TAB instead of
/// NEW_FOREGROUND_TAB when no existing tab is found. /// 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. /// 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; } cef_window_open_disposition_t;
/// ///

View File

@@ -92,13 +92,18 @@ class CefBrowserView : public CefView {
virtual CefRefPtr<CefView> GetChromeToolbar() = 0; virtual CefRefPtr<CefView> GetChromeToolbar() = 0;
/// ///
/// Sets whether accelerators registered with CefWindow::SetAccelerator are /// Sets whether normal priority accelerators are first forwarded to the web
/// triggered before or after the event is sent to the CefBrowser. If /// content (`keydown` event handler) or CefKeyboardHandler. Normal priority
/// |prefer_accelerators| is true then the matching accelerator will be /// accelerators can be registered via CefWindow::SetAccelerator (with
/// triggered immediately and the event will not be sent to the CefBrowser. If /// |high_priority|=false) or internally for standard accelerators supported
/// |prefer_accelerators| is false then the matching accelerator will only be /// by the Chrome runtime. If |prefer_accelerators| is true then the matching
/// triggered if the event is not handled by web content or by /// accelerator will be triggered immediately (calling
/// CefKeyboardHandler. The default value is false. /// 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()--*/ /*--cef()--*/
virtual void SetPreferAccelerators(bool prefer_accelerators) = 0; virtual void SetPreferAccelerators(bool prefer_accelerators) = 0;

View File

@@ -344,16 +344,25 @@ class CefWindow : public CefPanel {
/// ///
/// Set the keyboard accelerator for the specified |command_id|. |key_code| /// 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 /// CefWindowDelegate::OnAccelerator will be called if the keyboard
/// combination is triggered while this window has focus. /// 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()--*/ /*--cef()--*/
virtual void SetAccelerator(int command_id, virtual void SetAccelerator(int command_id,
int key_code, int key_code,
bool shift_pressed, bool shift_pressed,
bool ctrl_pressed, bool ctrl_pressed,
bool alt_pressed) = 0; bool alt_pressed,
bool high_priority) = 0;
/// ///
/// Remove the keyboard accelerator for the specified |command_id|. /// Remove the keyboard accelerator for the specified |command_id|.

View File

@@ -219,6 +219,38 @@ struct CefMessageRouterConfig {
size_t message_size_threshold; 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 /// Implements the browser side of query routing. The methods of this class may
/// be called on any browser process thread unless otherwise indicated. /// be called on any browser process thread unless otherwise indicated.
@@ -238,10 +270,17 @@ class CefMessageRouterBrowserSide
public: public:
/// ///
/// Notify the associated JavaScript onSuccess callback that the query has /// 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; 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 /// Notify the associated JavaScript onFailure callback that the query has
/// failed with the specified |error_code| and |error_message|. /// failed with the specified |error_code| and |error_message|.
@@ -276,6 +315,25 @@ class CefMessageRouterBrowserSide
return false; 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 /// Executed when a query has been canceled either explicitly using the
/// JavaScript cancel function or implicitly due to browser destruction, /// JavaScript cancel function or implicitly due to browser destruction,

View File

@@ -57,33 +57,6 @@ using content::KeyboardEventProcessingResult;
namespace { 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); static constexpr base::TimeDelta kRecentlyAudibleTimeout = base::Seconds(2);
} // namespace } // namespace
@@ -358,22 +331,15 @@ void AlloyBrowserHostImpl::StopFinding(bool clearSelection) {
} }
} }
void AlloyBrowserHostImpl::ShowDevTools(const CefWindowInfo& windowInfo, void AlloyBrowserHostImpl::ShowDevToolsOnUIThread(
CefRefPtr<CefClient> client, std::unique_ptr<CefShowDevToolsParams> params) {
const CefBrowserSettings& settings, CEF_REQUIRE_UIT();
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;
}
if (!EnsureDevToolsManager()) { if (!EnsureDevToolsManager()) {
return; return;
} }
devtools_manager_->ShowDevTools(windowInfo, client, settings, devtools_manager_->ShowDevTools(params->window_info_, params->client_,
inspect_element_at); params->settings_,
params->inspect_element_at_);
} }
void AlloyBrowserHostImpl::CloseDevTools() { void AlloyBrowserHostImpl::CloseDevTools() {
@@ -438,6 +404,16 @@ bool AlloyBrowserHostImpl::IsBackgroundHost() {
return is_background_host_; 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() { bool AlloyBrowserHostImpl::IsWindowRenderingDisabled() {
return IsWindowless(); return IsWindowless();
} }

View File

@@ -85,10 +85,6 @@ class AlloyBrowserHostImpl : public CefBrowserHostBase,
bool matchCase, bool matchCase,
bool findNext) override; bool findNext) override;
void StopFinding(bool clearSelection) 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; void CloseDevTools() override;
bool HasDevTools() override; bool HasDevTools() override;
bool IsWindowRenderingDisabled() override; bool IsWindowRenderingDisabled() override;
@@ -127,6 +123,9 @@ class AlloyBrowserHostImpl : public CefBrowserHostBase,
const CefSize& max_size) override; const CefSize& max_size) override;
CefRefPtr<CefExtension> GetExtension() override; CefRefPtr<CefExtension> GetExtension() override;
bool IsBackgroundHost() 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. // Returns true if windowless rendering is enabled.
bool IsWindowless() const override; bool IsWindowless() const override;
@@ -285,6 +284,10 @@ class AlloyBrowserHostImpl : public CefBrowserHostBase,
override; override;
void WebContentsDestroyed() override; void WebContentsDestroyed() override;
protected:
void ShowDevToolsOnUIThread(
std::unique_ptr<CefShowDevToolsParams> params) override;
private: private:
friend class CefBrowserPlatformDelegateAlloy; friend class CefBrowserPlatformDelegateAlloy;

View File

@@ -39,20 +39,15 @@ content::WebContents* CefBrowserPlatformDelegateAlloy::CreateWebContents(
REQUIRE_ALLOY_RUNTIME(); REQUIRE_ALLOY_RUNTIME();
DCHECK(primary_); 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) { if (!create_params.request_context) {
// Using the global 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; scoped_refptr<content::SiteInstance> site_instance;
if (extensions::ExtensionsEnabled() && !create_params.url.empty()) { if (extensions::ExtensionsEnabled() && !create_params.url.empty()) {
GURL gurl = url_util::MakeGURL(create_params.url, /*fixup=*/true); GURL gurl = url_util::MakeGURL(create_params.url, /*fixup=*/true);

View File

@@ -505,6 +505,22 @@ void CefBrowserHostBase::PrintToPDF(const CefString& path,
print_util::PrintToPDF(web_contents, path, settings, callback); 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, bool CefBrowserHostBase::SendDevToolsMessage(const void* message,
size_t message_size) { size_t message_size) {
if (!message || message_size == 0) { if (!message || message_size == 0) {
@@ -633,6 +649,31 @@ void CefBrowserHostBase::NotifyMoveOrResizeStarted() {
#endif #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) { void CefBrowserHostBase::ReplaceMisspelling(const CefString& word) {
if (!CEF_CURRENTLY_ON_UIT()) { if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK( CEF_POST_TASK(

View File

@@ -94,6 +94,23 @@ struct CefBrowserCreateParams {
extensions::mojom::ViewType::kInvalid; 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 // Base class for CefBrowserHost implementations. Includes functionality that is
// shared by the alloy and chrome runtimes. All methods are thread-safe unless // shared by the alloy and chrome runtimes. All methods are thread-safe unless
// otherwise indicated. // otherwise indicated.
@@ -191,6 +208,10 @@ class CefBrowserHostBase : public CefBrowserHost,
void PrintToPDF(const CefString& path, void PrintToPDF(const CefString& path,
const CefPdfPrintSettings& settings, const CefPdfPrintSettings& settings,
CefRefPtr<CefPdfPrintCallback> callback) override; 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 ReplaceMisspelling(const CefString& word) override;
void AddWordToDictionary(const CefString& word) override; void AddWordToDictionary(const CefString& word) override;
void SendKeyEvent(const CefKeyEvent& event) override; void SendKeyEvent(const CefKeyEvent& event) override;
@@ -212,6 +233,8 @@ class CefBrowserHostBase : public CefBrowserHost,
bool current_only) override; bool current_only) override;
CefRefPtr<CefNavigationEntry> GetVisibleNavigationEntry() override; CefRefPtr<CefNavigationEntry> GetVisibleNavigationEntry() override;
void NotifyMoveOrResizeStarted() override; void NotifyMoveOrResizeStarted() override;
bool IsFullscreen() override;
void ExitFullscreen(bool will_cause_resize) override;
// CefBrowser methods: // CefBrowser methods:
bool IsValid() override; bool IsValid() override;
@@ -344,6 +367,10 @@ class CefBrowserHostBase : public CefBrowserHost,
// Called from LoadMainFrameURL to perform the actual navigation. // Called from LoadMainFrameURL to perform the actual navigation.
virtual bool Navigate(const content::OpenURLParams& params); 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. // Create the CefFileDialogManager if it doesn't already exist.
bool EnsureFileDialogManager(); bool EnsureFileDialogManager();

View File

@@ -33,6 +33,16 @@ CefBrowserInfo::CefBrowserInfo(int browser_id,
is_windowless_(is_windowless), is_windowless_(is_windowless),
extra_info_(extra_info) { extra_info_(extra_info) {
DCHECK_GT(browser_id, 0); 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() { CefBrowserInfo::~CefBrowserInfo() {

View File

@@ -193,15 +193,8 @@ bool CefBrowserInfoManager::CanCreateWindow(
pending_popup->use_default_browser_creation = true; pending_popup->use_default_browser_creation = true;
} }
// In most cases, Views-hosted browsers should create Views-hosted popups create_params.popup_with_views_hosted_opener = ShouldCreateViewsHostedPopup(
// and native browsers should use default popup handling. With the Chrome browser, pending_popup->use_default_browser_creation);
// 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.settings = pending_popup->settings; create_params.settings = pending_popup->settings;
create_params.client = pending_popup->client; create_params.client = pending_popup->client;
create_params.extra_info = pending_popup->extra_info; create_params.extra_info = pending_popup->extra_info;
@@ -420,6 +413,19 @@ bool CefBrowserInfoManager::MaybeAllowNavigation(
return true; 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::BrowserInfoList
CefBrowserInfoManager::GetBrowserInfoList() { CefBrowserInfoManager::GetBrowserInfoList() {
base::AutoLock lock_scope(browser_info_lock_); base::AutoLock lock_scope(browser_info_lock_);

View File

@@ -143,6 +143,9 @@ class CefBrowserInfoManager : public content::RenderProcessHostObserver {
const content::OpenURLParams& params, const content::OpenURLParams& params,
CefRefPtr<CefBrowserHostBase>& browser) const; CefRefPtr<CefBrowserHostBase>& browser) const;
static bool ShouldCreateViewsHostedPopup(CefRefPtr<CefBrowserHostBase> opener,
bool use_default_browser_creation);
private: private:
// RenderProcessHostObserver methods: // RenderProcessHostObserver methods:
void RenderProcessHostDestroyed(content::RenderProcessHost* host) override; void RenderProcessHostDestroyed(content::RenderProcessHost* host) override;

View File

@@ -16,6 +16,7 @@
#include "ui/base/window_open_disposition.h" #include "ui/base/window_open_disposition.h"
class Browser; class Browser;
class Profile;
namespace cef { namespace cef {
@@ -40,6 +41,14 @@ class BrowserDelegate : public content::WebContentsDelegate {
~BrowserDelegate() override {} ~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 // Optionally override chrome::AddWebContents behavior. This is most often
// called via Browser::AddNewContents for new popup browsers and provides an // called via Browser::AddNewContents for new popup browsers and provides an
// opportunity for CEF to create a new Browser instead of proceeding with // opportunity for CEF to create a new Browser instead of proceeding with

View File

@@ -12,6 +12,7 @@
#include "libcef/browser/browser_platform_delegate.h" #include "libcef/browser/browser_platform_delegate.h"
#include "libcef/browser/chrome/chrome_browser_host_impl.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_browser_view.h"
#include "libcef/browser/chrome/views/chrome_child_window.h"
#include "libcef/browser/media_access_query.h" #include "libcef/browser/media_access_query.h"
#include "libcef/browser/request_context_impl.h" #include "libcef/browser/request_context_impl.h"
#include "libcef/browser/views/browser_view_impl.h" #include "libcef/browser/views/browser_view_impl.h"
@@ -24,6 +25,8 @@
#include "chrome/browser/ui/browser_tabstrip.h" #include "chrome/browser/ui/browser_tabstrip.h"
#include "content/public/browser/global_routing_id.h" #include "content/public/browser/global_routing_id.h"
#include "content/public/browser/keyboard_event_processing_result.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" #include "content/public/common/input/native_web_keyboard_event.h"
using content::KeyboardEventProcessingResult; using content::KeyboardEventProcessingResult;
@@ -36,7 +39,8 @@ ChromeBrowserDelegate::ChromeBrowserDelegate(
DCHECK(browser_); DCHECK(browser_);
if (opener) { 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); auto opener_host = ChromeBrowserHostImpl::GetBrowserForBrowser(opener);
DCHECK(opener_host); DCHECK(opener_host);
if (opener_host) { if (opener_host) {
@@ -47,6 +51,134 @@ ChromeBrowserDelegate::ChromeBrowserDelegate(
ChromeBrowserDelegate::~ChromeBrowserDelegate() = default; 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> ChromeBrowserDelegate::AddWebContents(
std::unique_ptr<content::WebContents> new_contents) { std::unique_ptr<content::WebContents> new_contents) {
if (CefBrowserInfoManager::GetInstance()->AddWebContents( if (CefBrowserInfoManager::GetInstance()->AddWebContents(
@@ -56,7 +188,9 @@ std::unique_ptr<content::WebContents> ChromeBrowserDelegate::AddWebContents(
ChromeBrowserHostImpl::GetBrowserForContents(new_contents.get()); ChromeBrowserHostImpl::GetBrowserForContents(new_contents.get());
if (new_browser) { if (new_browser) {
// Create a new Browser and give it ownership of the new WebContents. // 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 { } else {
LOG(ERROR) << "No host found for chrome popup browser"; LOG(ERROR) << "No host found for chrome popup browser";
} }
@@ -90,19 +224,26 @@ void ChromeBrowserDelegate::SetAsDelegate(content::WebContents* web_contents,
return; 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_); auto platform_delegate = CefBrowserPlatformDelegate::Create(create_params_);
CHECK(platform_delegate); CHECK(platform_delegate);
auto browser_info = CefBrowserInfoManager::GetInstance()->CreateBrowserInfo( 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 = auto request_context_impl =
CefRequestContextImpl::GetOrCreateForRequestContext( CefRequestContextImpl::GetOrCreateForRequestContext(
create_params_.request_context); create_params_.request_context);
CreateBrowser(web_contents, create_params_.settings, create_params_.client, CreateBrowserHost(web_contents, create_params_.settings,
std::move(platform_delegate), browser_info, /*opener=*/nullptr, create_params_.client, std::move(platform_delegate),
request_context_impl); browser_info, is_devtools_popup, /*opener=*/nullptr,
request_context_impl);
} }
bool ChromeBrowserDelegate::ShowStatusBubble(bool show_by_default) { bool ChromeBrowserDelegate::ShowStatusBubble(bool show_by_default) {
@@ -123,6 +264,11 @@ bool ChromeBrowserDelegate::ShowStatusBubble(bool show_by_default) {
bool ChromeBrowserDelegate::HandleCommand(int command_id, bool ChromeBrowserDelegate::HandleCommand(int command_id,
WindowOpenDisposition disposition) { 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 browser = ChromeBrowserHostImpl::GetBrowserForBrowser(browser_)) {
if (auto client = browser->GetClient()) { if (auto client = browser->GetClient()) {
if (auto handler = client->GetCommandHandler()) { if (auto handler = client->GetCommandHandler()) {
@@ -299,19 +445,13 @@ void ChromeBrowserDelegate::WebContentsCreated(
return; return;
} }
auto browser_info = // Create a new browser host that remains alive until the associated
CefBrowserInfoManager::GetInstance()->CreatePopupBrowserInfo( // WebContents is destroyed. Associate that browser host with the WebContents
new_contents, /*is_windowless=*/false, extra_info); // and execute initial client callbacks. Deliver required information to the
CHECK(browser_info->is_popup()); // renderer process.
CreateBrowserHostForPopup(new_contents, settings, client, extra_info,
// Popups must share the same RequestContext as the parent. std::move(platform_delegate),
auto request_context_impl = opener->request_context(); /*is_devtools_popup=*/false, opener);
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);
} }
content::WebContents* ChromeBrowserDelegate::OpenURLFromTab( content::WebContents* ChromeBrowserDelegate::OpenURLFromTab(
@@ -379,6 +519,14 @@ void ChromeBrowserDelegate::ExitFullscreenModeForTab(
if (auto delegate = GetDelegateForWebContents(web_contents)) { if (auto delegate = GetDelegateForWebContents(web_contents)) {
delegate->ExitFullscreenModeForTab(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( void ChromeBrowserDelegate::CanDownload(
@@ -413,12 +561,19 @@ bool ChromeBrowserDelegate::HandleKeyboardEvent(
return false; 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, content::WebContents* web_contents,
CefBrowserSettings settings, const CefBrowserSettings& settings,
CefRefPtr<CefClient> client, CefRefPtr<CefClient> client,
std::unique_ptr<CefBrowserPlatformDelegate> platform_delegate, std::unique_ptr<CefBrowserPlatformDelegate> platform_delegate,
scoped_refptr<CefBrowserInfo> browser_info, scoped_refptr<CefBrowserInfo> browser_info,
bool is_devtools_popup,
CefRefPtr<ChromeBrowserHostImpl> opener, CefRefPtr<ChromeBrowserHostImpl> opener,
CefRefPtr<CefRequestContextImpl> request_context_impl) { CefRefPtr<CefRequestContextImpl> request_context_impl) {
CEF_REQUIRE_UIT(); CEF_REQUIRE_UIT();
@@ -454,12 +609,40 @@ void ChromeBrowserDelegate::CreateBrowser(
CefRefPtr<ChromeBrowserHostImpl> browser_host = CefRefPtr<ChromeBrowserHostImpl> browser_host =
new ChromeBrowserHostImpl(settings, client, std::move(platform_delegate), new ChromeBrowserHostImpl(settings, client, std::move(platform_delegate),
browser_info, request_context_impl); 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) { if (!opener) {
browser_host->SetBrowser(browser_); 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( CefBrowserContentsDelegate* ChromeBrowserDelegate::GetDelegateForWebContents(

View File

@@ -39,6 +39,9 @@ class ChromeBrowserHostImpl;
// but the Browser object will change when the tab is dragged between windows. // but the Browser object will change when the tab is dragged between windows.
class ChromeBrowserDelegate : public cef::BrowserDelegate { class ChromeBrowserDelegate : public cef::BrowserDelegate {
public: 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, ChromeBrowserDelegate(Browser* browser,
const CefBrowserCreateParams& create_params, const CefBrowserCreateParams& create_params,
const Browser* opener); const Browser* opener);
@@ -49,6 +52,10 @@ class ChromeBrowserDelegate : public cef::BrowserDelegate {
~ChromeBrowserDelegate() override; ~ChromeBrowserDelegate() override;
// cef::BrowserDelegate methods: // 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> AddWebContents(
std::unique_ptr<content::WebContents> new_contents) override; std::unique_ptr<content::WebContents> new_contents) override;
void OnWebContentsCreated(content::WebContents* new_contents) override; void OnWebContentsCreated(content::WebContents* new_contents) override;
@@ -104,18 +111,31 @@ class ChromeBrowserDelegate : public cef::BrowserDelegate {
content::WebContents* source, content::WebContents* source,
const content::NativeWebKeyboardEvent& event) override; const content::NativeWebKeyboardEvent& event) override;
void SetPendingShowDevToolsParams(
std::unique_ptr<CefShowDevToolsParams> params);
Browser* browser() const { return browser_; } Browser* browser() const { return browser_; }
private: private:
void CreateBrowser( CefRefPtr<ChromeBrowserHostImpl> CreateBrowserHost(
content::WebContents* web_contents, content::WebContents* web_contents,
CefBrowserSettings settings, const CefBrowserSettings& settings,
CefRefPtr<CefClient> client, CefRefPtr<CefClient> client,
std::unique_ptr<CefBrowserPlatformDelegate> platform_delegate, std::unique_ptr<CefBrowserPlatformDelegate> platform_delegate,
scoped_refptr<CefBrowserInfo> browser_info, scoped_refptr<CefBrowserInfo> browser_info,
bool is_devtools_popup,
CefRefPtr<ChromeBrowserHostImpl> opener, CefRefPtr<ChromeBrowserHostImpl> opener,
CefRefPtr<CefRequestContextImpl> request_context_impl); 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( CefBrowserContentsDelegate* GetDelegateForWebContents(
content::WebContents* web_contents); content::WebContents* web_contents);
@@ -130,6 +150,8 @@ class ChromeBrowserDelegate : public cef::BrowserDelegate {
absl::optional<bool> show_status_bubble_; absl::optional<bool> show_status_bubble_;
absl::optional<SkRegion> draggable_region_; absl::optional<SkRegion> draggable_region_;
mutable absl::optional<bool> frameless_pip_; mutable absl::optional<bool> frameless_pip_;
std::unique_ptr<CefShowDevToolsParams> pending_show_devtools_params_;
}; };
#endif // CEF_LIBCEF_BROWSER_CHROME_CHROME_BROWSER_DELEGATE_H_ #endif // CEF_LIBCEF_BROWSER_CHROME_CHROME_BROWSER_DELEGATE_H_

View File

@@ -6,6 +6,7 @@
#include "libcef/browser/browser_platform_delegate.h" #include "libcef/browser/browser_platform_delegate.h"
#include "libcef/browser/chrome/browser_platform_delegate_chrome.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/thread_util.h"
#include "libcef/browser/views/browser_view_impl.h" #include "libcef/browser/views/browser_view_impl.h"
#include "libcef/common/net/url_util.h" #include "libcef/common/net/url_util.h"
@@ -13,8 +14,8 @@
#include "base/logging.h" #include "base/logging.h"
#include "base/notreached.h" #include "base/notreached.h"
#include "chrome/browser/devtools/devtools_window.h"
#include "chrome/browser/profiles/profile.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_commands.h"
#include "chrome/browser/ui/browser_navigator.h" #include "chrome/browser/ui/browser_navigator.h"
#include "chrome/browser/ui/browser_tabstrip.h" #include "chrome/browser/ui/browser_tabstrip.h"
@@ -28,7 +29,7 @@
// static // static
CefRefPtr<ChromeBrowserHostImpl> ChromeBrowserHostImpl::Create( CefRefPtr<ChromeBrowserHostImpl> ChromeBrowserHostImpl::Create(
const CefBrowserCreateParams& params) { const CefBrowserCreateParams& params) {
auto browser = CreateBrowser(params); auto browser = CreateBrowser(params, std::nullopt);
GURL url = url_util::MakeGURL(params.url, /*fixup=*/true); GURL url = url_util::MakeGURL(params.url, /*fixup=*/true);
if (url.is_empty()) { if (url.is_empty()) {
@@ -99,7 +100,8 @@ CefRefPtr<ChromeBrowserHostImpl> ChromeBrowserHostImpl::GetBrowserForBrowser(
ChromeBrowserHostImpl::~ChromeBrowserHostImpl() = default; ChromeBrowserHostImpl::~ChromeBrowserHostImpl() = default;
void ChromeBrowserHostImpl::AddNewContents( 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(contents);
DCHECK(!browser_); DCHECK(!browser_);
@@ -111,7 +113,7 @@ void ChromeBrowserHostImpl::AddNewContents(
params.browser_view = GetBrowserView(); params.browser_view = GetBrowserView();
// Create the new Browser representation. // Create the new Browser representation.
auto browser = CreateBrowser(params); auto browser = CreateBrowser(params, std::move(browser_create_params));
// Add the WebContents to the Browser. // Add the WebContents to the Browser.
browser->tab_strip_model()->AddWebContents( browser->tab_strip_model()->AddWebContents(
@@ -199,20 +201,66 @@ void ChromeBrowserHostImpl::StopFinding(bool clearSelection) {
NOTIMPLEMENTED(); NOTIMPLEMENTED();
} }
void ChromeBrowserHostImpl::ShowDevTools(const CefWindowInfo& windowInfo, void ChromeBrowserHostImpl::ShowDevToolsOnUIThread(
CefRefPtr<CefClient> client, std::unique_ptr<CefShowDevToolsParams> params) {
const CefBrowserSettings& settings, CEF_REQUIRE_UIT();
const CefPoint& inspect_element_at) {
NOTIMPLEMENTED(); 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() { 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() { bool ChromeBrowserHostImpl::HasDevTools() {
NOTIMPLEMENTED(); if (!CEF_CURRENTLY_ON_UIT()) {
return false; DCHECK(false) << "called on invalid thread";
return false;
}
return !!devtools_browser_host_;
} }
bool ChromeBrowserHostImpl::IsWindowRenderingDisabled() { bool ChromeBrowserHostImpl::IsWindowRenderingDisabled() {
@@ -332,6 +380,36 @@ bool ChromeBrowserHostImpl::IsBackgroundHost() {
return false; 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 { ChromeBrowserView* ChromeBrowserHostImpl::chrome_browser_view() const {
if (browser_ && is_views_hosted_) { if (browser_ && is_views_hosted_) {
return static_cast<ChromeBrowserView*>(browser_->window()); return static_cast<ChromeBrowserView*>(browser_->window());
@@ -389,19 +467,16 @@ ChromeBrowserHostImpl::ChromeBrowserHostImpl(
// static // static
Browser* ChromeBrowserHostImpl::CreateBrowser( Browser* ChromeBrowserHostImpl::CreateBrowser(
const CefBrowserCreateParams& params) { const CefBrowserCreateParams& params,
// Get or create the request context and profile. std::optional<Browser::CreateParams> browser_create_params) {
CefRefPtr<CefRequestContextImpl> request_context_impl = Browser::CreateParams chrome_params = [&params, &browser_create_params]() {
CefRequestContextImpl::GetOrCreateForRequestContext( if (!browser_create_params.has_value()) {
params.request_context); auto* profile = CefRequestContextImpl::GetProfile(params.request_context);
CHECK(request_context_impl); return Browser::CreateParams(profile, /*user_gesture=*/false);
auto cef_browser_context = request_context_impl->GetBrowserContext(); } else {
CHECK(cef_browser_context); return std::move(*browser_create_params);
auto profile = cef_browser_context->AsProfile(); }
CHECK(profile); }();
Browser::CreateParams chrome_params =
Browser::CreateParams(profile, /*user_gesture=*/false);
// Pass |params| to cef::BrowserDelegate::Create from the Browser constructor. // Pass |params| to cef::BrowserDelegate::Create from the Browser constructor.
chrome_params.cef_params = base::MakeRefCounted<DelegateCreateParams>(params); chrome_params.cef_params = base::MakeRefCounted<DelegateCreateParams>(params);
@@ -412,10 +487,12 @@ Browser* ChromeBrowserHostImpl::CreateBrowser(
// documentation. // documentation.
ChromeBrowserView* chrome_browser_view = nullptr; ChromeBrowserView* chrome_browser_view = nullptr;
if (params.browser_view) { if (params.browser_view) {
// Don't show most controls. if (chrome_params.type == Browser::TYPE_NORMAL) {
chrome_params.type = Browser::TYPE_POPUP; // Don't show most controls.
// Don't show title bar or address. chrome_params.type = Browser::TYPE_POPUP;
chrome_params.trusted_source = true; // Don't show title bar or address.
chrome_params.trusted_source = true;
}
auto view_impl = auto view_impl =
static_cast<CefBrowserViewImpl*>(params.browser_view.get()); static_cast<CefBrowserViewImpl*>(params.browser_view.get());
@@ -456,6 +533,7 @@ Browser* ChromeBrowserHostImpl::CreateBrowser(
} }
void ChromeBrowserHostImpl::Attach(content::WebContents* web_contents, void ChromeBrowserHostImpl::Attach(content::WebContents* web_contents,
bool is_devtools_popup,
CefRefPtr<ChromeBrowserHostImpl> opener) { CefRefPtr<ChromeBrowserHostImpl> opener) {
DCHECK(web_contents); DCHECK(web_contents);
@@ -464,7 +542,7 @@ void ChromeBrowserHostImpl::Attach(content::WebContents* web_contents,
// new browser's platform delegate. // new browser's platform delegate.
opener->platform_delegate_->PopupWebContentsCreated( opener->platform_delegate_->PopupWebContentsCreated(
settings_, client_, web_contents, platform_delegate_.get(), settings_, client_, web_contents, platform_delegate_.get(),
/*is_devtools_popup=*/false); is_devtools_popup);
} }
platform_delegate_->WebContentsCreated(web_contents, 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 // Notify that the browser has been created. These must be delivered in the
// expected order. // expected order.
if (opener && opener->platform_delegate_) { if (opener) {
// 1. Notify the opener browser's platform delegate. With Views this will // 1. Notify the opener browser's platform delegate. With Views this will
// result in a call to CefBrowserViewDelegate::OnPopupBrowserViewCreated(). // result in a call to CefBrowserViewDelegate::OnPopupBrowserViewCreated().
// We want to call this method first because the implementation will often // 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 // CefBrowserHost::GetWindowHandle() will return kNullWindowHandle in
// OnAfterCreated(), which breaks client expectations (e.g. clients expect // OnAfterCreated(), which breaks client expectations (e.g. clients expect
// everything about the browser to be valid at that time). // everything about the browser to be valid at that time).
opener->platform_delegate_->PopupBrowserCreated( opener->platform_delegate_->PopupBrowserCreated(this, is_devtools_popup);
this,
/*is_devtools_popup=*/false);
} }
// 2. Notify the browser's LifeSpanHandler. This must always be the first // 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) { void ChromeBrowserHostImpl::SetBrowser(Browser* browser) {
CEF_REQUIRE_UIT(); CEF_REQUIRE_UIT();
if (browser == browser_) {
return;
}
browser_ = browser; browser_ = browser;
static_cast<CefBrowserPlatformDelegateChrome*>(platform_delegate_.get()) static_cast<CefBrowserPlatformDelegateChrome*>(platform_delegate_.get())
->set_chrome_browser(browser); ->set_chrome_browser(browser);
if (browser_) { if (browser_) {
host_window_handle_ = platform_delegate_->GetHostWindowHandle(); 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() { void ChromeBrowserHostImpl::WindowDestroyed() {
CEF_REQUIRE_UIT(); CEF_REQUIRE_UIT();
if (auto view = chrome_browser_view()) { if (auto view = chrome_browser_view()) {

View File

@@ -12,8 +12,8 @@
#include "libcef/browser/chrome/browser_delegate.h" #include "libcef/browser/chrome/browser_delegate.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "chrome/browser/ui/browser.h"
class Browser;
class ChromeBrowserDelegate; class ChromeBrowserDelegate;
class ChromeBrowserView; class ChromeBrowserView;
@@ -72,10 +72,6 @@ class ChromeBrowserHostImpl : public CefBrowserHostBase {
bool matchCase, bool matchCase,
bool findNext) override; bool findNext) override;
void StopFinding(bool clearSelection) 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; void CloseDevTools() override;
bool HasDevTools() override; bool HasDevTools() override;
bool IsWindowRenderingDisabled() override; bool IsWindowRenderingDisabled() override;
@@ -114,6 +110,9 @@ class ChromeBrowserHostImpl : public CefBrowserHostBase {
const CefSize& max_size) override; const CefSize& max_size) override;
CefRefPtr<CefExtension> GetExtension() override; CefRefPtr<CefExtension> GetExtension() override;
bool IsBackgroundHost() 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_; } Browser* browser() const { return browser_; }
@@ -126,6 +125,8 @@ class ChromeBrowserHostImpl : public CefBrowserHostBase {
protected: protected:
bool Navigate(const content::OpenURLParams& params) override; bool Navigate(const content::OpenURLParams& params) override;
void ShowDevToolsOnUIThread(
std::unique_ptr<CefShowDevToolsParams> params) override;
private: private:
friend class ChromeBrowserDelegate; friend class ChromeBrowserDelegate;
@@ -138,22 +139,32 @@ class ChromeBrowserHostImpl : public CefBrowserHostBase {
CefRefPtr<CefRequestContextImpl> request_context); CefRefPtr<CefRequestContextImpl> request_context);
// Create a new Browser without initializing the WebContents. // 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 // Called from ChromeBrowserDelegate::CreateBrowser when this object is first
// created. Must be called on the UI thread. // created. Must be called on the UI thread.
void Attach(content::WebContents* web_contents, void Attach(content::WebContents* web_contents,
bool is_devtools_popup,
CefRefPtr<ChromeBrowserHostImpl> opener); CefRefPtr<ChromeBrowserHostImpl> opener);
// Called from ChromeBrowserDelegate::AddNewContents to take ownership of a // Called from ChromeBrowserDelegate::AddNewContents to take ownership of a
// popup WebContents. // popup WebContents. |browser_create_params| may be empty for default Browser
void AddNewContents(std::unique_ptr<content::WebContents> contents); // 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, // Called when this object changes Browser ownership (e.g. initially created,
// dragging between windows, etc). The old Browser, if any, will be cleared // 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. // before the new Browser is added. Must be called on the UI thread.
void SetBrowser(Browser* browser); void SetBrowser(Browser* browser);
void SetDevToolsBrowserHost(
base::WeakPtr<ChromeBrowserHostImpl> devtools_browser_host);
// CefBrowserHostBase methods: // CefBrowserHostBase methods:
void WindowDestroyed() override; void WindowDestroyed() override;
bool WillBeDestroyed() const override; bool WillBeDestroyed() const override;
@@ -168,6 +179,8 @@ class ChromeBrowserHostImpl : public CefBrowserHostBase {
Browser* browser_ = nullptr; Browser* browser_ = nullptr;
CefWindowHandle host_window_handle_ = kNullWindowHandle; CefWindowHandle host_window_handle_ = kNullWindowHandle;
base::WeakPtr<ChromeBrowserHostImpl> devtools_browser_host_;
base::WeakPtrFactory<ChromeBrowserHostImpl> weak_ptr_factory_{this}; base::WeakPtrFactory<ChromeBrowserHostImpl> weak_ptr_factory_{this};
}; };

View File

@@ -4,6 +4,8 @@
#include "libcef/browser/chrome/views/chrome_browser_frame.h" #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/themes/theme_service.h"
#include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_commands.h" #include "chrome/browser/ui/browser_commands.h"
@@ -57,3 +59,24 @@ ChromeBrowserFrame::CreateNonClientFrameView() {
// Bypass the BrowserFrame implementation. // Bypass the BrowserFrame implementation.
return views::Widget::CreateNonClientFrameView(); 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();
}

View File

@@ -103,6 +103,7 @@ class ChromeBrowserFrame : public BrowserFrame {
views::internal::RootView* CreateRootView() override; views::internal::RootView* CreateRootView() override;
std::unique_ptr<views::NonClientFrameView> CreateNonClientFrameView() std::unique_ptr<views::NonClientFrameView> CreateNonClientFrameView()
override; override;
void Activate() override;
BrowserView* browser_view() const { return browser_view_; } BrowserView* browser_view() const { return browser_view_; }

View File

@@ -126,8 +126,6 @@ class ChildBrowserViewDelegate : public CefBrowserViewDelegate {
bool OnPopupBrowserViewCreated(CefRefPtr<CefBrowserView> browser_view, bool OnPopupBrowserViewCreated(CefRefPtr<CefBrowserView> browser_view,
CefRefPtr<CefBrowserView> popup_browser_view, CefRefPtr<CefBrowserView> popup_browser_view,
bool is_devtools) override { bool is_devtools) override {
DCHECK(!is_devtools);
auto new_browser = static_cast<CefBrowserHostBase*>( auto new_browser = static_cast<CefBrowserHostBase*>(
popup_browser_view->GetBrowser().get()); popup_browser_view->GetBrowser().get());
auto new_platform_delegate = new_browser->platform_delegate(); auto new_platform_delegate = new_browser->platform_delegate();

View File

@@ -202,14 +202,8 @@ class CefBrowserURLRequest::Context
scoped_refptr<base::SequencedTaskRunner> task_runner) { scoped_refptr<base::SequencedTaskRunner> task_runner) {
CEF_REQUIRE_UIT(); CEF_REQUIRE_UIT();
// Get or create the request context and browser context. auto* browser_context =
CefRefPtr<CefRequestContextImpl> request_context_impl = CefRequestContextImpl::GetBrowserContext(request_context);
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();
CHECK(browser_context); CHECK(browser_context);
scoped_refptr<net_service::URLLoaderFactoryGetter> loader_factory_getter; scoped_refptr<net_service::URLLoaderFactoryGetter> loader_factory_getter;

View File

@@ -89,6 +89,17 @@ class ResolveHostHelper : public network::ResolveHostClientBase {
mojo::Receiver<network::mojom::ResolveHostClient> receiver_{this}; 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 } // namespace
// CefBrowserContext // CefBrowserContext
@@ -184,6 +195,21 @@ CefRequestContextImpl::GetOrCreateForRequestContext(
return CefRequestContextImpl::GetOrCreateRequestContext(config); 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 { bool CefRequestContextImpl::VerifyBrowserContext() const {
if (!CEF_CURRENTLY_ON_UIT()) { if (!CEF_CURRENTLY_ON_UIT()) {
DCHECK(false) << "called on invalid thread"; DCHECK(false) << "called on invalid thread";

View File

@@ -38,6 +38,15 @@ class CefRequestContextImpl : public CefRequestContext {
static CefRefPtr<CefRequestContextImpl> GetOrCreateForRequestContext( static CefRefPtr<CefRequestContextImpl> GetOrCreateForRequestContext(
CefRefPtr<CefRequestContext> request_context); 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 // Verify that the browser context can be directly accessed (e.g. on the UI
// thread and initialized). // thread and initialized).
bool VerifyBrowserContext() const; bool VerifyBrowserContext() const;

View File

@@ -121,12 +121,18 @@ void CefNativeWidgetMac::OnWindowFullscreenTransitionStart() {
views::NativeWidgetMac::OnWindowFullscreenTransitionStart(); views::NativeWidgetMac::OnWindowFullscreenTransitionStart();
if (IsCefWindowInitialized()) { if (IsCefWindowInitialized()) {
window_delegate_->OnWindowFullscreenTransition(window_, false); window_delegate_->OnWindowFullscreenTransition(window_, false);
if (browser_view_) {
browser_view_->FullscreenStateChanging();
}
} }
} }
void CefNativeWidgetMac::OnWindowFullscreenTransitionComplete() { void CefNativeWidgetMac::OnWindowFullscreenTransitionComplete() {
views::NativeWidgetMac::OnWindowFullscreenTransitionComplete(); views::NativeWidgetMac::OnWindowFullscreenTransitionComplete();
if (IsCefWindowInitialized()) { if (IsCefWindowInitialized()) {
if (browser_view_) {
browser_view_->FullscreenStateChanged();
}
window_delegate_->OnWindowFullscreenTransition(window_, true); window_delegate_->OnWindowFullscreenTransition(window_, true);
} }
} }

View File

@@ -669,7 +669,8 @@ void CefWindowImpl::SetAccelerator(int command_id,
int key_code, int key_code,
bool shift_pressed, bool shift_pressed,
bool ctrl_pressed, bool ctrl_pressed,
bool alt_pressed) { bool alt_pressed,
bool high_priority) {
CEF_REQUIRE_VALID_RETURN_VOID(); CEF_REQUIRE_VALID_RETURN_VOID();
if (!widget_) { if (!widget_) {
return; return;
@@ -698,7 +699,10 @@ void CefWindowImpl::SetAccelerator(int command_id,
views::FocusManager* focus_manager = widget_->GetFocusManager(); views::FocusManager* focus_manager = widget_->GetFocusManager();
DCHECK(focus_manager); DCHECK(focus_manager);
focus_manager->RegisterAccelerator( focus_manager->RegisterAccelerator(
accelerator, ui::AcceleratorManager::kNormalPriority, this); accelerator,
high_priority ? ui::AcceleratorManager::kHighPriority
: ui::AcceleratorManager::kNormalPriority,
this);
} }
void CefWindowImpl::RemoveAccelerator(int command_id) { void CefWindowImpl::RemoveAccelerator(int command_id) {

View File

@@ -86,7 +86,8 @@ class CefWindowImpl
int key_code, int key_code,
bool shift_pressed, bool shift_pressed,
bool ctrl_pressed, bool ctrl_pressed,
bool alt_pressed) override; bool alt_pressed,
bool high_priority) override;
void RemoveAccelerator(int command_id) override; void RemoveAccelerator(int command_id) override;
void RemoveAllAccelerators() override; void RemoveAllAccelerators() override;

View File

@@ -296,6 +296,13 @@ class CefValueBase : public CefType, public CefValueController::Object {
// True if access to the underlying value is read-only. // True if access to the underlying value is read-only.
inline bool read_only() const { return 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. // True if the underlying value has been detached.
inline bool detached() const { return !controller_.get(); } inline bool detached() const { return !controller_.get(); }

View File

@@ -606,6 +606,11 @@ CefRefPtr<CefBinaryValue> CefBinaryValueImpl::Copy() {
return new CefBinaryValueImpl(const_value().Clone()); 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() { size_t CefBinaryValueImpl::GetSize() {
CEF_VALUE_VERIFY_RETURN(false, 0); CEF_VALUE_VERIFY_RETURN(false, 0);
return const_value().GetBlob().size(); return const_value().GetBlob().size();

View File

@@ -177,6 +177,7 @@ class CefBinaryValueImpl : public CefValueBase<CefBinaryValue, base::Value> {
bool IsSame(CefRefPtr<CefBinaryValue> that) override; bool IsSame(CefRefPtr<CefBinaryValue> that) override;
bool IsEqual(CefRefPtr<CefBinaryValue> that) override; bool IsEqual(CefRefPtr<CefBinaryValue> that) override;
CefRefPtr<CefBinaryValue> Copy() override; CefRefPtr<CefBinaryValue> Copy() override;
const void* GetRawData() override;
size_t GetSize() override; size_t GetSize() override;
size_t GetData(void* buffer, size_t buffer_size, size_t data_offset) override; size_t GetData(void* buffer, size_t buffer_size, size_t data_offset) override;

View File

@@ -2368,6 +2368,61 @@ bool CefV8ValueImpl::NeuterArrayBuffer() {
return true; 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 CefV8ValueImpl::GetFunctionName() {
CefString rv; CefString rv;
CEF_V8_REQUIRE_OBJECT_RETURN(rv); CEF_V8_REQUIRE_OBJECT_RETURN(rv);

View File

@@ -274,6 +274,8 @@ class CefV8ValueImpl : public CefV8Value {
CefRefPtr<CefV8ArrayBufferReleaseCallback> GetArrayBufferReleaseCallback() CefRefPtr<CefV8ArrayBufferReleaseCallback> GetArrayBufferReleaseCallback()
override; override;
bool NeuterArrayBuffer() override; bool NeuterArrayBuffer() override;
size_t GetArrayBufferByteLength() override;
void* GetArrayBufferData() override;
CefString GetFunctionName() override; CefString GetFunctionName() override;
CefRefPtr<CefV8Handler> GetFunctionHandler() override; CefRefPtr<CefV8Handler> GetFunctionHandler() override;
CefRefPtr<CefV8Value> ExecuteFunction( CefRefPtr<CefV8Value> ExecuteFunction(

View File

@@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory // implementations. See the translator.README.txt file in the tools directory
// for more information. // for more information.
// //
// $hash=905b24443e08e2d3e2464d5f4138e97904be3e9e$ // $hash=8da36dc268f2f9beb26abc105656f3b04b1d46ed$
// //
#include "libcef_dll/cpptoc/binary_value_cpptoc.h" #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); 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) { size_t CEF_CALLBACK binary_value_get_size(struct _cef_binary_value_t* self) {
shutdown_checker::AssertNotShutdown(); shutdown_checker::AssertNotShutdown();
@@ -193,6 +212,7 @@ CefBinaryValueCppToC::CefBinaryValueCppToC() {
GetStruct()->is_same = binary_value_is_same; GetStruct()->is_same = binary_value_is_same;
GetStruct()->is_equal = binary_value_is_equal; GetStruct()->is_equal = binary_value_is_equal;
GetStruct()->copy = binary_value_copy; GetStruct()->copy = binary_value_copy;
GetStruct()->get_raw_data = binary_value_get_raw_data;
GetStruct()->get_size = binary_value_get_size; GetStruct()->get_size = binary_value_get_size;
GetStruct()->get_data = binary_value_get_data; GetStruct()->get_data = binary_value_get_data;
} }

View File

@@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory // implementations. See the translator.README.txt file in the tools directory
// for more information. // for more information.
// //
// $hash=497607653318fe0245cbe18c8911e39867e16249$ // $hash=a5c3b05b23c536eba7ce2e7242c3840e93729b29$
// //
#include "libcef_dll/cpptoc/browser_host_cpptoc.h" #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; 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 } // namespace
// CONSTRUCTOR - Do not edit by hand. // CONSTRUCTOR - Do not edit by hand.
@@ -1512,6 +1583,11 @@ CefBrowserHostCppToC::CefBrowserHostCppToC() {
GetStruct()->is_background_host = browser_host_is_background_host; GetStruct()->is_background_host = browser_host_is_background_host;
GetStruct()->set_audio_muted = browser_host_set_audio_muted; GetStruct()->set_audio_muted = browser_host_set_audio_muted;
GetStruct()->is_audio_muted = browser_host_is_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. // DESTRUCTOR - Do not edit by hand.

View File

@@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory // implementations. See the translator.README.txt file in the tools directory
// for more information. // for more information.
// //
// $hash=e96fe0660b55afa20c3bb5fdebc85635ccc53d09$ // $hash=4990c06888649a2cb06ba7028f16f9cd762f3ad0$
// //
#include "libcef_dll/cpptoc/life_span_handler_cpptoc.h" #include "libcef_dll/cpptoc/life_span_handler_cpptoc.h"
@@ -169,6 +169,126 @@ int CEF_CALLBACK life_span_handler_on_before_popup(
return _retval; 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 void CEF_CALLBACK
life_span_handler_on_after_created(struct _cef_life_span_handler_t* self, life_span_handler_on_after_created(struct _cef_life_span_handler_t* self,
cef_browser_t* browser) { cef_browser_t* browser) {
@@ -244,6 +364,8 @@ life_span_handler_on_before_close(struct _cef_life_span_handler_t* self,
CefLifeSpanHandlerCppToC::CefLifeSpanHandlerCppToC() { CefLifeSpanHandlerCppToC::CefLifeSpanHandlerCppToC() {
GetStruct()->on_before_popup = life_span_handler_on_before_popup; 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()->on_after_created = life_span_handler_on_after_created;
GetStruct()->do_close = life_span_handler_do_close; GetStruct()->do_close = life_span_handler_do_close;
GetStruct()->on_before_close = life_span_handler_on_before_close; GetStruct()->on_before_close = life_span_handler_on_before_close;

View File

@@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory // implementations. See the translator.README.txt file in the tools directory
// for more information. // for more information.
// //
// $hash=3bc6db85e54dc87c1e592291be01820547e0989f$ // $hash=4356ad718a385149741e4c8bbbe5d5290466ed40$
// //
#include "libcef_dll/cpptoc/shared_memory_region_cpptoc.h" #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; return NULL;
} }
// This manual implementation can be removed once support for 'void*'
// is integrated into the CEF translator tool (issue #3591).
// Execute // Execute
void* _retval = CefSharedMemoryRegionCppToC::Get(self)->Memory(); void* _retval = CefSharedMemoryRegionCppToC::Get(self)->Memory();

View File

@@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory // implementations. See the translator.README.txt file in the tools directory
// for more information. // for more information.
// //
// $hash=ecd6caa0c415b57e93bc66f3c7a4cfb547f022c1$ // $hash=21d8fb47eb282f40fb9d602f44b8c1fd4ff44dea$
// //
#include "libcef_dll/cpptoc/v8value_cpptoc.h" #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) { cef_v8array_buffer_release_callback_t* release_callback) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING // 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 // Verify param: release_callback; type: refptr_diff
DCHECK(release_callback); DCHECK(release_callback);
if (!release_callback) { if (!release_callback) {
return NULL; return NULL;
} }
// Unverified params: buffer
// Execute // Execute
CefRefPtr<CefV8Value> _retval = CefV8Value::CreateArrayBuffer( CefRefPtr<CefV8Value> _retval = CefV8Value::CreateArrayBuffer(
@@ -948,6 +944,38 @@ int CEF_CALLBACK v8value_neuter_array_buffer(struct _cef_v8value_t* self) {
return _retval; 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 cef_string_userfree_t CEF_CALLBACK
v8value_get_function_name(struct _cef_v8value_t* self) { v8value_get_function_name(struct _cef_v8value_t* self) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
@@ -1153,6 +1181,9 @@ CefV8ValueCppToC::CefV8ValueCppToC() {
GetStruct()->get_array_buffer_release_callback = GetStruct()->get_array_buffer_release_callback =
v8value_get_array_buffer_release_callback; v8value_get_array_buffer_release_callback;
GetStruct()->neuter_array_buffer = v8value_neuter_array_buffer; 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_name = v8value_get_function_name;
GetStruct()->get_function_handler = v8value_get_function_handler; GetStruct()->get_function_handler = v8value_get_function_handler;
GetStruct()->execute_function = v8value_execute_function; GetStruct()->execute_function = v8value_execute_function;

View File

@@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory // implementations. See the translator.README.txt file in the tools directory
// for more information. // for more information.
// //
// $hash=23777aea864e9abf38c2e2c5d79a40d6bd22876d$ // $hash=38a50bca35881beb6400f3ad5d81b0a5ec86331d$
// //
#include "libcef_dll/cpptoc/views/window_cpptoc.h" #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 key_code,
int shift_pressed, int shift_pressed,
int ctrl_pressed, int ctrl_pressed,
int alt_pressed) { int alt_pressed,
int high_priority) {
shutdown_checker::AssertNotShutdown(); shutdown_checker::AssertNotShutdown();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
@@ -685,7 +686,8 @@ void CEF_CALLBACK window_set_accelerator(struct _cef_window_t* self,
// Execute // Execute
CefWindowCppToC::Get(self)->SetAccelerator( CefWindowCppToC::Get(self)->SetAccelerator(
command_id, key_code, shift_pressed ? true : false, 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, void CEF_CALLBACK window_remove_accelerator(struct _cef_window_t* self,

View File

@@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory // implementations. See the translator.README.txt file in the tools directory
// for more information. // for more information.
// //
// $hash=caaf5dfe8d56c784e213b1590c21194f08084b70$ // $hash=f42bab3d9e4ff45faf1fd8071646a8e5bed64177$
// //
#include "libcef_dll/ctocpp/binary_value_ctocpp.h" #include "libcef_dll/ctocpp/binary_value_ctocpp.h"
@@ -139,6 +139,24 @@ CefRefPtr<CefBinaryValue> CefBinaryValueCToCpp::Copy() {
return CefBinaryValueCToCpp::Wrap(_retval); 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() { NO_SANITIZE("cfi-icall") size_t CefBinaryValueCToCpp::GetSize() {
shutdown_checker::AssertNotShutdown(); shutdown_checker::AssertNotShutdown();

View File

@@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory // implementations. See the translator.README.txt file in the tools directory
// for more information. // for more information.
// //
// $hash=b6f011a6c26b4264084eb68dae0d63032c07013c$ // $hash=2e0ac9b73ba6bdb4b07ee0f8c445974359c5862f$
// //
#ifndef CEF_LIBCEF_DLL_CTOCPP_BINARY_VALUE_CTOCPP_H_ #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 IsSame(CefRefPtr<CefBinaryValue> that) override;
bool IsEqual(CefRefPtr<CefBinaryValue> that) override; bool IsEqual(CefRefPtr<CefBinaryValue> that) override;
CefRefPtr<CefBinaryValue> Copy() override; CefRefPtr<CefBinaryValue> Copy() override;
const void* GetRawData() override;
size_t GetSize() override; size_t GetSize() override;
size_t GetData(void* buffer, size_t buffer_size, size_t data_offset) override; size_t GetData(void* buffer, size_t buffer_size, size_t data_offset) override;
}; };

View File

@@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory // implementations. See the translator.README.txt file in the tools directory
// for more information. // for more information.
// //
// $hash=cd4e4aa1670f0c887090e23f5e7e3a01e5de9d13$ // $hash=b06e3bbc86769bbc2485d4ab9530b5c39dc73243$
// //
#include "libcef_dll/ctocpp/browser_host_ctocpp.h" #include "libcef_dll/ctocpp/browser_host_ctocpp.h"
@@ -1229,6 +1229,73 @@ NO_SANITIZE("cfi-icall") bool CefBrowserHostCToCpp::IsAudioMuted() {
return _retval ? true : false; 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. // CONSTRUCTOR - Do not edit by hand.
CefBrowserHostCToCpp::CefBrowserHostCToCpp() {} CefBrowserHostCToCpp::CefBrowserHostCToCpp() {}

View File

@@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory // implementations. See the translator.README.txt file in the tools directory
// for more information. // for more information.
// //
// $hash=b4e11c91197cd5d6ccbe3a0d96aaae3792a6e05c$ // $hash=e07873b7e67c06fb54dafa370eca83d2c698ffb9$
// //
#ifndef CEF_LIBCEF_DLL_CTOCPP_BROWSER_HOST_CTOCPP_H_ #ifndef CEF_LIBCEF_DLL_CTOCPP_BROWSER_HOST_CTOCPP_H_
@@ -134,6 +134,11 @@ class CefBrowserHostCToCpp : public CefCToCppRefCounted<CefBrowserHostCToCpp,
bool IsBackgroundHost() override; bool IsBackgroundHost() override;
void SetAudioMuted(bool mute) override; void SetAudioMuted(bool mute) override;
bool IsAudioMuted() 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_ #endif // CEF_LIBCEF_DLL_CTOCPP_BROWSER_HOST_CTOCPP_H_

View File

@@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory // implementations. See the translator.README.txt file in the tools directory
// for more information. // for more information.
// //
// $hash=d141b95304de99ab093db8f6c524a05e26f4edb5$ // $hash=d85695db88a025b1f7e4e4604f3085da29d5eabf$
// //
#include "libcef_dll/ctocpp/life_span_handler_ctocpp.h" #include "libcef_dll/ctocpp/life_span_handler_ctocpp.h"
@@ -109,6 +109,76 @@ bool CefLifeSpanHandlerCToCpp::OnBeforePopup(
return _retval ? true : false; 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") NO_SANITIZE("cfi-icall")
void CefLifeSpanHandlerCToCpp::OnAfterCreated(CefRefPtr<CefBrowser> browser) { void CefLifeSpanHandlerCToCpp::OnAfterCreated(CefRefPtr<CefBrowser> browser) {
shutdown_checker::AssertNotShutdown(); shutdown_checker::AssertNotShutdown();

View File

@@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory // implementations. See the translator.README.txt file in the tools directory
// for more information. // for more information.
// //
// $hash=229117f1ecb1cc27b5ab5eebd79e64c30d73a855$ // $hash=53f00e60e361c79c69a8f19474a234d5011454f5$
// //
#ifndef CEF_LIBCEF_DLL_CTOCPP_LIFE_SPAN_HANDLER_CTOCPP_H_ #ifndef CEF_LIBCEF_DLL_CTOCPP_LIFE_SPAN_HANDLER_CTOCPP_H_
@@ -49,6 +49,12 @@ class CefLifeSpanHandlerCToCpp
CefBrowserSettings& settings, CefBrowserSettings& settings,
CefRefPtr<CefDictionaryValue>& extra_info, CefRefPtr<CefDictionaryValue>& extra_info,
bool* no_javascript_access) override; 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; void OnAfterCreated(CefRefPtr<CefBrowser> browser) override;
bool DoClose(CefRefPtr<CefBrowser> browser) override; bool DoClose(CefRefPtr<CefBrowser> browser) override;
void OnBeforeClose(CefRefPtr<CefBrowser> browser) override; void OnBeforeClose(CefRefPtr<CefBrowser> browser) override;

View File

@@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory // implementations. See the translator.README.txt file in the tools directory
// for more information. // for more information.
// //
// $hash=31516110398f9fe682988645d74ac8789b712181$ // $hash=a396f422ed18fe4aae90d4fef3750b4726279c7e$
// //
#include "libcef_dll/ctocpp/shared_memory_region_ctocpp.h" #include "libcef_dll/ctocpp/shared_memory_region_ctocpp.h"
@@ -59,6 +59,9 @@ NO_SANITIZE("cfi-icall") void* CefSharedMemoryRegionCToCpp::Memory() {
return NULL; return NULL;
} }
// This manual implementation can be removed once support for 'void*'
// is integrated into the CEF translator tool (issue #3591).
// Execute // Execute
void* _retval = _struct->memory(_struct); void* _retval = _struct->memory(_struct);

View File

@@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory // implementations. See the translator.README.txt file in the tools directory
// for more information. // for more information.
// //
// $hash=459c331b0c02f55c4b700761ad2132d7320fd467$ // $hash=f67b0996d7e2133f3f28f2d8ba5446c5ff40aaba$
// //
#include "libcef_dll/ctocpp/v8value_ctocpp.h" #include "libcef_dll/ctocpp/v8value_ctocpp.h"
@@ -147,16 +147,12 @@ CefRefPtr<CefV8Value> CefV8Value::CreateArrayBuffer(
CefRefPtr<CefV8ArrayBufferReleaseCallback> release_callback) { CefRefPtr<CefV8ArrayBufferReleaseCallback> release_callback) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING // 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 // Verify param: release_callback; type: refptr_diff
DCHECK(release_callback.get()); DCHECK(release_callback.get());
if (!release_callback.get()) { if (!release_callback.get()) {
return nullptr; return nullptr;
} }
// Unverified params: buffer
// Execute // Execute
cef_v8value_t* _retval = cef_v8value_create_array_buffer( cef_v8value_t* _retval = cef_v8value_create_array_buffer(
@@ -957,6 +953,37 @@ NO_SANITIZE("cfi-icall") bool CefV8ValueCToCpp::NeuterArrayBuffer() {
return _retval ? true : false; 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() { NO_SANITIZE("cfi-icall") CefString CefV8ValueCToCpp::GetFunctionName() {
cef_v8value_t* _struct = GetStruct(); cef_v8value_t* _struct = GetStruct();
if (CEF_MEMBER_MISSING(_struct, get_function_name)) { if (CEF_MEMBER_MISSING(_struct, get_function_name)) {

View File

@@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory // implementations. See the translator.README.txt file in the tools directory
// for more information. // for more information.
// //
// $hash=cab5b018f6706a3c8496865e0c9f30fcbc94cdd8$ // $hash=c81cc0910be6678c0512c5423b8fc5dc1df42743$
// //
#ifndef CEF_LIBCEF_DLL_CTOCPP_V8VALUE_CTOCPP_H_ #ifndef CEF_LIBCEF_DLL_CTOCPP_V8VALUE_CTOCPP_H_
@@ -83,6 +83,8 @@ class CefV8ValueCToCpp
CefRefPtr<CefV8ArrayBufferReleaseCallback> GetArrayBufferReleaseCallback() CefRefPtr<CefV8ArrayBufferReleaseCallback> GetArrayBufferReleaseCallback()
override; override;
bool NeuterArrayBuffer() override; bool NeuterArrayBuffer() override;
size_t GetArrayBufferByteLength() override;
void* GetArrayBufferData() override;
CefString GetFunctionName() override; CefString GetFunctionName() override;
CefRefPtr<CefV8Handler> GetFunctionHandler() override; CefRefPtr<CefV8Handler> GetFunctionHandler() override;
CefRefPtr<CefV8Value> ExecuteFunction( CefRefPtr<CefV8Value> ExecuteFunction(

View File

@@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory // implementations. See the translator.README.txt file in the tools directory
// for more information. // for more information.
// //
// $hash=b6b0a2a563b475163aa71b20af6ec2ac8c1f0cae$ // $hash=c8f164d20875c8071837c04abb44e09672d894af$
// //
#include "libcef_dll/ctocpp/views/window_ctocpp.h" #include "libcef_dll/ctocpp/views/window_ctocpp.h"
@@ -663,7 +663,8 @@ void CefWindowCToCpp::SetAccelerator(int command_id,
int key_code, int key_code,
bool shift_pressed, bool shift_pressed,
bool ctrl_pressed, bool ctrl_pressed,
bool alt_pressed) { bool alt_pressed,
bool high_priority) {
shutdown_checker::AssertNotShutdown(); shutdown_checker::AssertNotShutdown();
cef_window_t* _struct = GetStruct(); cef_window_t* _struct = GetStruct();
@@ -675,7 +676,7 @@ void CefWindowCToCpp::SetAccelerator(int command_id,
// Execute // Execute
_struct->set_accelerator(_struct, command_id, key_code, shift_pressed, _struct->set_accelerator(_struct, command_id, key_code, shift_pressed,
ctrl_pressed, alt_pressed); ctrl_pressed, alt_pressed, high_priority);
} }
NO_SANITIZE("cfi-icall") NO_SANITIZE("cfi-icall")

View File

@@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory // implementations. See the translator.README.txt file in the tools directory
// for more information. // for more information.
// //
// $hash=2a7aaed7d4296e29dca74345cf2b2d4db221a738$ // $hash=d0c31c38bf29c9b44f645e69a912b6b8a4030066$
// //
#ifndef CEF_LIBCEF_DLL_CTOCPP_VIEWS_WINDOW_CTOCPP_H_ #ifndef CEF_LIBCEF_DLL_CTOCPP_VIEWS_WINDOW_CTOCPP_H_
@@ -83,7 +83,8 @@ class CefWindowCToCpp
int key_code, int key_code,
bool shift_pressed, bool shift_pressed,
bool ctrl_pressed, bool ctrl_pressed,
bool alt_pressed) override; bool alt_pressed,
bool high_priority) override;
void RemoveAccelerator(int command_id) override; void RemoveAccelerator(int command_id) override;
void RemoveAllAccelerators() override; void RemoveAllAccelerators() override;

View File

@@ -9,11 +9,11 @@
#include <set> #include <set>
#include "include/base/cef_callback.h" #include "include/base/cef_callback.h"
#include "include/cef_shared_process_message_builder.h"
#include "include/cef_task.h" #include "include/cef_task.h"
#include "include/wrapper/cef_closure_task.h" #include "include/wrapper/cef_closure_task.h"
#include "include/wrapper/cef_helpers.h" #include "include/wrapper/cef_helpers.h"
#include "libcef_dll/wrapper/cef_browser_info_map.h" #include "libcef_dll/wrapper/cef_browser_info_map.h"
#include "libcef_dll/wrapper/cef_message_router_utils.h"
namespace { namespace {
@@ -47,126 +47,7 @@ bool ValidateConfig(CefMessageRouterConfig& config) {
return true; return true;
} }
struct MessageHeader { namespace cmru = cef_message_router_utils;
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{};
}
/** /**
* @brief A helper template for generating ID values. * @brief A helper template for generating ID values.
@@ -204,11 +85,15 @@ class CefMessageRouterBrowserSideImpl : public CefMessageRouterBrowserSide {
CallbackImpl(CefRefPtr<CefMessageRouterBrowserSideImpl> router, CallbackImpl(CefRefPtr<CefMessageRouterBrowserSideImpl> router,
int browser_id, int browser_id,
int64_t query_id, int64_t query_id,
bool persistent) bool persistent,
size_t message_size_threshold,
const std::string& query_message_name)
: router_(router), : router_(router),
browser_id_(browser_id), browser_id_(browser_id),
query_id_(query_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(const CallbackImpl&) = delete;
CallbackImpl& operator=(const CallbackImpl&) = delete; CallbackImpl& operator=(const CallbackImpl&) = delete;
@@ -221,44 +106,36 @@ class CefMessageRouterBrowserSideImpl : public CefMessageRouterBrowserSide {
} }
void Success(const CefString& response) override { void Success(const CefString& response) override {
if (!CefCurrentlyOn(TID_UI)) { auto builder = cmru::CreateBrowserResponseBuilder(
// Must execute on the UI thread to access member variables. message_size_threshold_, query_message_name_, response);
CefPostTask(TID_UI,
base::BindOnce(&CallbackImpl::Success, this, response));
return;
}
if (router_) { // We need to post task here for two reasons:
CefPostTask( // 1) To safely access member variables.
TID_UI, // 2) To let the router to persist the query information before
base::BindOnce(&CefMessageRouterBrowserSideImpl::OnCallbackSuccess, // the Success callback is executed.
router_.get(), browser_id_, query_id_, response)); CefPostTask(TID_UI,
base::BindOnce(&CallbackImpl::SuccessImpl, this, builder));
}
if (!persistent_) { void Success(const void* data, size_t size) override {
// Non-persistent callbacks are only good for a single use. auto builder = cmru::CreateBrowserResponseBuilder(
router_ = nullptr; 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 { void Failure(int error_code, const CefString& error_message) override {
if (!CefCurrentlyOn(TID_UI)) { // We need to post task here for two reasons:
// Must execute on the UI thread to access member variables. // 1) To safely access member variables.
CefPostTask(TID_UI, base::BindOnce(&CallbackImpl::Failure, this, // 2) To give previosly submitted tasks by the Success calls to execute
error_code, error_message)); // before we invalidate the callback.
return; CefPostTask(TID_UI, base::BindOnce(&CallbackImpl::FailureImpl, this,
} error_code, error_message));
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;
}
} }
void Detach() { void Detach() {
@@ -267,10 +144,37 @@ class CefMessageRouterBrowserSideImpl : public CefMessageRouterBrowserSide {
} }
private: 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_; CefRefPtr<CefMessageRouterBrowserSideImpl> router_;
const int browser_id_; const int browser_id_;
const int64_t query_id_; const int64_t query_id_;
const bool persistent_; const bool persistent_;
const size_t message_size_threshold_;
const std::string query_message_name_;
IMPLEMENT_REFCOUNTING(CallbackImpl); IMPLEMENT_REFCOUNTING(CallbackImpl);
}; };
@@ -388,13 +292,10 @@ class CefMessageRouterBrowserSideImpl : public CefMessageRouterBrowserSide {
const std::string& message_name = message->GetName(); const std::string& message_name = message->GetName();
if (message_name == query_message_name_) { if (message_name == query_message_name_) {
CefRefPtr<CefListValue> args = message->GetArgumentList(); cmru::RendererMessage content = cmru::ParseRendererMessage(message);
DCHECK_EQ(args->GetSize(), 4U); const int context_id = content.context_id;
const int request_id = content.request_id;
const int context_id = args->GetInt(0); const bool persistent = content.is_persistent;
const int request_id = args->GetInt(1);
const CefString& request = args->GetString(2);
const bool persistent = args->GetBool(3);
if (handler_set_.empty()) { if (handler_set_.empty()) {
// No handlers so cancel the query. // No handlers so cancel the query.
@@ -405,40 +306,38 @@ class CefMessageRouterBrowserSideImpl : public CefMessageRouterBrowserSide {
const int browser_id = browser->GetIdentifier(); const int browser_id = browser->GetIdentifier();
const int64_t query_id = query_id_generator_.GetNextId(); const int64_t query_id = query_id_generator_.GetNextId();
CefRefPtr<CallbackImpl> callback( CefRefPtr<CallbackImpl> callback =
new CallbackImpl(this, browser_id, query_id, persistent)); 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 // Make a copy of the handler list in case the user adds or removes a
// handler while we're iterating. // handler while we're iterating.
HandlerSet handler_set = handler_set_; const HandlerSet handlers = handler_set_;
bool handled = false; Handler* handler = std::visit(
HandlerSet::const_iterator it_handler = handler_set.begin(); [&](const auto& arg) -> CefMessageRouterBrowserSide::Handler* {
for (; it_handler != handler_set.end(); ++it_handler) { for (auto handler : handlers) {
handled = (*it_handler) bool handled = handler->OnQuery(browser, frame, query_id, arg,
->OnQuery(browser, frame, query_id, request, persistent, persistent, callback.get());
callback.get()); if (handled) {
if (handled) { return handler;
break; }
} }
} return nullptr;
},
content.payload);
// If the query isn't handled nothing should be keeping a reference to // If the query isn't handled nothing should be keeping a reference to
// the callback. // the callback.
DCHECK(handled || callback->HasOneRef()); DCHECK(handler != nullptr || callback->HasOneRef());
if (handled) { if (handler) {
// Persist the query information until the callback executes. // Persist the query information until the callback executes.
// It's safe to do this here because the callback will execute // It's safe to do this here because the callback will execute
// asynchronously. // asynchronously.
QueryInfo* info = new QueryInfo; QueryInfo* info =
info->browser = browser; new QueryInfo{browser, frame, context_id, request_id,
info->frame = frame; persistent, callback, handler};
info->context_id = context_id;
info->request_id = request_id;
info->persistent = persistent;
info->callback = callback;
info->handler = *(it_handler);
browser_query_info_map_.Add(browser_id, query_id, info); browser_query_info_map_.Add(browser_id, query_id, info);
} else { } else {
// Invalidate the callback. // Invalidate the callback.
@@ -527,15 +426,17 @@ class CefMessageRouterBrowserSideImpl : public CefMessageRouterBrowserSide {
} }
// Called by CallbackImpl on success. // Called by CallbackImpl on success.
void OnCallbackSuccess(int browser_id, void OnCallbackSuccess(
int64_t query_id, int browser_id,
const CefString& response) { int64_t query_id,
const CefRefPtr<cmru::BrowserResponseBuilder>& builder) {
CEF_REQUIRE_UI_THREAD(); CEF_REQUIRE_UI_THREAD();
bool removed; bool removed;
QueryInfo* info = GetQueryInfo(browser_id, query_id, false, &removed); QueryInfo* info = GetQueryInfo(browser_id, query_id, false, &removed);
if (info) { if (info) {
SendQuerySuccess(info, response); SendQuerySuccess(info->browser, info->frame, info->context_id,
info->request_id, builder);
if (removed) { if (removed) {
delete info; delete info;
} }
@@ -558,19 +459,13 @@ class CefMessageRouterBrowserSideImpl : public CefMessageRouterBrowserSide {
} }
} }
void SendQuerySuccess(QueryInfo* info, const CefString& response) { void SendQuerySuccess(
SendQuerySuccess(info->browser, info->frame, info->context_id, CefRefPtr<CefBrowser> browser,
info->request_id, response); CefRefPtr<CefFrame> frame,
} int context_id,
int request_id,
void SendQuerySuccess(CefRefPtr<CefBrowser> browser, const CefRefPtr<cmru::BrowserResponseBuilder>& builder) {
CefRefPtr<CefFrame> frame, if (auto message = builder->Build(context_id, request_id)) {
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)) {
frame->SendProcessMessage(PID_RENDERER, message); frame->SendProcessMessage(PID_RENDERER, message);
} }
} }
@@ -758,10 +653,16 @@ class CefMessageRouterRendererSideImpl : public CefMessageRouterRendererSide {
CefRefPtr<CefV8Value> arg = arguments[0]; CefRefPtr<CefV8Value> arg = arguments[0];
CefRefPtr<CefV8Value> requestVal = arg->GetValue(kMemberRequest); 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 '" + exception = "Invalid arguments; object member '" +
std::string(kMemberRequest) + std::string(kMemberRequest) +
"' is required and must have type string"; "' must have type string or ArrayBuffer";
return true; return true;
} }
@@ -804,9 +705,11 @@ class CefMessageRouterRendererSideImpl : public CefMessageRouterRendererSide {
(persistentVal.get() && persistentVal->GetBoolValue()); (persistentVal.get() && persistentVal->GetBoolValue());
const int request_id = router_->SendQuery( const int request_id = router_->SendQuery(
context->GetBrowser(), context->GetFrame(), context_id, context->GetBrowser(), context->GetFrame(), context_id, requestVal,
requestVal->GetStringValue(), persistent, successVal, failureVal); persistent, successVal, failureVal);
retval = CefV8Value::CreateInt(request_id); retval = CefV8Value::CreateInt(request_id);
return true; return true;
} else if (name == config_.js_cancel_function) { } else if (name == config_.js_cancel_function) {
if (arguments.size() != 1 || !arguments[0]->IsInt()) { if (arguments.size() != 1 || !arguments[0]->IsInt()) {
@@ -958,29 +861,26 @@ class CefMessageRouterRendererSideImpl : public CefMessageRouterRendererSide {
CefRefPtr<CefProcessMessage> message) override { CefRefPtr<CefProcessMessage> message) override {
CEF_REQUIRE_RENDERER_THREAD(); CEF_REQUIRE_RENDERER_THREAD();
const std::string& message_name = message->GetName(); if (message->GetName() != query_message_name_) {
if (message_name == query_message_name_) { return false;
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;
} }
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: private:
@@ -1039,7 +939,7 @@ class CefMessageRouterRendererSideImpl : public CefMessageRouterRendererSide {
int SendQuery(CefRefPtr<CefBrowser> browser, int SendQuery(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame, CefRefPtr<CefFrame> frame,
int context_id, int context_id,
const CefString& request, CefRefPtr<CefV8Value> request,
bool persistent, bool persistent,
CefRefPtr<CefV8Value> success_callback, CefRefPtr<CefV8Value> success_callback,
CefRefPtr<CefV8Value> failure_callback) { CefRefPtr<CefV8Value> failure_callback) {
@@ -1053,14 +953,9 @@ class CefMessageRouterRendererSideImpl : public CefMessageRouterRendererSide {
browser_request_info_map_.Add(browser->GetIdentifier(), browser_request_info_map_.Add(browser->GetIdentifier(),
std::make_pair(context_id, request_id), info); std::make_pair(context_id, request_id), info);
CefRefPtr<CefProcessMessage> message = CefRefPtr<CefProcessMessage> message = cmru::BuildRendererMsg(
CefProcessMessage::Create(query_message_name_); config_.message_size_threshold, query_message_name_, context_id,
request_id, request, persistent);
CefRefPtr<CefListValue> args = message->GetArgumentList();
args->SetInt(0, context_id);
args->SetInt(1, request_id);
args->SetString(2, request);
args->SetBool(3, persistent);
frame->SendProcessMessage(PID_BROWSER, message); 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. // Execute the onFailure JavaScript callback.
void ExecuteFailureCallback(int browser_id, void ExecuteFailureCallback(int browser_id,
int context_id, int context_id,

View 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

View 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_

View File

@@ -117,6 +117,10 @@ patches = [
# Windows: Fix incorrect DIPToScreenRect usage in DesktopWindowTreeHostWin # Windows: Fix incorrect DIPToScreenRect usage in DesktopWindowTreeHostWin
# when |has_external_parent_| is true. # when |has_external_parent_| is true.
# https://github.com/chromiumembedded/cef/issues/3359 # 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', 'name': 'views_widget',
}, },
{ {
@@ -674,5 +678,10 @@ patches = [
# https://chromium-review.googlesource.com/c/chromium/src/+/4829483 # https://chromium-review.googlesource.com/c/chromium/src/+/4829483
# https://bugs.chromium.org/p/chromium/issues/detail?id=1470837#c22 # https://bugs.chromium.org/p/chromium/issues/detail?id=1470837#c22
'name': 'rfh_navigation_4829483' 'name': 'rfh_navigation_4829483'
},
{
# linux: Disable compiler TLS in libxml2.
# https://github.com/chromiumembedded/cef/issues/3616
'name': 'linux_libxml_tls_3616'
} }
] ]

View File

@@ -20,10 +20,10 @@ index 401eb0cd40ee2..5e7ac0b6d9d0a 100644
// Make an exception to allow most visited tiles to commit in // 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 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
+++ 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 = bool use_opaque_origin =
(sandbox_flags & network::mojom::WebSandboxFlags::kOrigin) == (sandbox_flags & network::mojom::WebSandboxFlags::kOrigin) ==
network::mojom::WebSandboxFlags::kOrigin; network::mojom::WebSandboxFlags::kOrigin;
@@ -47,7 +47,7 @@ index 68b50260715c2..79d9cd4558848 100644
} }
return origin_and_debug_info; return origin_and_debug_info;
@@ -7572,6 +7584,15 @@ NavigationRequest::GetOriginForURLLoaderFactoryAfterResponseWithDebugInfo() { @@ -7573,6 +7585,15 @@ NavigationRequest::GetOriginForURLLoaderFactoryAfterResponseWithDebugInfo() {
DetermineInitiatorRelationship(initiator_rfh, DetermineInitiatorRelationship(initiator_rfh,
frame_tree_node_->current_frame_host())); frame_tree_node_->current_frame_host()));

View File

@@ -1,5 +1,5 @@
diff --git chrome/browser/BUILD.gn chrome/browser/BUILD.gn 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
+++ chrome/browser/BUILD.gn +++ chrome/browser/BUILD.gn
@@ -11,6 +11,7 @@ import("//build/config/compiler/pgo/pgo.gni") @@ -11,6 +11,7 @@ import("//build/config/compiler/pgo/pgo.gni")
@@ -18,7 +18,7 @@ index 157ee5cadc0a7..9906a3cc24dd0 100644
"//chrome:extra_resources", "//chrome:extra_resources",
"//chrome:resources", "//chrome:resources",
"//chrome:strings", "//chrome:strings",
@@ -2694,6 +2696,10 @@ static_library("browser") { @@ -2696,6 +2698,10 @@ static_library("browser") {
] ]
} }

View File

@@ -12,8 +12,70 @@ index 2480282a19d12..dbd1fbf8a15b5 100644
return false; 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 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
+++ chrome/browser/ui/BUILD.gn +++ chrome/browser/ui/BUILD.gn
@@ -9,6 +9,7 @@ import("//build/config/compiler/compiler.gni") @@ -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.cc",
"views/apps/app_info_dialog/app_info_dialog_container.h", "views/apps/app_info_dialog/app_info_dialog_container.h",
"views/apps/app_info_dialog/app_info_dialog_views.cc", "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) { if (enable_printing) {
deps += [ deps += [
"//components/printing/browser", "//components/printing/browser",
@@ -333,7 +395,7 @@ index 9ba2025634365..b6ceaa7f0b531 100644
case TYPE_NORMAL: case TYPE_NORMAL:
return NormalBrowserSupportsWindowFeature(feature, check_can_support); return NormalBrowserSupportsWindowFeature(feature, check_can_support);
diff --git chrome/browser/ui/browser.h chrome/browser/ui/browser.h 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
+++ chrome/browser/ui/browser.h +++ chrome/browser/ui/browser.h
@@ -22,6 +22,7 @@ @@ -22,6 +22,7 @@
@@ -364,7 +426,7 @@ index db37e861d2546..c47dfc31131f7 100644
+ scoped_refptr<cef::BrowserDelegate::CreateParams> cef_params; + scoped_refptr<cef::BrowserDelegate::CreateParams> cef_params;
+ +
+ // Specify the Browser that is opening this popup. + // 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; + raw_ptr<Browser, DanglingUntriaged> opener = nullptr;
+#endif +#endif
+ +

View File

@@ -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 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
+++ 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(); return callback.get();
} }
@@ -16,7 +16,7 @@ index 9ed9d3b43c45b..845bb4ff858ef 100644
enum class UmaEnumIdLookupType { enum class UmaEnumIdLookupType {
GeneralEnumId, GeneralEnumId,
ContextSpecificEnumId, 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)) if (ContextMenuMatcher::IsExtensionsCustomCommandId(id))
return 1; return 1;
@@ -27,7 +27,7 @@ index 9ed9d3b43c45b..845bb4ff858ef 100644
id = CollapseCommandsForUMA(id); id = CollapseCommandsForUMA(id);
const auto& map = GetIdcToUmaMap(type); const auto& map = GetIdcToUmaMap(type);
auto it = map.find(id); 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); pdf_ocr_submenu_model_ = std::make_unique<ui::SimpleMenuModel>(this);
#endif // BUILDFLAG(ENABLE_SCREEN_AI_SERVICE) #endif // BUILDFLAG(ENABLE_SCREEN_AI_SERVICE)
@@ -42,7 +42,7 @@ index 9ed9d3b43c45b..845bb4ff858ef 100644
observers_.AddObserver(&autofill_context_menu_manager_); observers_.AddObserver(&autofill_context_menu_manager_);
} }
@@ -1278,6 +1297,12 @@ void RenderViewContextMenu::InitMenu() { @@ -1280,6 +1299,12 @@ void RenderViewContextMenu::InitMenu() {
autofill::PopupHidingReason::kContextMenuOpened); autofill::PopupHidingReason::kContextMenuOpened);
} }
} }
@@ -55,7 +55,7 @@ index 9ed9d3b43c45b..845bb4ff858ef 100644
} }
Profile* RenderViewContextMenu::GetProfile() const { 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); execute_plugin_action_callback_ = std::move(cb);
} }
@@ -69,7 +69,7 @@ index 9ed9d3b43c45b..845bb4ff858ef 100644
RenderViewContextMenu::GetHandlersForLinkUrl() { RenderViewContextMenu::GetHandlersForLinkUrl() {
custom_handlers::ProtocolHandlerRegistry::ProtocolHandlerList handlers = 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 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
+++ 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 @@ -152,6 +152,12 @@ class RenderViewContextMenu
@@ -85,7 +85,7 @@ index 45f2a2a82cb03..5abee00109363 100644
protected: protected:
Profile* GetProfile() const; Profile* GetProfile() const;
@@ -437,6 +443,9 @@ class RenderViewContextMenu @@ -441,6 +447,9 @@ class RenderViewContextMenu
// built. // built.
bool is_protocol_submenu_valid_ = false; bool is_protocol_submenu_valid_ = false;

View File

@@ -1,5 +1,5 @@
diff --git chrome/browser/themes/theme_service.cc chrome/browser/themes/theme_service.cc 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
+++ chrome/browser/themes/theme_service.cc +++ chrome/browser/themes/theme_service.cc
@@ -29,6 +29,7 @@ @@ -29,6 +29,7 @@
@@ -10,7 +10,7 @@ index dbd628982e216..d77a39111e254 100644
#include "chrome/browser/browser_features.h" #include "chrome/browser/browser_features.h"
#include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/theme_installed_infobar_delegate.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/color/color_provider_manager.h"
#include "ui/native_theme/native_theme.h" #include "ui/native_theme/native_theme.h"
@@ -21,7 +21,7 @@ index dbd628982e216..d77a39111e254 100644
#if BUILDFLAG(ENABLE_EXTENSIONS) #if BUILDFLAG(ENABLE_EXTENSIONS)
#include "base/scoped_observation.h" #include "base/scoped_observation.h"
#include "extensions/browser/extension_registry_observer.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 // OnExtensionServiceReady. Otherwise, the ThemeObserver won't be
// constructed in time to observe the corresponding events. // constructed in time to observe the corresponding events.
#if BUILDFLAG(ENABLE_EXTENSIONS) #if BUILDFLAG(ENABLE_EXTENSIONS)

View File

@@ -233,7 +233,7 @@ index a509d0b37e953..0d48c4a1f1daf 100644
+#endif +#endif
} }
diff --git chrome/browser/chrome_content_browser_client.cc chrome/browser/chrome_content_browser_client.cc 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
+++ chrome/browser/chrome_content_browser_client.cc +++ chrome/browser/chrome_content_browser_client.cc
@@ -42,6 +42,7 @@ @@ -42,6 +42,7 @@
@@ -295,7 +295,7 @@ index 54053dfc9b86d..19c11cf71046d 100644
} }
std::vector<base::FilePath> 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 now = base::TimeTicks::Now();
const auto timeout = GetKeepaliveTimerTimeout(context); const auto timeout = GetKeepaliveTimerTimeout(context);
keepalive_deadline_ = std::max(keepalive_deadline_, now + timeout); keepalive_deadline_ = std::max(keepalive_deadline_, now + timeout);
@@ -308,7 +308,7 @@ index 54053dfc9b86d..19c11cf71046d 100644
FROM_HERE, keepalive_deadline_ - now, FROM_HERE, keepalive_deadline_ - now,
base::BindOnce( base::BindOnce(
&ChromeContentBrowserClient::OnKeepaliveTimerFired, &ChromeContentBrowserClient::OnKeepaliveTimerFired,
@@ -7674,7 +7686,8 @@ void ChromeContentBrowserClient::OnKeepaliveRequestFinished() { @@ -7675,7 +7687,8 @@ void ChromeContentBrowserClient::OnKeepaliveRequestFinished() {
--num_keepalive_requests_; --num_keepalive_requests_;
if (num_keepalive_requests_ == 0) { if (num_keepalive_requests_ == 0) {
DVLOG(1) << "Stopping the keepalive timer"; 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 // This deletes the keep alive handle attached to the timer function and
// unblock the shutdown sequence. // 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 now = base::TimeTicks::Now();
const auto then = keepalive_deadline_; const auto then = keepalive_deadline_;
if (now < then) { if (now < then) {

View File

@@ -231,7 +231,7 @@ index 59024587ef6b7..0c30aa71768cf 100644
void FindBarHost::RegisterAccelerators() { void FindBarHost::RegisterAccelerators() {
diff --git chrome/browser/ui/views/frame/browser_frame.cc chrome/browser/ui/views/frame/browser_frame.cc 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
+++ chrome/browser/ui/views/frame/browser_frame.cc +++ chrome/browser/ui/views/frame/browser_frame.cc
@@ -114,15 +114,23 @@ ui::ColorProviderKey::SchemeVariant GetSchemeVariant( @@ -114,15 +114,23 @@ ui::ColorProviderKey::SchemeVariant GetSchemeVariant(
@@ -260,7 +260,7 @@ index bb4b3821bcfda..9734fe4aaffcf 100644
} }
BrowserFrame::~BrowserFrame() {} BrowserFrame::~BrowserFrame() {}
@@ -228,6 +236,12 @@ void BrowserFrame::LayoutWebAppWindowTitle( @@ -228,10 +236,20 @@ void BrowserFrame::LayoutWebAppWindowTitle(
} }
int BrowserFrame::GetTopInset() const { int BrowserFrame::GetTopInset() const {
@@ -273,7 +273,15 @@ index bb4b3821bcfda..9734fe4aaffcf 100644
return browser_frame_view_->GetTopInset(false); 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 { bool BrowserFrame::UseCustomFrame() const {
@@ -282,7 +290,7 @@ index bb4b3821bcfda..9734fe4aaffcf 100644
return native_browser_frame_->UseCustomFrame(); 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, void BrowserFrame::GetWindowPlacement(gfx::Rect* bounds,
ui::WindowShowState* show_state) const { ui::WindowShowState* show_state) const {
@@ -313,7 +321,7 @@ index bb4b3821bcfda..9734fe4aaffcf 100644
browser_frame_view_->OnBrowserViewInitViewsComplete(); 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() { void BrowserFrame::OnNativeWidgetWorkspaceChanged() {
@@ -322,7 +330,7 @@ index bb4b3821bcfda..9734fe4aaffcf 100644
chrome::SaveWindowWorkspace(browser_view_->browser(), GetWorkspace()); chrome::SaveWindowWorkspace(browser_view_->browser(), GetWorkspace());
chrome::SaveWindowVisibleOnAllWorkspaces(browser_view_->browser(), chrome::SaveWindowVisibleOnAllWorkspaces(browser_view_->browser(),
IsVisibleOnAllWorkspaces()); 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 { ui::ColorProviderKey BrowserFrame::GetColorProviderKey() const {
auto key = Widget::GetColorProviderKey(); auto key = Widget::GetColorProviderKey();
@@ -331,7 +339,7 @@ index bb4b3821bcfda..9734fe4aaffcf 100644
key.app_controller = browser_view_->browser()->app_controller(); 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 { bool BrowserFrame::IsIncognitoBrowser() const {
@@ -711,7 +719,7 @@ index 8267a265a8e10..ee08f18e96a34 100644
ContentsWebView::~ContentsWebView() { 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 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
+++ 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( @@ -573,6 +573,11 @@ PictureInPictureBrowserFrameView::PictureInPictureBrowserFrameView(
@@ -726,7 +734,7 @@ index b9b50af047993..30793a69c4942 100644
} }
PictureInPictureBrowserFrameView::~PictureInPictureBrowserFrameView() { PictureInPictureBrowserFrameView::~PictureInPictureBrowserFrameView() {
@@ -669,17 +674,20 @@ gfx::Rect PictureInPictureBrowserFrameView::GetWindowBoundsForClientBounds( @@ -669,18 +674,42 @@ gfx::Rect PictureInPictureBrowserFrameView::GetWindowBoundsForClientBounds(
int PictureInPictureBrowserFrameView::NonClientHitTest( int PictureInPictureBrowserFrameView::NonClientHitTest(
const gfx::Point& point) { const gfx::Point& point) {
@@ -735,18 +743,14 @@ index b9b50af047993..30793a69c4942 100644
- GetBackToTabControlsBounds().Contains(point) || - GetBackToTabControlsBounds().Contains(point) ||
- GetCloseControlsBounds().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)) {
+ const bool frameless = !top_bar_container_view_->GetVisible(); + const bool frameless = !top_bar_container_view_->GetVisible();
+ if (!frameless) { + if (!frameless) {
+ // Allow interacting with the buttons. + // Allow interacting with the buttons.
+ if (GetLocationIconViewBounds().Contains(point) || + if (GetLocationIconViewBounds().Contains(point) ||
+ GetBackToTabControlsBounds().Contains(point) || + GetBackToTabControlsBounds().Contains(point) ||
+ GetCloseControlsBounds().Contains(point)) { + GetCloseControlsBounds().Contains(point)) {
return HTCLIENT; + return HTCLIENT;
} + }
+ +
+ for (size_t i = 0; i < content_setting_views_.size(); i++) { + for (size_t i = 0; i < content_setting_views_.size(); i++) {
+ if (GetContentSettingViewBounds(i).Contains(point)) { + if (GetContentSettingViewBounds(i).Contains(point)) {
@@ -755,11 +759,9 @@ index b9b50af047993..30793a69c4942 100644
+ } + }
} }
// Allow dragging and resizing the window. - for (size_t i = 0; i < content_setting_views_.size(); i++) {
@@ -689,6 +697,27 @@ int PictureInPictureBrowserFrameView::NonClientHitTest( - if (GetContentSettingViewBounds(i).Contains(point)) {
if (window_component != HTNOWHERE) - return HTCLIENT;
return window_component;
+#if BUILDFLAG(ENABLE_CEF) +#if BUILDFLAG(ENABLE_CEF)
+ if (frameless) { + if (frameless) {
+ // Match logic in BrowserView::ShouldDescendIntoChildForEventHandling. + // Match logic in BrowserView::ShouldDescendIntoChildForEventHandling.
@@ -777,13 +779,12 @@ index b9b50af047993..30793a69c4942 100644
+ point_in_contents_web_view_coords.y())) { + point_in_contents_web_view_coords.y())) {
+ return HTCAPTION; + return HTCAPTION;
+ } + }
+ } }
+ } }
+#endif // BUILDFLAG(ENABLE_CEF) +#endif // BUILDFLAG(ENABLE_CEF)
+
// Allow interacting with the web contents. // Allow dragging and resizing the window.
int frame_component = frame()->client_view()->NonClientHitTest(point); int window_component = GetHTComponentForFrame(
if (frame_component != HTNOWHERE)
@@ -747,7 +776,8 @@ void PictureInPictureBrowserFrameView::Layout() { @@ -747,7 +776,8 @@ void PictureInPictureBrowserFrameView::Layout() {
gfx::Rect content_area = GetLocalBounds(); gfx::Rect content_area = GetLocalBounds();
content_area.Inset(FrameBorderInsets()); content_area.Inset(FrameBorderInsets());

View File

@@ -12,10 +12,10 @@ index 34cacda8ef225..e0465b8ac1185 100644
version.Set("V8-Version", V8_VERSION_STRING); version.Set("V8-Version", V8_VERSION_STRING);
std::string host = info.GetHeaderValue("host"); std::string host = info.GetHeaderValue("host");
diff --git content/browser/loader/navigation_url_loader_impl.cc content/browser/loader/navigation_url_loader_impl.cc 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
+++ 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, resource_request_->has_user_gesture, initiating_origin,
initiator_document_.AsRenderFrameHostIfValid(), &loader_factory); initiator_document_.AsRenderFrameHostIfValid(), &loader_factory);
@@ -145,7 +145,7 @@ index 3c3ebfeec280e..b239506a39b43 100644
base::BindRepeating(&RenderThreadImpl::OnRendererInterfaceReceiver, base::BindRepeating(&RenderThreadImpl::OnRendererInterfaceReceiver,
base::Unretained(this))); base::Unretained(this)));
diff --git content/renderer/renderer_blink_platform_impl.cc content/renderer/renderer_blink_platform_impl.cc 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
+++ content/renderer/renderer_blink_platform_impl.cc +++ content/renderer/renderer_blink_platform_impl.cc
@@ -941,6 +941,15 @@ SkBitmap* RendererBlinkPlatformImpl::GetSadPageBitmap() { @@ -941,6 +941,15 @@ SkBitmap* RendererBlinkPlatformImpl::GetSadPageBitmap() {

View 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

View File

@@ -41,10 +41,10 @@ index afefe3cd83dee..6668463247644 100644
} // namespace content } // namespace content
diff --git content/browser/renderer_host/render_widget_host_impl.cc content/browser/renderer_host/render_widget_host_impl.cc 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
+++ 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); GetProcess(), bad_message::INPUT_ROUTER_INVALID_EVENT_SOURCE);
} }

View File

@@ -12,10 +12,10 @@ index 5cb6e6463767d..84a9de1dfc6f0 100644
RenderFrameHostImpl::FromFrameToken( RenderFrameHostImpl::FromFrameToken(
process_id, initiator_frame_token->value())) { 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 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
+++ 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 = auto browser_calc_origin_to_commit =
navigation_request->GetOriginToCommitWithDebugInfo(); navigation_request->GetOriginToCommitWithDebugInfo();
if (!process_lock.is_error_page() && !is_mhtml_subframe && if (!process_lock.is_error_page() && !is_mhtml_subframe &&

View File

@@ -21,7 +21,7 @@ index 0a6c1f498b8fc..79e0cf27a7715 100644
// If the corresponding Connector policy isn't set, don't perform scans. // If the corresponding Connector policy isn't set, don't perform scans.
if (!service || !service->IsConnectorEnabled(connector)) if (!service || !service->IsConnectorEnabled(connector))
diff --git chrome/browser/net/profile_network_context_service.cc chrome/browser/net/profile_network_context_service.cc 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
+++ chrome/browser/net/profile_network_context_service.cc +++ chrome/browser/net/profile_network_context_service.cc
@@ -22,6 +22,7 @@ @@ -22,6 +22,7 @@
@@ -45,7 +45,7 @@ index 1200475275e91..d32195f01c7ed 100644
DisableQuicIfNotAllowed(); DisableQuicIfNotAllowed();
@@ -480,6 +483,9 @@ void ProfileNetworkContextService::OnTruncatedCookieBlockingChanged() { @@ -490,6 +493,9 @@ void ProfileNetworkContextService::OnTruncatedCookieBlockingChanged() {
void ProfileNetworkContextService::OnFirstPartySetsEnabledChanged( void ProfileNetworkContextService::OnFirstPartySetsEnabledChanged(
bool enabled) { bool enabled) {
@@ -55,7 +55,7 @@ index 1200475275e91..d32195f01c7ed 100644
// Update all FPS Access Delegates on the FPS service to be `enabled`. // Update all FPS Access Delegates on the FPS service to be `enabled`.
first_party_sets::FirstPartySetsPolicyServiceFactory::GetForBrowserContext( first_party_sets::FirstPartySetsPolicyServiceFactory::GetForBrowserContext(
profile_) profile_)
@@ -866,9 +872,26 @@ void ProfileNetworkContextService::ConfigureNetworkContextParamsInternal( @@ -881,9 +887,26 @@ void ProfileNetworkContextService::ConfigureNetworkContextParamsInternal(
network_context_params->cookie_manager_params = network_context_params->cookie_manager_params =
CreateCookieManagerParams(profile_, *cookie_settings_); CreateCookieManagerParams(profile_, *cookie_settings_);
@@ -83,7 +83,7 @@ index 1200475275e91..d32195f01c7ed 100644
PrefService* local_state = g_browser_process->local_state(); PrefService* local_state = g_browser_process->local_state();
// Configure the HTTP cache path and size. // Configure the HTTP cache path and size.
base::FilePath base_cache_path; base::FilePath base_cache_path;
@@ -877,15 +900,14 @@ void ProfileNetworkContextService::ConfigureNetworkContextParamsInternal( @@ -892,15 +915,14 @@ void ProfileNetworkContextService::ConfigureNetworkContextParamsInternal(
local_state->GetFilePath(prefs::kDiskCacheDir); local_state->GetFilePath(prefs::kDiskCacheDir);
if (!disk_cache_dir.empty()) if (!disk_cache_dir.empty())
base_cache_path = disk_cache_dir.Append(base_cache_path.BaseName()); 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 = network_context_params->file_paths->data_directory =
path.Append(chrome::kNetworkDataDirname); path.Append(chrome::kNetworkDataDirname);
network_context_params->file_paths->unsandboxed_data_path = path; 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 = network_context_params->block_trust_tokens =
anti_abuse_content_setting == CONTENT_SETTING_BLOCK; 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_context_params->first_party_sets_access_delegate_params =
network::mojom::FirstPartySetsAccessDelegateParams::New(); network::mojom::FirstPartySetsAccessDelegateParams::New();
network_context_params->first_party_sets_access_delegate_params->enabled = 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_); GetForBrowserContext(profile_);
DCHECK(fps_service); DCHECK(fps_service);
fps_service->AddRemoteAccessDelegate(std::move(fps_access_delegate_remote)); fps_service->AddRemoteAccessDelegate(std::move(fps_access_delegate_remote));
@@ -223,7 +223,7 @@ index 61fd008fc067e..73909be088278 100644
// reset to null. // reset to null.
const CookieAccessDelegate* cookie_access_delegate() const { const CookieAccessDelegate* cookie_access_delegate() const {
diff --git services/network/cookie_manager.cc services/network/cookie_manager.cc 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
+++ services/network/cookie_manager.cc +++ services/network/cookie_manager.cc
@@ -297,14 +297,9 @@ void CookieManager::AllowFileSchemeCookies( @@ -297,14 +297,9 @@ void CookieManager::AllowFileSchemeCookies(

View File

@@ -414,7 +414,7 @@ index 2f552f72074e3..3f057242d198c 100644
} }
diff --git ui/views/widget/widget.h ui/views/widget/widget.h 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
+++ ui/views/widget/widget.h +++ ui/views/widget/widget.h
@@ -351,6 +351,8 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate, @@ -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 // Specifies the initial bounds of the Widget. Default is empty, which means
// the NativeWidget may specify a default size. If the parent is specified, // 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 // |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 diff --git ui/views/widget/widget_delegate.h ui/views/widget/widget_delegate.h
index 6d87be86ae8b3..02fe7a11958d0 100644 index 6d87be86ae8b3..02fe7a11958d0 100644
--- ui/views/widget/widget_delegate.h --- ui/views/widget/widget_delegate.h

View File

@@ -11,7 +11,7 @@ index 8a18ecf567cd3..9697d43bbbfb9 100644
// Cancels and hides the current popup (datetime, select...) if any. // Cancels and hides the current popup (datetime, select...) if any.
virtual void CancelPagePopup() = 0; 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 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
+++ 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) { @@ -249,8 +249,13 @@ void WebView::SetUseExternalPopupMenus(bool use_external_popup_menus) {

View 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

View 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_

View File

@@ -583,7 +583,7 @@ bool ClientHandler::OnChromeCommand(CefRefPtr<CefBrowser> browser,
} else if (!with_controls_) { } else if (!with_controls_) {
// If controls are hidden, block all commands that don't target the current // If controls are hidden, block all commands that don't target the current
// tab or aren't specifically allowed. // tab or aren't specifically allowed.
block = disposition != WOD_CURRENT_TAB || !allowed; block = disposition != CEF_WOD_CURRENT_TAB || !allowed;
} }
if (block) { if (block) {
@@ -644,11 +644,12 @@ void ClientHandler::OnBeforeContextMenu(CefRefPtr<CefBrowser> browser,
model->AddSeparator(); 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) { if (!use_chrome_runtime) {
// TODO(chrome-runtime): Add support for this. // Chrome runtime already gives us an "Inspect" menu item.
// Add DevTools items to all context menus.
model->AddItem(CLIENT_ID_SHOW_DEVTOOLS, "&Show DevTools");
model->AddItem(CLIENT_ID_CLOSE_DEVTOOLS, "Close DevTools");
model->AddSeparator(); model->AddSeparator();
model->AddItem(CLIENT_ID_INSPECT_ELEMENT, "Inspect Element"); model->AddItem(CLIENT_ID_INSPECT_ELEMENT, "Inspect Element");
} }
@@ -938,15 +939,36 @@ bool ClientHandler::OnBeforePopup(
bool* no_javascript_access) { bool* no_javascript_access) {
CEF_REQUIRE_UI_THREAD(); 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. // Use default handling for document picture-in-picture popups.
client = nullptr; client = nullptr;
return false; return false;
} }
// Return true to cancel the popup window. // Potentially create a new RootWindow for the popup browser that will be
return !CreatePopupWindow(browser, false, popupFeatures, windowInfo, client, // created asynchronously.
settings); 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) { void ClientHandler::OnAfterCreated(CefRefPtr<CefBrowser> browser) {
@@ -1081,8 +1103,8 @@ bool ClientHandler::OnOpenURLFromTab(
const CefString& target_url, const CefString& target_url,
CefRequestHandler::WindowOpenDisposition target_disposition, CefRequestHandler::WindowOpenDisposition target_disposition,
bool user_gesture) { bool user_gesture) {
if (target_disposition == WOD_NEW_BACKGROUND_TAB || if (target_disposition == CEF_WOD_NEW_BACKGROUND_TAB ||
target_disposition == WOD_NEW_FOREGROUND_TAB) { target_disposition == CEF_WOD_NEW_FOREGROUND_TAB) {
// Handle middle-click and ctrl + left-click by opening the URL in a new // Handle middle-click and ctrl + left-click by opening the URL in a new
// browser window. // browser window.
auto config = std::make_unique<RootWindowConfig>(); auto config = std::make_unique<RootWindowConfig>();
@@ -1303,25 +1325,21 @@ void ClientHandler::ShowDevTools(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefClient> client; CefRefPtr<CefClient> client;
CefBrowserSettings settings; CefBrowserSettings settings;
MainContext::Get()->PopulateBrowserSettings(&settings);
CefRefPtr<CefBrowserHost> host = browser->GetHost(); CefRefPtr<CefBrowserHost> host = browser->GetHost();
// Test if the DevTools browser already exists. // Test if the DevTools browser already exists.
bool has_devtools = host->HasDevTools(); if (!MainContext::Get()->UseChromeRuntime() && !host->HasDevTools()) {
if (!has_devtools) { // Potentially create a new RootWindow for the DevTools browser that will be
// Create a new RootWindow for the DevTools browser that will be created // created by ShowDevTools(). For Chrome runtime this occurs in
// by ShowDevTools(). // OnBeforeDevToolsPopup instead.
has_devtools = CreatePopupWindow(browser, true, CefPopupFeatures(), CreatePopupWindow(browser, /*is_devtools=*/true, CefPopupFeatures(),
windowInfo, client, settings); windowInfo, client, settings);
} }
if (has_devtools) { // Create the DevTools browser if it doesn't already exist.
// Create the DevTools browser if it doesn't already exist. // Otherwise, focus the existing DevTools browser and inspect the element
// Otherwise, focus the existing DevTools browser and inspect the element // at |inspect_element_at| if non-empty.
// at |inspect_element_at| if non-empty. host->ShowDevTools(windowInfo, client, settings, inspect_element_at);
host->ShowDevTools(windowInfo, client, settings, inspect_element_at);
}
} }
void ClientHandler::CloseDevTools(CefRefPtr<CefBrowser> browser) { 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. // The popup browser will be parented to a new native window.
// Don't show URL bar and navigation buttons on DevTools windows. // 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, with_controls_ && !is_devtools, is_osr_, popupFeatures, windowInfo,
client, settings); client, settings);
return true;
} }
void ClientHandler::NotifyBrowserCreated(CefRefPtr<CefBrowser> browser) { void ClientHandler::NotifyBrowserCreated(CefRefPtr<CefBrowser> browser) {

View File

@@ -224,6 +224,12 @@ class ClientHandler : public CefClient,
CefBrowserSettings& settings, CefBrowserSettings& settings,
CefRefPtr<CefDictionaryValue>& extra_info, CefRefPtr<CefDictionaryValue>& extra_info,
bool* no_javascript_access) override; 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; void OnAfterCreated(CefRefPtr<CefBrowser> browser) override;
bool DoClose(CefRefPtr<CefBrowser> browser) override; bool DoClose(CefRefPtr<CefBrowser> browser) override;
void OnBeforeClose(CefRefPtr<CefBrowser> browser) override; void OnBeforeClose(CefRefPtr<CefBrowser> browser) override;
@@ -348,9 +354,8 @@ class ClientHandler : public CefClient,
friend class ClientDownloadImageCallback; friend class ClientDownloadImageCallback;
// Create a new popup window using the specified information. |is_devtools| // 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 // will be true if the window will be used for DevTools. Returns true if a
// proceed with popup browser creation or false to cancel the popup browser. // RootWindow was created for the popup.
// May be called on any thead.
bool CreatePopupWindow(CefRefPtr<CefBrowser> browser, bool CreatePopupWindow(CefRefPtr<CefBrowser> browser,
bool is_devtools, bool is_devtools,
const CefPopupFeatures& popupFeatures, const CefPopupFeatures& popupFeatures,

View File

@@ -42,6 +42,10 @@ class MainContext {
// Returns true if the Chrome runtime will be used. // Returns true if the Chrome runtime will be used.
virtual bool UseChromeRuntime() = 0; 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. // Returns true if the Views framework will be used.
virtual bool UseViews() = 0; virtual bool UseViews() = 0;

View File

@@ -111,8 +111,9 @@ MainContextImpl::MainContextImpl(CefRefPtr<CefCommandLine> command_line,
} }
#if defined(OS_WIN) || defined(OS_LINUX) #if defined(OS_WIN) || defined(OS_LINUX)
if (use_chrome_runtime_ && !use_views_ && use_chrome_runtime_native_ =
!command_line->HasSwitch(switches::kUseNative)) { 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."; LOG(WARNING) << "Chrome runtime defaults to the Views framework.";
use_views_ = true; use_views_ = true;
} }
@@ -174,6 +175,10 @@ bool MainContextImpl::UseChromeRuntime() {
return use_chrome_runtime_; return use_chrome_runtime_;
} }
bool MainContextImpl::UseChromeRuntimeNative() {
return use_chrome_runtime_native_;
}
bool MainContextImpl::UseViews() { bool MainContextImpl::UseViews() {
return use_views_; return use_views_;
} }

View File

@@ -29,6 +29,7 @@ class MainContextImpl : public MainContext {
std::string GetMainURL() override; std::string GetMainURL() override;
cef_color_t GetBackgroundColor() override; cef_color_t GetBackgroundColor() override;
bool UseChromeRuntime() override; bool UseChromeRuntime() override;
bool UseChromeRuntimeNative() override;
bool UseViews() override; bool UseViews() override;
bool UseWindowlessRendering() override; bool UseWindowlessRendering() override;
bool TouchEventsEnabled() override; bool TouchEventsEnabled() override;
@@ -74,6 +75,7 @@ class MainContextImpl : public MainContext {
bool use_windowless_rendering_; bool use_windowless_rendering_;
int windowless_frame_rate_ = 0; int windowless_frame_rate_ = 0;
bool use_chrome_runtime_; bool use_chrome_runtime_;
bool use_chrome_runtime_native_ = false;
bool use_views_; bool use_views_;
std::unique_ptr<RootWindowManager> root_window_manager_; std::unique_ptr<RootWindowManager> root_window_manager_;

View File

@@ -44,31 +44,32 @@
#define ID_TESTS_UNMUTE_AUDIO 32717 #define ID_TESTS_UNMUTE_AUDIO 32717
#define ID_TESTS_LAST 32717 #define ID_TESTS_LAST 32717
#define IDC_STATIC -1 #define IDC_STATIC -1
#define IDS_BINDING_HTML 1000 #define IDS_BINARY_TRANSFER_HTML 1000
#define IDS_DIALOGS_HTML 1001 #define IDS_BINDING_HTML 1001
#define IDS_DRAGGABLE_HTML 1002 #define IDS_DIALOGS_HTML 1002
#define IDS_IPC_PERFORMANCE_HTML 1003 #define IDS_DRAGGABLE_HTML 1003
#define IDS_LOCALSTORAGE_HTML 1004 #define IDS_IPC_PERFORMANCE_HTML 1004
#define IDS_LOGO_PNG 1005 #define IDS_LOCALSTORAGE_HTML 1005
#define IDS_MEDIA_ROUTER_HTML 1006 #define IDS_LOGO_PNG 1006
#define IDS_MENU_ICON_1X_PNG 1007 #define IDS_MEDIA_ROUTER_HTML 1007
#define IDS_MENU_ICON_2X_PNG 1008 #define IDS_MENU_ICON_1X_PNG 1008
#define IDS_OSRTEST_HTML 1009 #define IDS_MENU_ICON_2X_PNG 1009
#define IDS_OTHER_TESTS_HTML 1010 #define IDS_OSRTEST_HTML 1010
#define IDS_PDF_HTML 1011 #define IDS_OTHER_TESTS_HTML 1011
#define IDS_PDF_PDF 1012 #define IDS_PDF_HTML 1012
#define IDS_PERFORMANCE_HTML 1013 #define IDS_PDF_PDF 1013
#define IDS_PERFORMANCE2_HTML 1014 #define IDS_PERFORMANCE_HTML 1014
#define IDS_PREFERENCES_HTML 1015 #define IDS_PERFORMANCE2_HTML 1015
#define IDS_RESPONSE_FILTER_HTML 1016 #define IDS_PREFERENCES_HTML 1016
#define IDS_SERVER_HTML 1017 #define IDS_RESPONSE_FILTER_HTML 1017
#define IDS_TRANSPARENCY_HTML 1018 #define IDS_SERVER_HTML 1018
#define IDS_URLREQUEST_HTML 1019 #define IDS_TRANSPARENCY_HTML 1019
#define IDS_WEBSOCKET_HTML 1020 #define IDS_URLREQUEST_HTML 1020
#define IDS_WINDOW_HTML 1021 #define IDS_WEBSOCKET_HTML 1021
#define IDS_WINDOW_ICON_1X_PNG 1022 #define IDS_WINDOW_HTML 1022
#define IDS_WINDOW_ICON_2X_PNG 1023 #define IDS_WINDOW_ICON_1X_PNG 1023
#define IDS_XMLHTTPREQUEST_HTML 1024 #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_ICON_PNG 1030
#define IDS_EXTENSIONS_SET_PAGE_COLOR_MANIFEST_JSON 1031 #define IDS_EXTENSIONS_SET_PAGE_COLOR_MANIFEST_JSON 1031

View File

@@ -13,7 +13,8 @@ int GetResourceId(const char* resource_name) {
static struct _resource_map { static struct _resource_map {
const char* name; const char* name;
int id; 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}, {"dialogs.html", IDS_DIALOGS_HTML},
{"draggable.html", IDS_DRAGGABLE_HTML}, {"draggable.html", IDS_DRAGGABLE_HTML},
{"extensions/set_page_color/icon.png", {"extensions/set_page_color/icon.png",

View File

@@ -28,6 +28,9 @@ enum class WindowType {
// The window is a modal dialog. // The window is a modal dialog.
DIALOG, DIALOG,
// The window is a DevTools popup.
DEVTOOLS,
}; };
// Used to configure how a RootWindow is created. // Used to configure how a RootWindow is created.

View File

@@ -249,7 +249,7 @@ void RootWindowViews::OnViewsWindowClosing(CefRefPtr<ViewsWindow> window) {
CEF_REQUIRE_UI_THREAD(); CEF_REQUIRE_UI_THREAD();
DCHECK(window_); DCHECK(window_);
if (config_->window_type != WindowType::NORMAL) { if (!window_->SupportsWindowRestore()) {
return; return;
} }
@@ -516,7 +516,7 @@ void RootWindowViews::InitOnUIThread(
// Initial state was specified via the config object. // Initial state was specified via the config object.
initial_bounds_ = config_->bounds; initial_bounds_ = config_->bounds;
initial_show_state_ = config_->show_state; 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 // Initial state may be specified via the command-line or global
// preferences. // preferences.
std::optional<CefRect> bounds; std::optional<CefRect> bounds;

View File

@@ -16,6 +16,7 @@
#include "include/views/cef_browser_view.h" #include "include/views/cef_browser_view.h"
#include "include/wrapper/cef_closure_task.h" #include "include/wrapper/cef_closure_task.h"
#include "include/wrapper/cef_stream_resource_handler.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/binding_test.h"
#include "tests/cefclient/browser/client_handler.h" #include "tests/cefclient/browser/client_handler.h"
#include "tests/cefclient/browser/dialog_test.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) { void CreateMessageHandlers(MessageHandlerSet& handlers) {
handlers.insert(new PromptHandler); handlers.insert(new PromptHandler);
// Create the binary trasfer test handlers.
binary_transfer_test::CreateMessageHandlers(handlers);
// Create the binding test handlers. // Create the binding test handlers.
binding_test::CreateMessageHandlers(handlers); binding_test::CreateMessageHandlers(handlers);

View File

@@ -399,10 +399,21 @@ void ViewsWindow::OnExtensionsChanged(const ExtensionSet& extensions) {
base::BindOnce(&ViewsWindow::OnExtensionIconsLoaded, this, 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( bool ViewsWindow::GetWindowRestorePreferences(
cef_show_state_t& show_state, cef_show_state_t& show_state,
std::optional<CefRect>& dip_bounds) { std::optional<CefRect>& dip_bounds) {
CEF_REQUIRE_UI_THREAD(); CEF_REQUIRE_UI_THREAD();
DCHECK(SupportsWindowRestore());
if (!window_) { if (!window_) {
return false; return false;
} }
@@ -460,7 +471,9 @@ CefRefPtr<CefBrowserViewDelegate> ViewsWindow::GetDelegateForPopupBrowserView(
DCHECK(popup_delegate != delegate_); DCHECK(popup_delegate != delegate_);
// Create a new ViewsWindow for the popup BrowserView. // 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( bool ViewsWindow::OnPopupBrowserViewCreated(
@@ -651,6 +664,18 @@ void ViewsWindow::OnWindowFullscreenTransition(CefRefPtr<CefWindow> window,
if (should_change && with_controls_) { if (should_change && with_controls_) {
ShowTopControls(!window->IsFullscreen()); 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) { void ViewsWindow::OnWindowCreated(CefRefPtr<CefWindow> window) {
@@ -664,12 +689,12 @@ void ViewsWindow::OnWindowCreated(CefRefPtr<CefWindow> window) {
delegate_->OnViewsWindowCreated(this); delegate_->OnViewsWindowCreated(this);
if (type_ == WindowType::NORMAL) { if (type_ == WindowType::NORMAL || type_ == WindowType::DEVTOOLS) {
const CefRect bounds = delegate_->GetInitialBounds(); const CefRect bounds = delegate_->GetInitialBounds();
if (bounds.IsEmpty()) { if (bounds.IsEmpty()) {
// Size the Window and center it at the default size. // Size the Window and center it at the default size.
window_->CenterWindow(CefSize(kDefaultWidth, kDefaultHeight)); window_->CenterWindow(CefSize(kDefaultWidth, kDefaultHeight));
} else { } else if (SupportsWindowRestore()) {
// Remember the bounds from the previous application run in case the user // Remember the bounds from the previous application run in case the user
// does not move or resize the window during this application run. // does not move or resize the window during this application run.
last_visible_bounds_ = bounds; last_visible_bounds_ = bounds;
@@ -746,7 +771,7 @@ void ViewsWindow::OnWindowActivationChanged(CefRefPtr<CefWindow> window,
void ViewsWindow::OnWindowBoundsChanged(CefRefPtr<CefWindow> window, void ViewsWindow::OnWindowBoundsChanged(CefRefPtr<CefWindow> window,
const CefRect& new_bounds) { const CefRect& new_bounds) {
if (type_ == WindowType::NORMAL && !window->IsMinimized() && if (SupportsWindowRestore() && !window->IsMinimized() &&
!window->IsMaximized() && !window->IsFullscreen()) { !window->IsMaximized() && !window->IsFullscreen()) {
// Track the last visible bounds for window restore purposes. // Track the last visible bounds for window restore purposes.
last_visible_bounds_ = new_bounds; last_visible_bounds_ = new_bounds;
@@ -833,20 +858,18 @@ bool ViewsWindow::GetTitlebarHeight(CefRefPtr<CefWindow> window,
bool ViewsWindow::CanResize(CefRefPtr<CefWindow> window) { bool ViewsWindow::CanResize(CefRefPtr<CefWindow> window) {
CEF_REQUIRE_UI_THREAD(); CEF_REQUIRE_UI_THREAD();
// Only allow resize of normal windows. // Only allow resize of normal and DevTools windows.
return type_ == WindowType::NORMAL; return type_ == WindowType::NORMAL || type_ == WindowType::DEVTOOLS;
} }
bool ViewsWindow::CanMaximize(CefRefPtr<CefWindow> window) { bool ViewsWindow::CanMaximize(CefRefPtr<CefWindow> window) {
CEF_REQUIRE_UI_THREAD(); CEF_REQUIRE_UI_THREAD();
// Only allow maximize of normal windows. return CanResize(window);
return type_ == WindowType::NORMAL;
} }
bool ViewsWindow::CanMinimize(CefRefPtr<CefWindow> window) { bool ViewsWindow::CanMinimize(CefRefPtr<CefWindow> window) {
CEF_REQUIRE_UI_THREAD(); CEF_REQUIRE_UI_THREAD();
// Only allow minimize of normal windows. return CanResize(window);
return type_ == WindowType::NORMAL;
} }
bool ViewsWindow::OnAccelerator(CefRefPtr<CefWindow> window, int command_id) { bool ViewsWindow::OnAccelerator(CefRefPtr<CefWindow> window, int command_id) {
@@ -1271,12 +1294,11 @@ void ViewsWindow::AddControls() {
} }
void ViewsWindow::AddAccelerators() { 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 // Specify the accelerators to handle. OnAccelerator will be called when the
// accelerator is triggered. // 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) { void ViewsWindow::SetMenuFocusable(bool focusable) {

View File

@@ -127,6 +127,8 @@ class ViewsWindow : public CefBrowserViewDelegate,
void OnBeforeContextMenu(CefRefPtr<CefMenuModel> model); void OnBeforeContextMenu(CefRefPtr<CefMenuModel> model);
void OnExtensionsChanged(const ExtensionSet& extensions); void OnExtensionsChanged(const ExtensionSet& extensions);
static bool SupportsWindowRestore(WindowType type);
bool SupportsWindowRestore() const;
bool GetWindowRestorePreferences(cef_show_state_t& show_state, bool GetWindowRestorePreferences(cef_show_state_t& show_state,
std::optional<CefRect>& dip_bounds); std::optional<CefRect>& dip_bounds);
void SetTitlebarHeight(const std::optional<float>& height); void SetTitlebarHeight(const std::optional<float>& height);

View 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,&nbsp;ms
</td>
<td class="center" style="width: 8%">
Binary Round Trip Avg,&nbsp;ms
</td>
<td class="center" style="width: 10%">Relative Trip Difference</td>
<td class="center" style="width: 8%">String Speed,&nbsp;MB/s</td>
<td class="center" style="width: 8%">Binary Speed,&nbsp;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>

View File

@@ -9,6 +9,7 @@
<li><a href="http://webkit.org/blog-files/3d-transforms/poster-circle.html">Accelerated Layers</a></li> <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/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="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="http://html5advent2011.digitpaint.nl/3/index.html">Cursors</a></li>
<li><a href="dialogs">Dialogs</a></li> <li><a href="dialogs">Dialogs</a></li>
<li><a href="http://html5demos.com/drag">Drag & Drop</a></li> <li><a href="http://html5demos.com/drag">Drag & Drop</a></li>

View File

@@ -29,6 +29,7 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
// Binary // Binary
// //
IDS_BINARY_TRANSFER_HTML BINARY "..\\binary_transfer.html"
IDS_BINDING_HTML BINARY "..\\binding.html" IDS_BINDING_HTML BINARY "..\\binding.html"
IDS_DIALOGS_HTML BINARY "..\\dialogs.html" IDS_DIALOGS_HTML BINARY "..\\dialogs.html"
IDS_DRAGGABLE_HTML BINARY "..\\draggable.html" IDS_DRAGGABLE_HTML BINARY "..\\draggable.html"
@@ -228,4 +229,3 @@ END
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED #endif // not APSTUDIO_INVOKED

View File

@@ -2,6 +2,12 @@
<html lang="en-US"> <html lang="en-US">
<head> <head>
<title>Window Test</title> <title>Window Test</title>
<style>
/* Background becomes pink in fullscreen mode. */
:fullscreen {
background: pink;
}
</style>
<script> <script>
function setup() { function setup() {
if (location.hostname == 'tests' || location.hostname == 'localhost') if (location.hostname == 'tests' || location.hostname == 'localhost')
@@ -38,10 +44,18 @@ function restore() {
setTimeout(function() { send_message('Restore'); }, 1000); setTimeout(function() { send_message('Restore'); }, 1000);
} }
function fullscreen() { function fullscreenWindow() {
send_message('Fullscreen'); send_message('Fullscreen');
} }
function fullscreenBrowser() {
if (document.fullscreenElement) {
document.exitFullscreen();
} else {
document.getElementById('form').requestFullscreen();
}
}
function position() { function position() {
var x = parseInt(document.getElementById('x').value); var x = parseInt(document.getElementById('x').value);
var y = parseInt(document.getElementById('y').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="minimize();" value="Minimize">
<br/><input type="button" onclick="maximize();" value="Maximize"> <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="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"> <br/><input type="button" onclick="position();" value="Set Position">
X: <input type="text" size="4" id="x" value="200"> X: <input type="text" size="4" id="x" value="200">
Y: <input type="text" size="4" id="y" value="100"> Y: <input type="text" size="4" id="y" value="100">

View 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