From ebee84755ed14e71388b343231d3a419f1c5c1fd Mon Sep 17 00:00:00 2001 From: Marshall Greenblatt Date: Fri, 14 May 2021 12:58:55 -0400 Subject: [PATCH] Convert legacy IPC messages to Mojo (fixes issue #3123) This change introduces a few minor CEF API behavior changes: - A CefProcessMessage object cannot be reused after being passed to SendProcessMessage. - The |extra_info| argument to CefRenderProcessHandler::OnBrowserCreated may now be NULL. Where appropriate, we now utilize the default UTF string encoding format and shared memory to reduce copies and conversions for the cross-process transfer of arbitrary-length strings. For example, CefFrame::GetSource/GetText now involves zero UTF conversions and zero copies in the browser process for the CefString delivered to CefStringVisitor::Visit(). --- BUILD.gn | 29 +- include/capi/cef_frame_capi.h | 12 +- .../capi/cef_render_process_handler_capi.h | 4 +- include/cef_frame.h | 10 +- include/cef_render_process_handler.h | 4 +- include/internal/cef_string_wrappers.h | 179 +++++-- .../browser/alloy/alloy_browser_host_impl.cc | 1 - .../alloy/alloy_content_browser_client.cc | 13 +- libcef/browser/browser_contents_delegate.cc | 12 - libcef/browser/browser_contents_delegate.h | 2 - libcef/browser/browser_frame.cc | 71 +++ libcef/browser/browser_frame.h | 50 ++ libcef/browser/browser_host_base.cc | 4 +- libcef/browser/browser_info_manager.cc | 85 ++-- libcef/browser/browser_info_manager.h | 32 +- libcef/browser/browser_manager.cc | 56 +++ libcef/browser/browser_manager.h | 54 ++ libcef/browser/browser_message_filter.cc | 55 --- libcef/browser/browser_message_filter.h | 40 -- .../chrome_content_browser_client_cef.cc | 29 +- .../chrome_content_browser_client_cef.h | 7 + libcef/browser/download_manager_delegate.cc | 4 +- .../extensions/extension_function_details.cc | 1 - libcef/browser/frame_host_impl.cc | 463 +++++++----------- libcef/browser/frame_host_impl.h | 69 ++- libcef/browser/menu_manager.cc | 4 +- libcef/browser/navigate_params.cc | 12 - libcef/browser/navigate_params.h | 81 --- libcef/browser/origin_whitelist_impl.cc | 155 +++--- libcef/browser/origin_whitelist_impl.h | 10 +- libcef/browser/print_settings_impl.cc | 15 +- libcef/browser/print_settings_impl.h | 2 - libcef/browser/printing/print_view_manager.h | 2 - libcef/common/alloy/alloy_main_delegate.cc | 11 +- libcef/common/cef_message_generator.cc | 33 -- libcef/common/cef_message_generator.h | 7 - libcef/common/cef_messages.cc | 119 ----- libcef/common/cef_messages.h | 209 -------- .../common/chrome/chrome_main_delegate_cef.cc | 2 +- libcef/common/mojom/BUILD.gn | 29 ++ libcef/common/mojom/cef.mojom | 129 +++++ libcef/common/net/upload_data.cc | 35 -- libcef/common/net/upload_data.h | 83 ---- libcef/common/net/upload_element.cc | 21 - libcef/common/net/upload_element.h | 113 ----- libcef/common/process_message_impl.cc | 79 +-- libcef/common/process_message_impl.h | 37 +- libcef/common/request_impl.cc | 279 ++--------- libcef/common/request_impl.h | 22 +- libcef/common/response_manager.cc | 59 --- libcef/common/response_manager.h | 66 --- libcef/common/string_util.cc | 72 +++ libcef/common/string_util.h | 44 ++ libcef/common/value_base.h | 5 +- libcef/common/values_impl.h | 15 +- .../alloy/alloy_content_renderer_client.cc | 39 +- .../alloy/alloy_content_renderer_client.h | 8 +- .../alloy/alloy_render_frame_observer.cc | 23 - .../alloy/alloy_render_frame_observer.h | 38 -- .../alloy/alloy_render_thread_observer.h | 4 +- libcef/renderer/blink_glue.cc | 11 +- libcef/renderer/blink_glue.h | 4 +- libcef/renderer/browser_impl.cc | 9 +- .../chrome_content_renderer_client_cef.cc | 30 +- .../chrome_content_renderer_client_cef.h | 7 +- libcef/renderer/frame_impl.cc | 335 +++++-------- libcef/renderer/frame_impl.h | 64 +-- libcef/renderer/render_frame_observer.cc | 17 +- libcef/renderer/render_frame_observer.h | 22 +- .../{browser_manager.cc => render_manager.cc} | 153 ++++-- .../{browser_manager.h => render_manager.h} | 46 +- libcef/renderer/render_thread_observer.cc | 52 -- libcef/renderer/render_thread_observer.h | 35 -- .../cpptoc/render_process_handler_cpptoc.cc | 7 +- .../ctocpp/render_process_handler_ctocpp.cc | 7 +- patch/patch.cfg | 5 + patch/patches/content_mojo_3123.patch | 23 + tests/ceftests/frame_unittest.cc | 2 +- tests/ceftests/navigation_unittest.cc | 8 +- tests/ceftests/process_message_unittest.cc | 10 +- tests/ceftests/request_handler_unittest.cc | 2 +- tests/ceftests/v8_unittest.cc | 2 +- 82 files changed, 1614 insertions(+), 2385 deletions(-) create mode 100644 libcef/browser/browser_frame.cc create mode 100644 libcef/browser/browser_frame.h create mode 100644 libcef/browser/browser_manager.cc create mode 100644 libcef/browser/browser_manager.h delete mode 100644 libcef/browser/browser_message_filter.cc delete mode 100644 libcef/browser/browser_message_filter.h delete mode 100644 libcef/browser/navigate_params.cc delete mode 100644 libcef/browser/navigate_params.h delete mode 100644 libcef/common/cef_message_generator.cc delete mode 100644 libcef/common/cef_message_generator.h delete mode 100644 libcef/common/cef_messages.cc delete mode 100644 libcef/common/cef_messages.h create mode 100644 libcef/common/mojom/BUILD.gn create mode 100644 libcef/common/mojom/cef.mojom delete mode 100644 libcef/common/net/upload_data.cc delete mode 100644 libcef/common/net/upload_data.h delete mode 100644 libcef/common/net/upload_element.cc delete mode 100644 libcef/common/net/upload_element.h delete mode 100644 libcef/common/response_manager.cc delete mode 100644 libcef/common/response_manager.h create mode 100644 libcef/common/string_util.cc create mode 100644 libcef/common/string_util.h delete mode 100644 libcef/renderer/alloy/alloy_render_frame_observer.cc delete mode 100644 libcef/renderer/alloy/alloy_render_frame_observer.h rename libcef/renderer/{browser_manager.cc => render_manager.cc} (65%) rename libcef/renderer/{browser_manager.h => render_manager.h} (67%) delete mode 100644 libcef/renderer/render_thread_observer.cc delete mode 100644 libcef/renderer/render_thread_observer.h create mode 100644 patch/patches/content_mojo_3123.patch diff --git a/BUILD.gn b/BUILD.gn index 351b20505..85b6e4948 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -431,6 +431,8 @@ static_library("libcef_static") { "libcef/browser/browser_context.h", "libcef/browser/browser_context_keyed_service_factories.cc", "libcef/browser/browser_context_keyed_service_factories.h", + "libcef/browser/browser_frame.cc", + "libcef/browser/browser_frame.h", "libcef/browser/browser_host_base.cc", "libcef/browser/browser_host_base.h", "libcef/browser/browser_host_create.cc", @@ -438,8 +440,8 @@ static_library("libcef_static") { "libcef/browser/browser_info.h", "libcef/browser/browser_info_manager.cc", "libcef/browser/browser_info_manager.h", - "libcef/browser/browser_message_filter.cc", - "libcef/browser/browser_message_filter.h", + "libcef/browser/browser_manager.cc", + "libcef/browser/browser_manager.h", "libcef/browser/browser_message_loop.cc", "libcef/browser/browser_message_loop.h", "libcef/browser/browser_platform_delegate.cc", @@ -560,8 +562,6 @@ static_library("libcef_static") { "libcef/browser/native/browser_platform_delegate_native.h", "libcef/browser/native/cursor_util.h", "libcef/browser/native/cursor_util.cc", - "libcef/browser/navigate_params.cc", - "libcef/browser/navigate_params.h", "libcef/browser/navigation_entry_impl.cc", "libcef/browser/navigation_entry_impl.h", "libcef/browser/net/chrome_scheme_handler.cc", @@ -675,10 +675,6 @@ static_library("libcef_static") { "libcef/common/app_manager.cc", "libcef/common/app_manager.h", "libcef/common/base_impl.cc", - "libcef/common/cef_message_generator.cc", - "libcef/common/cef_message_generator.h", - "libcef/common/cef_messages.cc", - "libcef/common/cef_messages.h", "libcef/common/cef_switches.cc", "libcef/common/cef_switches.h", "libcef/common/chrome/chrome_content_client_cef.cc", @@ -715,10 +711,6 @@ static_library("libcef_static") { "libcef/common/net/net_resource_provider.h", "libcef/common/net/scheme_registration.cc", "libcef/common/net/scheme_registration.h", - "libcef/common/net/upload_data.cc", - "libcef/common/net/upload_data.h", - "libcef/common/net/upload_element.cc", - "libcef/common/net/upload_element.h", "libcef/common/net/url_util.cc", "libcef/common/net/url_util.h", "libcef/common/net_service/net_service_util.cc", @@ -736,14 +728,14 @@ static_library("libcef_static") { "libcef/common/resource_util.h", "libcef/common/response_impl.cc", "libcef/common/response_impl.h", - "libcef/common/response_manager.cc", - "libcef/common/response_manager.h", "libcef/common/scheme_registrar_impl.cc", "libcef/common/scheme_registrar_impl.h", "libcef/common/string_list_impl.cc", "libcef/common/string_map_impl.cc", "libcef/common/string_multimap_impl.cc", "libcef/common/string_types_impl.cc", + "libcef/common/string_util.cc", + "libcef/common/string_util.h", "libcef/common/task_impl.cc", "libcef/common/task_runner_impl.cc", "libcef/common/task_runner_impl.h", @@ -769,16 +761,12 @@ static_library("libcef_static") { "libcef/features/runtime_checks.h", "libcef/renderer/alloy/alloy_content_renderer_client.cc", "libcef/renderer/alloy/alloy_content_renderer_client.h", - "libcef/renderer/alloy/alloy_render_frame_observer.cc", - "libcef/renderer/alloy/alloy_render_frame_observer.h", "libcef/renderer/alloy/alloy_render_thread_observer.cc", "libcef/renderer/alloy/alloy_render_thread_observer.h", "libcef/renderer/alloy/url_loader_throttle_provider_impl.cc", "libcef/renderer/alloy/url_loader_throttle_provider_impl.h", "libcef/renderer/browser_impl.cc", "libcef/renderer/browser_impl.h", - "libcef/renderer/browser_manager.cc", - "libcef/renderer/browser_manager.h", "libcef/renderer/chrome/chrome_content_renderer_client_cef.cc", "libcef/renderer/chrome/chrome_content_renderer_client_cef.h", "libcef/renderer/dom_document_impl.cc", @@ -797,8 +785,8 @@ static_library("libcef_static") { "libcef/renderer/render_frame_observer.h", "libcef/renderer/render_frame_util.cc", "libcef/renderer/render_frame_util.h", - "libcef/renderer/render_thread_observer.cc", - "libcef/renderer/render_thread_observer.h", + "libcef/renderer/render_manager.cc", + "libcef/renderer/render_manager.h", "libcef/renderer/render_urlrequest_impl.cc", "libcef/renderer/render_urlrequest_impl.h", "libcef/renderer/thread_util.h", @@ -834,6 +822,7 @@ static_library("libcef_static") { deps = [ ":cef_make_headers", + "libcef/common/mojom", ":libcef_static_unittested", diff --git a/include/capi/cef_frame_capi.h b/include/capi/cef_frame_capi.h index 7a6f6046c..18c1fd959 100644 --- a/include/capi/cef_frame_capi.h +++ b/include/capi/cef_frame_capi.h @@ -33,7 +33,7 @@ // by hand. See the translator.README.txt file in the tools directory for // more information. // -// $hash=bce865a34f45e6dee8f413f0d6bd7f4c37ab55c0$ +// $hash=872fd1e811d41f56f03da0da75a8f2e89cad40cd$ // #ifndef CEF_INCLUDE_CAPI_CEF_FRAME_CAPI_H_ @@ -242,10 +242,12 @@ typedef struct _cef_frame_t { struct _cef_urlrequest_client_t* client); /// - // Send a message to the specified |target_process|. Message delivery is not - // guaranteed in all cases (for example, if the browser is closing, - // navigating, or if the target process crashes). Send an ACK message back - // from the target process if confirmation is required. + // Send a message to the specified |target_process|. Ownership of the message + // contents will be transferred and the |message| reference will be + // invalidated. Message delivery is not guaranteed in all cases (for example, + // if the browser is closing, navigating, or if the target process crashes). + // Send an ACK message back from the target process if confirmation is + // required. /// void(CEF_CALLBACK* send_process_message)( struct _cef_frame_t* self, diff --git a/include/capi/cef_render_process_handler_capi.h b/include/capi/cef_render_process_handler_capi.h index 5359e9df7..d33ef9c44 100644 --- a/include/capi/cef_render_process_handler_capi.h +++ b/include/capi/cef_render_process_handler_capi.h @@ -33,7 +33,7 @@ // by hand. See the translator.README.txt file in the tools directory for // more information. // -// $hash=41339414bca54054046a8f7fbce402a0e0dd8020$ +// $hash=131544be2c5e916381f80854451538ad64a687a2$ // #ifndef CEF_INCLUDE_CAPI_CEF_RENDER_PROCESS_HANDLER_CAPI_H_ @@ -73,7 +73,7 @@ typedef struct _cef_render_process_handler_t { /// // Called after a browser has been created. When browsing cross-origin a new // browser will be created before the old browser with the same identifier is - // destroyed. |extra_info| is a read-only value originating from + // destroyed. |extra_info| is an optional read-only value originating from // cef_browser_host_t::cef_browser_host_create_browser(), // cef_browser_host_t::cef_browser_host_create_browser_sync(), // cef_life_span_handler_t::on_before_popup() or diff --git a/include/cef_frame.h b/include/cef_frame.h index a1d0bbadc..2ce488342 100644 --- a/include/cef_frame.h +++ b/include/cef_frame.h @@ -246,10 +246,12 @@ class CefFrame : public virtual CefBaseRefCounted { CefRefPtr client) = 0; /// - // Send a message to the specified |target_process|. Message delivery is not - // guaranteed in all cases (for example, if the browser is closing, - // navigating, or if the target process crashes). Send an ACK message back - // from the target process if confirmation is required. + // Send a message to the specified |target_process|. Ownership of the message + // contents will be transferred and the |message| reference will be + // invalidated. Message delivery is not guaranteed in all cases (for example, + // if the browser is closing, navigating, or if the target process crashes). + // Send an ACK message back from the target process if confirmation is + // required. /// /*--cef()--*/ virtual void SendProcessMessage(CefProcessId target_process, diff --git a/include/cef_render_process_handler.h b/include/cef_render_process_handler.h index e91555fb5..95476239f 100644 --- a/include/cef_render_process_handler.h +++ b/include/cef_render_process_handler.h @@ -66,11 +66,11 @@ class CefRenderProcessHandler : public virtual CefBaseRefCounted { /// // Called after a browser has been created. When browsing cross-origin a new // browser will be created before the old browser with the same identifier is - // destroyed. |extra_info| is a read-only value originating from + // destroyed. |extra_info| is an optional read-only value originating from // CefBrowserHost::CreateBrowser(), CefBrowserHost::CreateBrowserSync(), // CefLifeSpanHandler::OnBeforePopup() or CefBrowserView::CreateBrowserView(). /// - /*--cef()--*/ + /*--cef(optional_param=extra_info)--*/ virtual void OnBrowserCreated(CefRefPtr browser, CefRefPtr extra_info) {} diff --git a/include/internal/cef_string_wrappers.h b/include/internal/cef_string_wrappers.h index 6645b8588..c53f5627e 100644 --- a/include/internal/cef_string_wrappers.h +++ b/include/internal/cef_string_wrappers.h @@ -79,15 +79,24 @@ struct CefStringTraitsWide { cef_string_utf8_clear(&cstr); return str; } + static inline bool from_string(const std::string::value_type* data, + size_t length, + struct_type* s) { + return cef_string_utf8_to_wide(data, length, s) ? true : false; + } static inline bool from_string(const std::string& str, struct_type* s) { - return cef_string_utf8_to_wide(str.c_str(), str.length(), s) ? true : false; + return from_string(str.data(), str.length(), s); } static inline std::wstring to_wstring(const struct_type* s) { return std::wstring(s->str, s->length); } + static inline bool from_wstring(const std::wstring::value_type* data, + size_t length, + struct_type* s) { + return cef_string_wide_set(data, length, s, true) ? true : false; + } static inline bool from_wstring(const std::wstring& str, struct_type* s) { - return cef_string_wide_set(str.c_str(), str.length(), s, true) ? true - : false; + return from_wstring(str.data(), str.length(), s); } #if defined(WCHAR_T_IS_UTF32) static inline std::u16string to_string16(const struct_type* s) { @@ -102,9 +111,11 @@ struct CefStringTraitsWide { cef_string_utf16_clear(&cstr); return str; } - static inline bool from_string16(const std::u16string& str, struct_type* s) { - return cef_string_utf16_to_wide( - reinterpret_cast(str.c_str()), str.length(), s) + static inline bool from_string16(const std::u16string::value_type* data, + size_t length, + struct_type* s) { + return cef_string_utf16_to_wide(reinterpret_cast(data), + length, s) ? true : false; } @@ -113,13 +124,18 @@ struct CefStringTraitsWide { return std::u16string( reinterpret_cast(s->str), s->length); } - static inline bool from_string16(const std::u16string& str, struct_type* s) { - return cef_string_wide_set(reinterpret_cast(str.c_str()), - str.length(), s, true) + static inline bool from_string16(const std::u16string::value_type* data, + size_t length, + struct_type* s) { + return cef_string_wide_set(reinterpret_cast(data), length, + s, true) ? true : false; } #endif // WCHAR_T_IS_UTF32 + static inline bool from_string16(const std::u16string& str, struct_type* s) { + return from_string16(str.data(), str.length(), s); + } }; /// @@ -154,8 +170,13 @@ struct CefStringTraitsUTF8 { static inline std::string to_string(const struct_type* s) { return std::string(s->str, s->length); } + static inline bool from_string(const std::string::value_type* data, + size_t length, + struct_type* s) { + return cef_string_utf8_copy(data, length, s) ? true : false; + } static inline bool from_string(const std::string& str, struct_type* s) { - return cef_string_utf8_copy(str.c_str(), str.length(), s) ? true : false; + return from_string(str.c_str(), str.length(), s); } static inline std::wstring to_wstring(const struct_type* s) { cef_string_wide_t cstr; @@ -167,8 +188,13 @@ struct CefStringTraitsUTF8 { cef_string_wide_clear(&cstr); return str; } + static inline bool from_wstring(const std::wstring::value_type* data, + size_t length, + struct_type* s) { + return cef_string_wide_to_utf8(data, length, s) ? true : false; + } static inline bool from_wstring(const std::wstring& str, struct_type* s) { - return cef_string_wide_to_utf8(str.c_str(), str.length(), s) ? true : false; + return from_wstring(str.data(), str.length(), s); } static inline std::u16string to_string16(const struct_type* s) { cef_string_utf16_t cstr; @@ -182,12 +208,17 @@ struct CefStringTraitsUTF8 { cef_string_utf16_clear(&cstr); return str; } - static inline bool from_string16(const std::u16string& str, struct_type* s) { - return cef_string_utf16_to_utf8( - reinterpret_cast(str.c_str()), str.length(), s) + static inline bool from_string16(const std::u16string::value_type* data, + size_t length, + struct_type* s) { + return cef_string_utf16_to_utf8(reinterpret_cast(data), + length, s) ? true : false; } + static inline bool from_string16(const std::u16string& str, struct_type* s) { + return from_string16(str.data(), str.length(), s); + } }; /// @@ -229,9 +260,13 @@ struct CefStringTraitsUTF16 { cef_string_utf8_clear(&cstr); return str; } + static inline bool from_string(const std::string::value_type* data, + size_t length, + struct_type* s) { + return cef_string_utf8_to_utf16(data, length, s) ? true : false; + } static inline bool from_string(const std::string& str, struct_type* s) { - return cef_string_utf8_to_utf16(str.c_str(), str.length(), s) ? true - : false; + return from_string(str.data(), str.length(), s); } #if defined(WCHAR_T_IS_UTF32) static inline std::wstring to_wstring(const struct_type* s) { @@ -244,29 +279,39 @@ struct CefStringTraitsUTF16 { cef_string_wide_clear(&cstr); return str; } - static inline bool from_wstring(const std::wstring& str, struct_type* s) { - return cef_string_wide_to_utf16(str.c_str(), str.length(), s) ? true - : false; + static inline bool from_wstring(const std::wstring::value_type* data, + size_t length, + struct_type* s) { + return cef_string_wide_to_utf16(data, length, s) ? true : false; } #else // WCHAR_T_IS_UTF32 static inline std::wstring to_wstring(const struct_type* s) { return std::wstring(s->str, s->length); } - static inline bool from_wstring(const std::wstring& str, struct_type* s) { - return cef_string_utf16_set(str.c_str(), str.length(), s, true) ? true - : false; + static inline bool from_wstring(const std::wstring::value_type* data, + size_t length, + struct_type* s) { + return cef_string_utf16_set(data, length, s, true) ? true : false; } #endif // WCHAR_T_IS_UTF32 + static inline bool from_wstring(const std::wstring& str, struct_type* s) { + return from_wstring(str.data(), str.length(), s); + } static inline std::u16string to_string16(const struct_type* s) { return std::u16string( reinterpret_cast(s->str), s->length); } - static inline bool from_string16(const std::u16string& str, struct_type* s) { - return cef_string_utf16_set(reinterpret_cast(str.c_str()), - str.length(), s, true) + static inline bool from_string16(const std::u16string::value_type* data, + size_t length, + struct_type* s) { + return cef_string_utf16_set(reinterpret_cast(data), length, + s, true) ? true : false; } + static inline bool from_string16(const std::u16string& str, struct_type* s) { + return from_string16(str.data(), str.length(), s); + } }; /// @@ -324,9 +369,10 @@ class CefStringBase { CefStringBase(const std::string& src) : string_(NULL), owner_(false) { FromString(src); } - CefStringBase(const char* src) : string_(NULL), owner_(false) { + CefStringBase(const char* src, size_t length = 0) + : string_(NULL), owner_(false) { if (src) - FromString(std::string(src)); + FromString(src, length); } /// @@ -337,9 +383,10 @@ class CefStringBase { CefStringBase(const std::wstring& src) : string_(NULL), owner_(false) { FromWString(src); } - CefStringBase(const wchar_t* src) : string_(NULL), owner_(false) { + CefStringBase(const wchar_t* src, size_t length = 0) + : string_(NULL), owner_(false) { if (src) - FromWString(std::wstring(src)); + FromWString(src, length); } /// @@ -350,16 +397,17 @@ class CefStringBase { CefStringBase(const std::u16string& src) : string_(NULL), owner_(false) { FromString16(src); } - CefStringBase(const std::u16string::value_type* src) + CefStringBase(const std::u16string::value_type* src, size_t length = 0) : string_(NULL), owner_(false) { if (src) - FromString16(std::u16string(src)); + FromString16(src, length); } #if defined(WCHAR_T_IS_UTF32) - CefStringBase(const char16* src) : string_(NULL), owner_(false) { + CefStringBase(const char16* src, size_t length = 0) + : string_(NULL), owner_(false) { if (src) { - FromString16(std::u16string( - reinterpret_cast(src))); + FromString16(reinterpret_cast(src), + length); } } #endif // WCHAR_T_IS_UTF32 @@ -599,6 +647,23 @@ class CefStringBase { return traits::from_string(str, string_); } + /// + // Set this string's data from existing |data| and optional |length|. Data + // will be always copied. Translation will occur if necessary based on the + // underlying string type. + /// + bool FromString(const std::string::value_type* data, size_t length = 0) { + if (data && length == 0) { + length = std::char_traits::length(data); + } + if (!data || length == 0) { + clear(); + return true; + } + AllocIfNeeded(); + return traits::from_string(data, length, string_); + } + /// // Return this string's data as a std::wstring. Translation will occur if // necessary based on the underlying string type. @@ -623,6 +688,22 @@ class CefStringBase { return traits::from_wstring(str, string_); } + /// + // Set this string's data from existing |data| and optional |length|. Data + // will be always copied. Translation will occur if necessary based on the + // underlying string type. + /// + bool FromWString(const std::wstring::value_type* data, size_t length = 0) { + if (data && length == 0) { + length = std::char_traits::length(data); + } + if (!data || length == 0) { + clear(); + return true; + } + AllocIfNeeded(); + return traits::from_wstring(data, length, string_); + } /// // Return this string's data as a string16. Translation will occur if // necessary based on the underlying string type. @@ -647,6 +728,23 @@ class CefStringBase { return traits::from_string16(str, string_); } + /// + // Set this string's data from existing |data| and optional |length|. Data + // will be always copied. Translation will occur if necessary based on the + // underlying string type. + /// + bool FromString16(const std::u16string::value_type* data, size_t length = 0) { + if (data && length == 0) { + length = std::char_traits::length(data); + } + if (!data || length == 0) { + clear(); + return true; + } + AllocIfNeeded(); + return traits::from_string16(data, length, string_); + } + /// // Comparison operator overloads. /// @@ -677,8 +775,8 @@ class CefStringBase { FromString(str); return *this; } - CefStringBase& operator=(const char* str) { - FromString(std::string(str)); + CefStringBase& operator=(const std::string::value_type* str) { + FromString(str); return *this; } operator std::wstring() const { return ToWString(); } @@ -686,8 +784,8 @@ class CefStringBase { FromWString(str); return *this; } - CefStringBase& operator=(const wchar_t* str) { - FromWString(std::wstring(str)); + CefStringBase& operator=(const std::wstring::value_type* str) { + FromWString(str); return *this; } operator std::u16string() const { return ToString16(); } @@ -696,13 +794,12 @@ class CefStringBase { return *this; } CefStringBase& operator=(const std::u16string::value_type* str) { - FromString16(std::u16string(str)); + FromString16(str); return *this; } #if defined(WCHAR_T_IS_UTF32) CefStringBase& operator=(const char16* str) { - FromString16(std::u16string( - reinterpret_cast(str))); + FromString16(reinterpret_cast(str)); return *this; } #endif // WCHAR_T_IS_UTF32 diff --git a/libcef/browser/alloy/alloy_browser_host_impl.cc b/libcef/browser/alloy/alloy_browser_host_impl.cc index ec9b8e6bc..1af79386c 100644 --- a/libcef/browser/alloy/alloy_browser_host_impl.cc +++ b/libcef/browser/alloy/alloy_browser_host_impl.cc @@ -21,7 +21,6 @@ #include "libcef/browser/osr/osr_util.h" #include "libcef/browser/request_context_impl.h" #include "libcef/browser/thread_util.h" -#include "libcef/common/cef_messages.h" #include "libcef/common/cef_switches.h" #include "libcef/common/drag_data_impl.h" #include "libcef/common/net/url_util.h" diff --git a/libcef/browser/alloy/alloy_content_browser_client.cc b/libcef/browser/alloy/alloy_content_browser_client.cc index 877909af7..abb3f084d 100644 --- a/libcef/browser/alloy/alloy_content_browser_client.cc +++ b/libcef/browser/alloy/alloy_content_browser_client.cc @@ -12,9 +12,10 @@ #include "libcef/browser/alloy/alloy_browser_host_impl.h" #include "libcef/browser/alloy/alloy_browser_main.h" #include "libcef/browser/browser_context.h" +#include "libcef/browser/browser_frame.h" #include "libcef/browser/browser_info.h" #include "libcef/browser/browser_info_manager.h" -#include "libcef/browser/browser_message_filter.h" +#include "libcef/browser/browser_manager.h" #include "libcef/browser/browser_platform_delegate.h" #include "libcef/browser/context.h" #include "libcef/browser/devtools/devtools_manager_delegate.h" @@ -35,7 +36,6 @@ #include "libcef/browser/x509_certificate_impl.h" #include "libcef/common/alloy/alloy_content_client.h" #include "libcef/common/app_manager.h" -#include "libcef/common/cef_messages.h" #include "libcef/common/cef_switches.h" #include "libcef/common/command_line_impl.h" #include "libcef/common/extensions/extensions_util.h" @@ -502,8 +502,6 @@ void AlloyContentBrowserClient::RenderProcessWillLaunch( const int id = host->GetID(); Profile* profile = Profile::FromBrowserContext(host->GetBrowserContext()); - host->AddFilter(new CefBrowserMessageFilter(id)); - if (extensions::ExtensionsEnabled()) { host->AddFilter(new extensions::ExtensionMessageFilter(id, profile)); host->AddFilter( @@ -782,7 +780,7 @@ void AlloyContentBrowserClient::AppendExtraCommandLineSwitches( CefRefPtr commandLinePtr( new CefCommandLineImpl(command_line, false, false)); handler->OnBeforeChildProcessLaunch(commandLinePtr.get()); - commandLinePtr->Detach(nullptr); + ignore_result(commandLinePtr->Detach(nullptr)); } } } @@ -1044,6 +1042,9 @@ void AlloyContentBrowserClient::ExposeInterfacesToRenderer( content::RenderProcessHost* host) { associated_registry->AddInterface( base::BindRepeating(&BindPluginInfoHost, host->GetID())); + + CefBrowserManager::ExposeInterfacesToRenderer(registry, associated_registry, + host); } std::unique_ptr @@ -1292,6 +1293,8 @@ void AlloyContentBrowserClient::RegisterBrowserInterfaceBindersForFrame( content::RenderFrameHost* render_frame_host, mojo::BinderMapWithContext* map) { PopulateChromeFrameBinders(map); + CefBrowserFrame::RegisterBrowserInterfaceBindersForFrame(render_frame_host, + map); if (!extensions::ExtensionsEnabled()) return; diff --git a/libcef/browser/browser_contents_delegate.cc b/libcef/browser/browser_contents_delegate.cc index f6f26956c..87848a5cf 100644 --- a/libcef/browser/browser_contents_delegate.cc +++ b/libcef/browser/browser_contents_delegate.cc @@ -426,18 +426,6 @@ void CefBrowserContentsDelegate::DidFailLoad( OnLoadEnd(frame, validated_url, error_code); } -bool CefBrowserContentsDelegate::OnMessageReceived( - const IPC::Message& message, - content::RenderFrameHost* render_frame_host) { - // Messages may arrive after a frame is detached. Ignore those messages. - auto frame = browser_info_->GetFrameForHost(render_frame_host); - if (frame) { - return static_cast(frame.get()) - ->OnMessageReceived(message); - } - return false; -} - void CefBrowserContentsDelegate::TitleWasSet(content::NavigationEntry* entry) { // |entry| may be NULL if a popup is created via window.open and never // navigated. diff --git a/libcef/browser/browser_contents_delegate.h b/libcef/browser/browser_contents_delegate.h index 9977552a8..ac30f5f92 100644 --- a/libcef/browser/browser_contents_delegate.h +++ b/libcef/browser/browser_contents_delegate.h @@ -121,8 +121,6 @@ class CefBrowserContentsDelegate : public content::WebContentsDelegate, void DidFailLoad(content::RenderFrameHost* render_frame_host, const GURL& validated_url, int error_code) override; - bool OnMessageReceived(const IPC::Message& message, - content::RenderFrameHost* render_frame_host) override; void TitleWasSet(content::NavigationEntry* entry) override; void PluginCrashed(const base::FilePath& plugin_path, base::ProcessId plugin_pid) override; diff --git a/libcef/browser/browser_frame.cc b/libcef/browser/browser_frame.cc new file mode 100644 index 000000000..0fe8ee9ed --- /dev/null +++ b/libcef/browser/browser_frame.cc @@ -0,0 +1,71 @@ +// Copyright 2021 The Chromium Embedded Framework Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "libcef/browser/browser_frame.h" + +#include "libcef/browser/browser_host_base.h" +#include "libcef/browser/thread_util.h" + +#include "content/public/browser/render_frame_host.h" +#include "content/public/browser/render_process_host.h" +#include "content/public/browser/web_contents.h" +#include "content/public/browser/web_contents_observer.h" +#include "mojo/public/cpp/bindings/self_owned_receiver.h" + +CefBrowserFrame::CefBrowserFrame( + content::RenderFrameHost* render_frame_host, + mojo::PendingReceiver receiver) + : FrameServiceBase(render_frame_host, std::move(receiver)) {} + +CefBrowserFrame::~CefBrowserFrame() = default; + +// static +void CefBrowserFrame::RegisterBrowserInterfaceBindersForFrame( + content::RenderFrameHost* render_frame_host, + mojo::BinderMapWithContext* map) { + map->Add(base::BindRepeating( + [](content::RenderFrameHost* frame_host, + mojo::PendingReceiver receiver) { + // This object is bound to the lifetime of |frame_host| and the mojo + // connection. See FrameServiceBase for details. + new CefBrowserFrame(frame_host, std::move(receiver)); + })); +} + +void CefBrowserFrame::SendMessage(const std::string& name, + base::Value arguments) { + if (auto host = GetFrameHost()) { + host->SendMessage(name, std::move(arguments)); + } +} + +void CefBrowserFrame::FrameAttached() { + if (auto host = GetFrameHost()) { + host->FrameAttached(); + } +} + +void CefBrowserFrame::DidFinishFrameLoad(const GURL& validated_url, + int http_status_code) { + if (auto host = GetFrameHost()) { + host->DidFinishFrameLoad(validated_url, http_status_code); + } +} + +void CefBrowserFrame::UpdateDraggableRegions( + base::Optional> regions) { + if (auto host = GetFrameHost()) { + host->UpdateDraggableRegions(std::move(regions)); + } +} + +CefRefPtr CefBrowserFrame::GetFrameHost() const { + CEF_REQUIRE_UIT(); + auto rfh = render_frame_host(); + if (auto browser = CefBrowserHostBase::GetBrowserForHost(rfh)) { + return browser->browser_info()->GetFrameForHost(rfh); + } + NOTREACHED(); + return nullptr; +} diff --git a/libcef/browser/browser_frame.h b/libcef/browser/browser_frame.h new file mode 100644 index 000000000..0b7cd00bb --- /dev/null +++ b/libcef/browser/browser_frame.h @@ -0,0 +1,50 @@ +// Copyright 2021 The Chromium Embedded Framework Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CEF_LIBCEF_BROWSER_BROWSER_FRAME_H_ +#define CEF_LIBCEF_BROWSER_BROWSER_FRAME_H_ +#pragma once + +#include "libcef/browser/frame_host_impl.h" + +#include "cef/libcef/common/mojom/cef.mojom.h" +#include "content/public/browser/frame_service_base.h" +#include "mojo/public/cpp/bindings/binder_map.h" + +// Implementation of the BrowserFrame mojo interface. +// This is implemented separately from CefFrameHostImpl to better manage the +// association with the RenderFrameHost (which may be speculative, etc.), and so +// that messages are always routed to the most appropriate CefFrameHostImpl +// instance. Lifespan is tied to the RFH via FrameServiceBase. +class CefBrowserFrame + : public content::FrameServiceBase { + public: + CefBrowserFrame(content::RenderFrameHost* render_frame_host, + mojo::PendingReceiver receiver); + ~CefBrowserFrame() override; + + // Called from the ContentBrowserClient method of the same name. + static void RegisterBrowserInterfaceBindersForFrame( + content::RenderFrameHost* render_frame_host, + mojo::BinderMapWithContext* map); + + private: + // cef::mojom::BrowserFrame methods: + void SendMessage(const std::string& name, base::Value arguments) override; + void FrameAttached() override; + void DidFinishFrameLoad(const GURL& validated_url, + int32_t http_status_code) override; + void UpdateDraggableRegions( + base::Optional> regions) + override; + + // FrameServiceBase methods: + bool ShouldCloseOnFinishNavigation() const override { return false; } + + CefRefPtr GetFrameHost() const; + + DISALLOW_COPY_AND_ASSIGN(CefBrowserFrame); +}; + +#endif // CEF_LIBCEF_BROWSER_BROWSER_FRAME_H_ diff --git a/libcef/browser/browser_host_base.cc b/libcef/browser/browser_host_base.cc index 20760ddff..d91c23a28 100644 --- a/libcef/browser/browser_host_base.cc +++ b/libcef/browser/browser_host_base.cc @@ -367,7 +367,7 @@ void CefBrowserHostBase::GetNavigationEntries( CefRefPtr entry = new CefNavigationEntryImpl(controller.GetEntryAtIndex(current)); visitor->Visit(entry.get(), true, current, total); - entry->Detach(nullptr); + ignore_result(entry->Detach(nullptr)); } else { // Visit all entries. bool cont = true; @@ -375,7 +375,7 @@ void CefBrowserHostBase::GetNavigationEntries( CefRefPtr entry = new CefNavigationEntryImpl(controller.GetEntryAtIndex(i)); cont = visitor->Visit(entry.get(), (i == current), i, total); - entry->Detach(nullptr); + ignore_result(entry->Detach(nullptr)); } } } diff --git a/libcef/browser/browser_info_manager.cc b/libcef/browser/browser_info_manager.cc index 4193972c9..0ae6ea7dd 100644 --- a/libcef/browser/browser_info_manager.cc +++ b/libcef/browser/browser_info_manager.cc @@ -10,7 +10,6 @@ #include "libcef/browser/browser_platform_delegate.h" #include "libcef/browser/extensions/browser_extensions_util.h" #include "libcef/browser/thread_util.h" -#include "libcef/common/cef_messages.h" #include "libcef/common/cef_switches.h" #include "libcef/common/extensions/extensions_util.h" #include "libcef/common/values_impl.h" @@ -18,6 +17,7 @@ #include "base/command_line.h" #include "base/logging.h" +#include "base/threading/sequenced_task_runner_handle.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_process_host.h" #include "content/public/browser/web_contents.h" @@ -95,9 +95,9 @@ scoped_refptr CefBrowserInfoManager::CreatePopupBrowserInfo( // Continue any pending NewBrowserInfo request. auto it = pending_new_browser_info_map_.find(frame_id); if (it != pending_new_browser_info_map_.end()) { - SendNewBrowserInfoResponse(render_process_id, browser_info, - false /* is_guest_view */, - it->second->reply_msg); + SendNewBrowserInfoResponse( + render_process_id, browser_info, /*is_guest_view=*/false, + std::move(it->second->callback), it->second->callback_runner); pending_new_browser_info_map_.erase(it); } @@ -262,12 +262,15 @@ void CefBrowserInfoManager::WebContentsCreated( extra_info = pending_popup->extra_info; } -void CefBrowserInfoManager::OnGetNewBrowserInfo(int render_process_id, - int render_routing_id, - IPC::Message* reply_msg) { +void CefBrowserInfoManager::OnGetNewBrowserInfo( + int render_process_id, + int render_routing_id, + cef::mojom::BrowserManager::GetNewBrowserInfoCallback callback) { DCHECK_NE(render_process_id, content::ChildProcessHost::kInvalidUniqueID); DCHECK_GT(render_routing_id, 0); - DCHECK(reply_msg); + DCHECK(callback); + + auto callback_runner = base::SequencedTaskRunnerHandle::Get(); base::AutoLock lock_scope(browser_info_lock_); @@ -279,7 +282,7 @@ void CefBrowserInfoManager::OnGetNewBrowserInfo(int render_process_id, if (browser_info.get()) { // Send the response immediately. SendNewBrowserInfoResponse(render_process_id, browser_info, is_guest_view, - reply_msg); + std::move(callback), callback_runner); return; } @@ -297,7 +300,8 @@ void CefBrowserInfoManager::OnGetNewBrowserInfo(int render_process_id, pending->render_process_id = render_process_id; pending->render_routing_id = render_routing_id; pending->timeout_id = timeout_id; - pending->reply_msg = reply_msg; + pending->callback = std::move(callback); + pending->callback_runner = callback_runner; pending_new_browser_info_map_.insert( std::make_pair(frame_id, std::move(pending))); @@ -437,11 +441,13 @@ void CefBrowserInfoManager::RenderProcessHostDestroyed( PendingNewBrowserInfoMap::iterator it = pending_new_browser_info_map_.begin(); while (it != pending_new_browser_info_map_.end()) { - auto info = it->second.get(); - if (info->render_process_id == render_process_id) + const auto& info = it->second; + if (info->render_process_id == render_process_id) { + CancelNewBrowserInfoResponse(info.get()); it = pending_new_browser_info_map_.erase(it); - else + } else { ++it; + } } } @@ -522,44 +528,47 @@ void CefBrowserInfoManager::SendNewBrowserInfoResponse( int render_process_id, scoped_refptr browser_info, bool is_guest_view, - IPC::Message* reply_msg) { - if (!CEF_CURRENTLY_ON_UIT()) { - CEF_POST_TASK( - CEF_UIT, - base::Bind(&CefBrowserInfoManager::SendNewBrowserInfoResponse, - render_process_id, browser_info, is_guest_view, reply_msg)); + cef::mojom::BrowserManager::GetNewBrowserInfoCallback callback, + scoped_refptr callback_runner) { + if (!callback_runner->RunsTasksInCurrentSequence()) { + callback_runner->PostTask( + FROM_HERE, + base::BindOnce(&CefBrowserInfoManager::SendNewBrowserInfoResponse, + render_process_id, browser_info, is_guest_view, + std::move(callback), callback_runner)); return; } - content::RenderProcessHost* host = - content::RenderProcessHost::FromID(render_process_id); - if (!host) { - delete reply_msg; - return; - } - - CefProcessHostMsg_GetNewBrowserInfo_Params params; - params.is_guest_view = is_guest_view; + auto params = cef::mojom::NewBrowserInfo::New(); + params->is_guest_view = is_guest_view; if (browser_info) { - params.browser_id = browser_info->browser_id(); - params.is_windowless = browser_info->is_windowless(); - params.is_popup = browser_info->is_popup(); + params->browser_id = browser_info->browser_id(); + params->is_windowless = browser_info->is_windowless(); + params->is_popup = browser_info->is_popup(); auto extra_info = browser_info->extra_info(); if (extra_info) { auto extra_info_impl = static_cast(extra_info.get()); - auto extra_info_value = extra_info_impl->CopyValue(); - extra_info_value->Swap(¶ms.extra_info); + auto extra_info_value = base::WrapUnique(extra_info_impl->CopyValue()); + params->extra_info = std::move(*extra_info_value); } } else { // The new browser info response has timed out. - params.browser_id = -1; + params->browser_id = -1; } - CefProcessHostMsg_GetNewBrowserInfo::WriteReplyParams(reply_msg, params); - host->Send(reply_msg); + std::move(callback).Run(std::move(params)); +} + +// static +void CefBrowserInfoManager::CancelNewBrowserInfoResponse( + PendingNewBrowserInfo* pending_info) { + SendNewBrowserInfoResponse(pending_info->render_process_id, + /*browser_info=*/nullptr, /*is_guest_view=*/false, + std::move(pending_info->callback), + pending_info->callback_runner); } // static @@ -582,9 +591,7 @@ void CefBrowserInfoManager::TimeoutNewBrowserInfoResponse(int64_t frame_id, << pending_info->render_process_id << " and routing id " << pending_info->render_routing_id; - SendNewBrowserInfoResponse(pending_info->render_process_id, nullptr, - false /* is_guest_view */, - pending_info->reply_msg); + CancelNewBrowserInfoResponse(pending_info.get()); g_info_manager->pending_new_browser_info_map_.erase(it); } } diff --git a/libcef/browser/browser_info_manager.h b/libcef/browser/browser_info_manager.h index 010b11239..47e709e6f 100644 --- a/libcef/browser/browser_info_manager.h +++ b/libcef/browser/browser_info_manager.h @@ -14,7 +14,9 @@ #include "libcef/browser/browser_info.h" +#include "base/sequenced_task_runner.h" #include "base/synchronization/lock.h" +#include "cef/libcef/common/mojom/cef.mojom.h" #include "content/public/browser/render_process_host_observer.h" #include "third_party/blink/public/mojom/window_features/window_features.mojom.h" #include "ui/base/window_open_disposition.h" @@ -33,10 +35,6 @@ class WebContents; class WebContentsView; } // namespace content -namespace IPC { -class Message; -} - class CefBrowserHostBase; class CefBrowserPlatformDelegate; @@ -97,16 +95,17 @@ class CefBrowserInfoManager : public content::RenderProcessHostObserver { std::unique_ptr& platform_delegate, CefRefPtr& extra_info); - // Called from CefBrowserMessageFilter::OnGetNewBrowserInfo for delivering + // Called from CefBrowserManager::GetNewBrowserInfo for delivering // browser info to the renderer process. If the browser info already exists // the response will be sent immediately. Otherwise, the response will be sent // when CreatePopupBrowserInfo creates the browser info. The info will already // exist for explicitly created browsers and guest views. It may sometimes // already exist for traditional popup browsers depending on timing. See // comments on PendingPopup for more information. - void OnGetNewBrowserInfo(int render_process_id, - int render_routing_id, - IPC::Message* reply_msg); + void OnGetNewBrowserInfo( + int render_process_id, + int render_routing_id, + cef::mojom::BrowserManager::GetNewBrowserInfoCallback callback); // Called from CefBrowserHostBase::DestroyBrowser() when a browser is // destroyed. @@ -163,7 +162,7 @@ class CefBrowserInfoManager : public content::RenderProcessHostObserver { // Creates the OSR views for windowless popups. // - WebContentsCreated (UIT): // Creates the CefBrowserHost representation for the popup. - // - CefBrowserMessageFilter::OnGetNewBrowserInfo (IOT) + // - CefBrowserManager::GetNewBrowserInfo (IOT) // Passes information about the popup to the renderer process. struct PendingPopup { // Track the last method that modified this PendingPopup instance. There may @@ -209,19 +208,24 @@ class CefBrowserInfoManager : public content::RenderProcessHostObserver { int render_process_id, scoped_refptr browser_info, bool is_guest_view, - IPC::Message* reply_msg); - - // Time out a response if it's still pending. - static void TimeoutNewBrowserInfoResponse(int64_t frame_id, int timeout_id); + cef::mojom::BrowserManager::GetNewBrowserInfoCallback callback, + scoped_refptr callback_runner); // Pending request for OnGetNewBrowserInfo. struct PendingNewBrowserInfo { int render_process_id; int render_routing_id; int timeout_id; - IPC::Message* reply_msg; + cef::mojom::BrowserManager::GetNewBrowserInfoCallback callback; + scoped_refptr callback_runner; }; + // Cancel a response that is still pending. + static void CancelNewBrowserInfoResponse(PendingNewBrowserInfo* pending_info); + + // Time out a response if it's still pending. + static void TimeoutNewBrowserInfoResponse(int64_t frame_id, int timeout_id); + mutable base::Lock browser_info_lock_; // Access to the below members must be protected by |browser_info_lock_|. diff --git a/libcef/browser/browser_manager.cc b/libcef/browser/browser_manager.cc new file mode 100644 index 000000000..5d40d5137 --- /dev/null +++ b/libcef/browser/browser_manager.cc @@ -0,0 +1,56 @@ +// Copyright 2021 The Chromium Embedded Framework Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "libcef/browser/browser_manager.h" + +#include "libcef/browser/browser_info_manager.h" +#include "libcef/browser/origin_whitelist_impl.h" + +#include "content/public/browser/render_process_host.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" +#include "mojo/public/cpp/bindings/self_owned_receiver.h" +#include "services/service_manager/public/cpp/binder_registry.h" + +CefBrowserManager::CefBrowserManager(int render_process_id) + : render_process_id_(render_process_id) {} + +CefBrowserManager::~CefBrowserManager() = default; + +// static +void CefBrowserManager::ExposeInterfacesToRenderer( + service_manager::BinderRegistry* registry, + blink::AssociatedInterfaceRegistry* associated_registry, + content::RenderProcessHost* host) { + registry->AddInterface(base::BindRepeating( + [](int render_process_id, + mojo::PendingReceiver receiver) { + mojo::MakeSelfOwnedReceiver( + std::make_unique(render_process_id), + std::move(receiver)); + }, + host->GetID())); +} + +// static +mojo::Remote +CefBrowserManager::GetRenderManagerForProcess( + content::RenderProcessHost* host) { + mojo::Remote client; + host->BindReceiver(client.BindNewPipeAndPassReceiver()); + return client; +} + +void CefBrowserManager::GetNewRenderThreadInfo( + cef::mojom::BrowserManager::GetNewRenderThreadInfoCallback callback) { + auto info = cef::mojom::NewRenderThreadInfo::New(); + GetCrossOriginWhitelistEntries(&info->cross_origin_whitelist_entries); + std::move(callback).Run(std::move(info)); +} + +void CefBrowserManager::GetNewBrowserInfo( + int32_t render_frame_routing_id, + cef::mojom::BrowserManager::GetNewBrowserInfoCallback callback) { + CefBrowserInfoManager::GetInstance()->OnGetNewBrowserInfo( + render_process_id_, render_frame_routing_id, std::move(callback)); +} diff --git a/libcef/browser/browser_manager.h b/libcef/browser/browser_manager.h new file mode 100644 index 000000000..3c17e01cd --- /dev/null +++ b/libcef/browser/browser_manager.h @@ -0,0 +1,54 @@ +// Copyright 2021 The Chromium Embedded Framework Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CEF_LIBCEF_BROWSER_BROWSER_MANAGER_H_ +#define CEF_LIBCEF_BROWSER_BROWSER_MANAGER_H_ + +#include "cef/libcef/common/mojom/cef.mojom.h" +#include "mojo/public/cpp/bindings/remote.h" +#include "services/service_manager/public/cpp/binder_registry.h" + +namespace blink { +class AssociatedInterfaceRegistry; +} + +namespace content { +class RenderProcessHost; +} + +class CefBrowserManager : public cef::mojom::BrowserManager { + public: + explicit CefBrowserManager(int render_process_id); + ~CefBrowserManager() override; + + // Called from the ContentBrowserClient method of the same name. + // |associated_registry| is used for interfaces which must be associated with + // some IPC::ChannelProxy, meaning that messages on the interface retain FIFO + // with respect to legacy Chrome IPC messages sent or dispatched on the + // channel. + static void ExposeInterfacesToRenderer( + service_manager::BinderRegistry* registry, + blink::AssociatedInterfaceRegistry* associated_registry, + content::RenderProcessHost* host); + + // Connects to CefRenderManager in the render process. + static mojo::Remote GetRenderManagerForProcess( + content::RenderProcessHost* host); + + private: + // cef::mojom::BrowserManager methods: + void GetNewRenderThreadInfo( + cef::mojom::BrowserManager::GetNewRenderThreadInfoCallback callback) + override; + void GetNewBrowserInfo( + int32_t render_frame_routing_id, + cef::mojom::BrowserManager::GetNewBrowserInfoCallback callback) override; + + // The process ID of the renderer. + const int render_process_id_; + + DISALLOW_COPY_AND_ASSIGN(CefBrowserManager); +}; + +#endif // CEF_LIBCEF_BROWSER_BROWSER_MANAGER_H_ diff --git a/libcef/browser/browser_message_filter.cc b/libcef/browser/browser_message_filter.cc deleted file mode 100644 index 31b8a00b9..000000000 --- a/libcef/browser/browser_message_filter.cc +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (c) 2012 The Chromium Embedded Framework Authors. -// Portions (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "libcef/browser/browser_message_filter.h" - -#include "libcef/browser/browser_info_manager.h" -#include "libcef/browser/origin_whitelist_impl.h" -#include "libcef/common/app_manager.h" -#include "libcef/common/cef_messages.h" -#include "libcef/common/values_impl.h" - -#include "base/bind.h" -#include "base/compiler_specific.h" -#include "content/public/common/child_process_host.h" - -CefBrowserMessageFilter::CefBrowserMessageFilter(int render_process_id) - : content::BrowserMessageFilter(ExtensionMsgStart), - render_process_id_(render_process_id) {} - -CefBrowserMessageFilter::~CefBrowserMessageFilter() {} - -void CefBrowserMessageFilter::OnFilterRemoved() { - render_process_id_ = content::ChildProcessHost::kInvalidUniqueID; - content::BrowserMessageFilter::OnFilterRemoved(); -} - -bool CefBrowserMessageFilter::OnMessageReceived(const IPC::Message& message) { - bool handled = true; - - IPC_BEGIN_MESSAGE_MAP(CefBrowserMessageFilter, message) - IPC_MESSAGE_HANDLER(CefProcessHostMsg_GetNewRenderThreadInfo, - OnGetNewRenderThreadInfo) - IPC_MESSAGE_HANDLER_DELAY_REPLY(CefProcessHostMsg_GetNewBrowserInfo, - OnGetNewBrowserInfo) - IPC_MESSAGE_UNHANDLED(handled = false) - IPC_END_MESSAGE_MAP() - return handled; -} - -void CefBrowserMessageFilter::OnGetNewRenderThreadInfo( - CefProcessHostMsg_GetNewRenderThreadInfo_Params* params) { - GetCrossOriginWhitelistEntries(¶ms->cross_origin_whitelist_entries); -} - -void CefBrowserMessageFilter::OnGetNewBrowserInfo(int render_frame_routing_id, - IPC::Message* reply_msg) { - if (render_process_id_ != content::ChildProcessHost::kInvalidUniqueID) { - CefBrowserInfoManager::GetInstance()->OnGetNewBrowserInfo( - render_process_id_, render_frame_routing_id, reply_msg); - } else { - delete reply_msg; - } -} diff --git a/libcef/browser/browser_message_filter.h b/libcef/browser/browser_message_filter.h deleted file mode 100644 index c4a28e435..000000000 --- a/libcef/browser/browser_message_filter.h +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (c) 2012 The Chromium Embedded Framework Authors. -// Portions copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CEF_LIBCEF_BROWSER_BROWSER_MESSAGE_FILTER_H_ -#define CEF_LIBCEF_BROWSER_BROWSER_MESSAGE_FILTER_H_ - -#include - -#include - -#include "content/public/browser/browser_message_filter.h" - -struct CefProcessHostMsg_GetNewBrowserInfo_Params; -struct CefProcessHostMsg_GetNewRenderThreadInfo_Params; - -// This class sends and receives control messages on the browser process. -class CefBrowserMessageFilter : public content::BrowserMessageFilter { - public: - explicit CefBrowserMessageFilter(int render_process_id); - ~CefBrowserMessageFilter() override; - - // IPC::ChannelProxy::MessageFilter implementation. - void OnFilterRemoved() override; - bool OnMessageReceived(const IPC::Message& message) override; - - private: - // Message handlers. - void OnGetNewRenderThreadInfo( - CefProcessHostMsg_GetNewRenderThreadInfo_Params* params); - void OnGetNewBrowserInfo(int render_frame_routing_id, - IPC::Message* reply_msg); - - int render_process_id_; - - DISALLOW_COPY_AND_ASSIGN(CefBrowserMessageFilter); -}; - -#endif // CEF_LIBCEF_BROWSER_BROWSER_MESSAGE_FILTER_H_ diff --git a/libcef/browser/chrome/chrome_content_browser_client_cef.cc b/libcef/browser/chrome/chrome_content_browser_client_cef.cc index 23092aeaf..e18c43c1a 100644 --- a/libcef/browser/chrome/chrome_content_browser_client_cef.cc +++ b/libcef/browser/chrome/chrome_content_browser_client_cef.cc @@ -5,8 +5,9 @@ #include "libcef/browser/chrome/chrome_content_browser_client_cef.h" +#include "libcef/browser/browser_frame.h" #include "libcef/browser/browser_info_manager.h" -#include "libcef/browser/browser_message_filter.h" +#include "libcef/browser/browser_manager.h" #include "libcef/browser/chrome/chrome_browser_host_impl.h" #include "libcef/browser/chrome/chrome_browser_main_extra_parts_cef.h" #include "libcef/browser/context.h" @@ -122,7 +123,7 @@ void ChromeContentBrowserClientCef::AppendExtraCommandLineSwitches( CefRefPtr commandLinePtr( new CefCommandLineImpl(command_line, false, false)); handler->OnBeforeChildProcessLaunch(commandLinePtr.get()); - commandLinePtr->Detach(nullptr); + ignore_result(commandLinePtr->Detach(nullptr)); } } } @@ -131,9 +132,6 @@ void ChromeContentBrowserClientCef::RenderProcessWillLaunch( content::RenderProcessHost* host) { ChromeContentBrowserClient::RenderProcessWillLaunch(host); - const int id = host->GetID(); - host->AddFilter(new CefBrowserMessageFilter(id)); - // If the renderer process crashes then the host may already have // CefBrowserInfoManager as an observer. Try to remove it first before adding // to avoid DCHECKs. @@ -357,6 +355,27 @@ bool ChromeContentBrowserClientCef::IsWebUIAllowedToMakeNetworkRequests( return scheme::IsWebUIAllowedToMakeNetworkRequests(origin); } +void ChromeContentBrowserClientCef::ExposeInterfacesToRenderer( + service_manager::BinderRegistry* registry, + blink::AssociatedInterfaceRegistry* associated_registry, + content::RenderProcessHost* host) { + ChromeContentBrowserClient::ExposeInterfacesToRenderer( + registry, associated_registry, host); + + CefBrowserManager::ExposeInterfacesToRenderer(registry, associated_registry, + host); +} + +void ChromeContentBrowserClientCef::RegisterBrowserInterfaceBindersForFrame( + content::RenderFrameHost* render_frame_host, + mojo::BinderMapWithContext* map) { + ChromeContentBrowserClient::RegisterBrowserInterfaceBindersForFrame( + render_frame_host, map); + + CefBrowserFrame::RegisterBrowserInterfaceBindersForFrame(render_frame_host, + map); +} + CefRefPtr ChromeContentBrowserClientCef::request_context() const { return browser_main_parts_->request_context(); diff --git a/libcef/browser/chrome/chrome_content_browser_client_cef.h b/libcef/browser/chrome/chrome_content_browser_client_cef.h index ebe2f6ce4..dcbaaf164 100644 --- a/libcef/browser/chrome/chrome_content_browser_client_cef.h +++ b/libcef/browser/chrome/chrome_content_browser_client_cef.h @@ -96,6 +96,13 @@ class ChromeContentBrowserClientCef : public ChromeContentBrowserClient { LoginAuthRequiredCallback auth_required_callback) override; void BrowserURLHandlerCreated(content::BrowserURLHandler* handler) override; bool IsWebUIAllowedToMakeNetworkRequests(const url::Origin& origin) override; + void ExposeInterfacesToRenderer( + service_manager::BinderRegistry* registry, + blink::AssociatedInterfaceRegistry* associated_registry, + content::RenderProcessHost* render_process_host) override; + void RegisterBrowserInterfaceBindersForFrame( + content::RenderFrameHost* render_frame_host, + mojo::BinderMapWithContext* map) override; CefRefPtr request_context() const; diff --git a/libcef/browser/download_manager_delegate.cc b/libcef/browser/download_manager_delegate.cc index 004f469b1..437794bfe 100644 --- a/libcef/browser/download_manager_delegate.cc +++ b/libcef/browser/download_manager_delegate.cc @@ -289,7 +289,7 @@ void CefDownloadManagerDelegate::OnDownloadUpdated(DownloadItem* download) { handler->OnDownloadUpdated(browser.get(), download_item.get(), callback); - download_item->Detach(nullptr); + ignore_result(download_item->Detach(nullptr)); } } @@ -384,7 +384,7 @@ bool CefDownloadManagerDelegate::DetermineDownloadTarget( handler->OnBeforeDownload(browser.get(), download_item.get(), suggested_name.value(), callbackObj); - download_item->Detach(nullptr); + ignore_result(download_item->Detach(nullptr)); } return true; diff --git a/libcef/browser/extensions/extension_function_details.cc b/libcef/browser/extensions/extension_function_details.cc index 79d0aafb2..e6cf50771 100644 --- a/libcef/browser/extensions/extension_function_details.cc +++ b/libcef/browser/extensions/extension_function_details.cc @@ -7,7 +7,6 @@ #include "libcef/browser/browser_context.h" #include "libcef/browser/extensions/browser_extensions_util.h" #include "libcef/browser/extensions/extension_system.h" -#include "libcef/browser/navigate_params.h" #include "libcef/browser/thread_util.h" #include "base/strings/utf_string_conversions.h" diff --git a/libcef/browser/frame_host_impl.cc b/libcef/browser/frame_host_impl.cc index df800f43f..694a98915 100644 --- a/libcef/browser/frame_host_impl.cc +++ b/libcef/browser/frame_host_impl.cc @@ -9,53 +9,42 @@ #include "include/cef_v8.h" #include "include/test/cef_test_helpers.h" #include "libcef/browser/browser_host_base.h" -#include "libcef/browser/navigate_params.h" #include "libcef/browser/net_service/browser_urlrequest_impl.h" -#include "libcef/common/cef_messages.h" -#include "libcef/common/frame_util.h" +#include "libcef/common/frame_util.h" #include "libcef/common/net/url_util.h" #include "libcef/common/process_message_impl.h" #include "libcef/common/request_impl.h" +#include "libcef/common/string_util.h" #include "libcef/common/task_runner_impl.h" #include "content/browser/renderer_host/frame_tree_node.h" #include "content/public/browser/render_process_host.h" #include "content/public/browser/render_view_host.h" +#include "services/service_manager/public/cpp/interface_provider.h" namespace { -// Implementation of CommandResponseHandler for calling a CefStringVisitor. -class StringVisitHandler : public CefResponseManager::Handler { - public: - explicit StringVisitHandler(CefRefPtr visitor) - : visitor_(visitor) {} - void OnResponse(const Cef_Response_Params& params) override { - visitor_->Visit(params.response); - } +void StringVisitCallback(CefRefPtr visitor, + base::ReadOnlySharedMemoryRegion response) { + string_util::ExecuteWithScopedCefString( + std::move(response), + base::BindOnce([](CefRefPtr visitor, + const CefString& str) { visitor->Visit(str); }, + visitor)); +} - private: - CefRefPtr visitor_; - - IMPLEMENT_REFCOUNTING(StringVisitHandler); -}; - -// Implementation of CommandResponseHandler for calling ViewText(). -class ViewTextHandler : public CefResponseManager::Handler { - public: - explicit ViewTextHandler(CefRefPtr frame) : frame_(frame) {} - void OnResponse(const Cef_Response_Params& params) override { - CefRefPtr browser = frame_->GetBrowser(); - if (browser.get()) { - static_cast(browser.get()) - ->ViewText(params.response); - } +void ViewTextCallback(CefRefPtr frame, + base::ReadOnlySharedMemoryRegion response) { + if (auto browser = frame->GetBrowser()) { + string_util::ExecuteWithScopedCefString( + std::move(response), + base::BindOnce( + [](CefRefPtr browser, const CefString& str) { + static_cast(browser.get())->ViewText(str); + }, + browser)); } - - private: - CefRefPtr frame_; - - IMPLEMENT_REFCOUNTING(ViewTextHandler); -}; +} } // namespace @@ -80,17 +69,13 @@ CefFrameHostImpl::CefFrameHostImpl(scoped_refptr browser_info, CefFrameHostImpl::CefFrameHostImpl(scoped_refptr browser_info, content::RenderFrameHost* render_frame_host) : is_main_frame_(render_frame_host->GetParent() == nullptr), - frame_id_(MakeFrameId(render_frame_host)), browser_info_(browser_info), is_focused_(is_main_frame_), // The main frame always starts focused. - url_(render_frame_host->GetLastCommittedURL().spec()), - name_(render_frame_host->GetFrameName()), parent_frame_id_(is_main_frame_ ? kInvalidFrameId - : MakeFrameId(render_frame_host->GetParent())), - render_frame_host_(render_frame_host), - response_manager_(new CefResponseManager) { + : MakeFrameId(render_frame_host->GetParent())) { DCHECK(browser_info_); + SetRenderFrameHost(render_frame_host); } CefFrameHostImpl::~CefFrameHostImpl() {} @@ -102,16 +87,13 @@ void CefFrameHostImpl::SetRenderFrameHost(content::RenderFrameHost* host) { // We should not be detached. CHECK(browser_info_); - // We should be the main frame. - CHECK(is_main_frame_); + + render_frame_.reset(); render_frame_host_ = host; frame_id_ = MakeFrameId(host); url_ = host->GetLastCommittedURL().spec(); name_ = host->GetFrameName(); - - // Cancel any existing messages. - response_manager_.reset(new CefResponseManager); } bool CefFrameHostImpl::IsValid() { @@ -119,49 +101,53 @@ bool CefFrameHostImpl::IsValid() { } void CefFrameHostImpl::Undo() { - SendCommand("Undo", nullptr); + SendCommand("Undo"); } void CefFrameHostImpl::Redo() { - SendCommand("Redo", nullptr); + SendCommand("Redo"); } void CefFrameHostImpl::Cut() { - SendCommand("Cut", nullptr); + SendCommand("Cut"); } void CefFrameHostImpl::Copy() { - SendCommand("Copy", nullptr); + SendCommand("Copy"); } void CefFrameHostImpl::Paste() { - SendCommand("Paste", nullptr); + SendCommand("Paste"); } void CefFrameHostImpl::Delete() { - SendCommand("Delete", nullptr); + SendCommand("Delete"); } void CefFrameHostImpl::SelectAll() { - SendCommand("SelectAll", nullptr); + SendCommand("SelectAll"); } void CefFrameHostImpl::ViewSource() { - SendCommand("GetSource", new ViewTextHandler(this)); + SendCommandWithResponse( + "GetSource", + base::BindOnce(&ViewTextCallback, CefRefPtr(this))); } void CefFrameHostImpl::GetSource(CefRefPtr visitor) { - SendCommand("GetSource", new StringVisitHandler(visitor)); + SendCommandWithResponse("GetSource", + base::BindOnce(&StringVisitCallback, visitor)); } void CefFrameHostImpl::GetText(CefRefPtr visitor) { - SendCommand("GetText", new StringVisitHandler(visitor)); + SendCommandWithResponse("GetText", + base::BindOnce(&StringVisitCallback, visitor)); } void CefFrameHostImpl::LoadRequest(CefRefPtr request) { - CefNavigateParams params(GURL(), kPageTransitionExplicit); + auto params = cef::mojom::RequestParams::New(); static_cast(request.get())->Get(params); - Navigate(params); + LoadRequest(std::move(params)); } void CefFrameHostImpl::LoadURL(const CefString& url) { @@ -257,21 +243,17 @@ void CefFrameHostImpl::SendProcessMessage( CefProcessId target_process, CefRefPtr message) { DCHECK_EQ(PID_RENDERER, target_process); - DCHECK(message.get()); - - Cef_Request_Params params; - CefProcessMessageImpl* impl = - static_cast(message.get()); - if (!impl->CopyTo(params)) + DCHECK(message && message->IsValid()); + if (!message || !message->IsValid()) return; - DCHECK(!params.name.empty()); - - params.user_initiated = true; - params.request_id = -1; - params.expect_response = false; - - Send(new CefMsg_Request(MSG_ROUTING_NONE, params)); + SendToRenderFrame(base::BindOnce( + [](CefRefPtr message, + const RenderFrameType& render_frame) { + auto impl = static_cast(message.get()); + render_frame->SendMessage(impl->GetName(), impl->TakeArgumentList()); + }, + message)); } void CefFrameHostImpl::SetFocused(bool focused) { @@ -304,27 +286,21 @@ void CefFrameHostImpl::RefreshAttributes() { } void CefFrameHostImpl::NotifyMoveOrResizeStarted() { - Send(new CefMsg_MoveOrResizeStarted(MSG_ROUTING_NONE)); + SendToRenderFrame(base::BindOnce([](const RenderFrameType& render_frame) { + render_frame->MoveOrResizeStarted(); + })); } -void CefFrameHostImpl::Navigate(const CefNavigateParams& params) { - CefMsg_LoadRequest_Params request; - - request.url = params.url; - if (!url_util::FixupGURL(request.url)) +void CefFrameHostImpl::LoadRequest(cef::mojom::RequestParamsPtr params) { + if (!url_util::FixupGURL(params->url)) return; - request.method = params.method; - request.referrer = params.referrer.url; - request.referrer_policy = - CefRequestImpl::BlinkReferrerPolicyToNetReferrerPolicy( - params.referrer.policy); - request.site_for_cookies = params.site_for_cookies; - request.headers = params.headers; - request.load_flags = params.load_flags; - request.upload_data = params.upload_data; - - Send(new CefMsg_LoadRequest(MSG_ROUTING_NONE, request)); + SendToRenderFrame(base::BindOnce( + [](cef::mojom::RequestParamsPtr params, + const RenderFrameType& render_frame) { + render_frame->LoadRequest(std::move(params)); + }, + std::move(params))); auto browser = GetBrowserHostBase(); if (browser) @@ -340,8 +316,8 @@ void CefFrameHostImpl::LoadURLWithExtras(const std::string& url, if (frame_id < CefFrameHostImpl::kMainFrameId) return; - // Any necessary fixup will occur in Navigate. - GURL gurl = url_util::MakeGURL(url, /*fixup=*/false); + // Any necessary fixup will occur in LoadRequest. + GURL gurl = url_util::MakeGURL(url, /*fixup=*/false); if (frame_id == CefFrameHostImpl::kMainFrameId) { // Load via the browser using NavigationController. @@ -355,102 +331,41 @@ void CefFrameHostImpl::LoadURLWithExtras(const std::string& url, browser->LoadMainFrameURL(params); } } else { - CefNavigateParams params(gurl, transition); - params.referrer = referrer; - params.headers = extra_headers; - Navigate(params); + auto params = cef::mojom::RequestParams::New(); + params->url = gurl; + params->referrer = + blink::mojom::Referrer::New(referrer.url, referrer.policy); + params->headers = extra_headers; + LoadRequest(std::move(params)); } } -void CefFrameHostImpl::SendCommand( - const std::string& command, - CefRefPtr responseHandler) { +void CefFrameHostImpl::SendCommand(const std::string& command) { DCHECK(!command.empty()); - - if (!CEF_CURRENTLY_ON_UIT()) { - CEF_POST_TASK(CEF_UIT, base::BindOnce(&CefFrameHostImpl::SendCommand, this, - command, responseHandler)); - return; - } - - // Only known frame ids or kMainFrameId are supported. - const auto frame_id = GetFrameId(); - if (frame_id < CefFrameHostImpl::kMainFrameId) - return; - - if (!render_frame_host_ || !response_manager_) { - // detached frame has no response_manager_ - return; - } - - TRACE_EVENT2("cef", "CefFrameHostImpl::SendCommand", "frame_id", frame_id, - "needsResponse", responseHandler.get() ? 1 : 0); - Cef_Request_Params params; - params.name = "execute-command"; - params.user_initiated = false; - - if (responseHandler.get()) { - params.request_id = response_manager_->RegisterHandler(responseHandler); - params.expect_response = true; - } else { - params.request_id = -1; - params.expect_response = false; - } - - params.arguments.AppendString(command); - - Send(new CefMsg_Request(MSG_ROUTING_NONE, params)); -} - -void CefFrameHostImpl::SendCode( - bool is_javascript, - const std::string& code, - const std::string& script_url, - int script_start_line, - CefRefPtr responseHandler) { - DCHECK(!code.empty()); - DCHECK_GE(script_start_line, 0); - - if (!CEF_CURRENTLY_ON_UIT()) { - CEF_POST_TASK(CEF_UIT, base::BindOnce(&CefFrameHostImpl::SendCode, this, - is_javascript, code, script_url, - script_start_line, responseHandler)); - return; - } - - // Only known frame ids or kMainFrameId are supported. - auto frame_id = GetFrameId(); - if (frame_id < CefFrameHostImpl::kMainFrameId) - return; - - if (!render_frame_host_ || !response_manager_) { - // detached frame has no response_manager_ - return; - } - - TRACE_EVENT2("cef", "CefFrameHostImpl::SendCommand", "frame_id", frame_id, - "needsResponse", responseHandler.get() ? 1 : 0); - Cef_Request_Params params; - params.name = "execute-code"; - params.user_initiated = false; - - if (responseHandler.get()) { - params.request_id = response_manager_->RegisterHandler(responseHandler); - params.expect_response = true; - } else { - params.request_id = -1; - params.expect_response = false; - } - - params.arguments.AppendBoolean(is_javascript); - params.arguments.AppendString(code); - params.arguments.AppendString(script_url); - params.arguments.AppendInteger(script_start_line); - - Send(new CefMsg_Request(MSG_ROUTING_NONE, params)); + SendToRenderFrame(base::BindOnce( + [](const std::string& command, const RenderFrameType& render_frame) { + render_frame->SendCommand(command); + }, + command)); } -void CefFrameHostImpl::SendJavaScript(const std::string& jsCode, +void CefFrameHostImpl::SendCommandWithResponse( + const std::string& command, + cef::mojom::RenderFrame::SendCommandWithResponseCallback + response_callback) { + DCHECK(!command.empty()); + SendToRenderFrame(base::BindOnce( + [](const std::string& command, + cef::mojom::RenderFrame::SendCommandWithResponseCallback + response_callback, + const RenderFrameType& render_frame) { + render_frame->SendCommandWithResponse(command, + std::move(response_callback)); + }, + command, std::move(response_callback))); +} + +void CefFrameHostImpl::SendJavaScript(const std::u16string& jsCode, const std::string& scriptUrl, int startLine) { if (jsCode.empty()) @@ -462,7 +377,12 @@ void CefFrameHostImpl::SendJavaScript(const std::string& jsCode, startLine = 1; } - SendCode(true, jsCode, scriptUrl, startLine, nullptr); + SendToRenderFrame(base::BindOnce( + [](const std::u16string& jsCode, const std::string& scriptUrl, + int startLine, const RenderFrameType& render_frame) { + render_frame->SendJavaScript(jsCode, scriptUrl, startLine); + }, + jsCode, scriptUrl, startLine)); } void CefFrameHostImpl::MaybeSendDidStopLoading() { @@ -478,22 +398,9 @@ void CefFrameHostImpl::MaybeSendDidStopLoading() { return; } - Send(new CefMsg_DidStopLoading(MSG_ROUTING_NONE)); -} - -bool CefFrameHostImpl::OnMessageReceived(const IPC::Message& message) { - bool handled = true; - IPC_BEGIN_MESSAGE_MAP(CefFrameHostImpl, message) - IPC_MESSAGE_HANDLER(CefHostMsg_FrameAttached, OnAttached) - IPC_MESSAGE_HANDLER(CefHostMsg_DidFinishLoad, OnDidFinishLoad) - IPC_MESSAGE_HANDLER(CefHostMsg_UpdateDraggableRegions, - OnUpdateDraggableRegions) - IPC_MESSAGE_HANDLER(CefHostMsg_Request, OnRequest) - IPC_MESSAGE_HANDLER(CefHostMsg_Response, OnResponse) - IPC_MESSAGE_HANDLER(CefHostMsg_ResponseAck, OnResponseAck) - IPC_MESSAGE_UNHANDLED(handled = false) - IPC_END_MESSAGE_MAP() - return handled; + SendToRenderFrame(base::BindOnce([](const RenderFrameType& render_frame) { + render_frame->DidStopLoading(); + })); } void CefFrameHostImpl::ExecuteJavaScriptWithUserGestureForTests( @@ -526,11 +433,11 @@ void CefFrameHostImpl::Detach() { } // In case we never attached, clean up. - while (!queued_messages_.empty()) { - queued_messages_.pop(); + while (!queued_actions_.empty()) { + queued_actions_.pop(); } - response_manager_.reset(); + render_frame_.reset(); render_frame_host_ = nullptr; } @@ -571,120 +478,108 @@ CefRefPtr CefFrameHostImpl::GetBrowserHostBase() const { return nullptr; } -void CefFrameHostImpl::OnAttached() { - if (!is_attached_) { - is_attached_ = true; - while (!queued_messages_.empty()) { - Send(queued_messages_.front().release()); - queued_messages_.pop(); - } - } -} +const mojo::Remote& +CefFrameHostImpl::GetRenderFrame() { + CEF_REQUIRE_UIT(); + DCHECK(is_attached_); -void CefFrameHostImpl::OnDidFinishLoad(const GURL& validated_url, - int http_status_code) { - auto browser = GetBrowserHostBase(); - if (browser) - browser->OnDidFinishLoad(this, validated_url, http_status_code); + if (!render_frame_.is_bound() && render_frame_host_ && + render_frame_host_->GetRemoteInterfaces()) { + // Connects to a CefFrameImpl that already exists in the renderer process. + render_frame_host_->GetRemoteInterfaces()->GetInterface( + render_frame_.BindNewPipeAndPassReceiver()); + } + return render_frame_; } -void CefFrameHostImpl::OnUpdateDraggableRegions( - const std::vector& regions) { - auto browser = GetBrowserHostBase(); - if (!browser) +void CefFrameHostImpl::SendToRenderFrame(RenderFrameAction action) { + if (!CEF_CURRENTLY_ON_UIT()) { + CEF_POST_TASK(CEF_UIT, base::BindOnce(&CefFrameHostImpl::SendToRenderFrame, + this, std::move(action))); return; + } - CefRefPtr handler; - auto client = browser->GetClient(); - if (client) - handler = client->GetDragHandler(); - if (!handler) + if (!render_frame_host_) { + // Either we're a placeholder frame without a renderer representation, or + // we've been detached. return; - - std::vector draggable_regions; - draggable_regions.reserve(regions.size()); - - std::vector::const_iterator it = regions.begin(); - for (; it != regions.end(); ++it) { - const gfx::Rect& rect(it->bounds); - const CefRect bounds(rect.x(), rect.y(), rect.width(), rect.height()); - draggable_regions.push_back(CefDraggableRegion(bounds, it->draggable)); } - handler->OnDraggableRegionsChanged(browser.get(), this, draggable_regions); -} + if (!is_attached_) { + // Queue actions until we're notified by the renderer that it's ready to + // handle them. + queued_actions_.push(std::move(action)); + return; + } -void CefFrameHostImpl::OnRequest(const Cef_Request_Params& params) { - CEF_REQUIRE_UIT(); + auto& render_frame = GetRenderFrame(); + if (!render_frame) + return; - bool success = false; - std::string response; - bool expect_response_ack = false; + std::move(action).Run(render_frame); +} - if (params.user_initiated) { - auto browser = GetBrowserHostBase(); - if (browser && browser->GetClient()) { - // Give the user a chance to handle the request. +void CefFrameHostImpl::SendMessage(const std::string& name, + base::Value arguments) { + if (auto browser = GetBrowserHostBase()) { + if (auto client = browser->GetClient()) { + auto& list_value = base::Value::AsListValue(arguments); CefRefPtr message(new CefProcessMessageImpl( - const_cast(¶ms), false, true)); - success = browser->GetClient()->OnProcessMessageReceived( + name, const_cast(&list_value), /*read_only=*/true)); + browser->GetClient()->OnProcessMessageReceived( browser.get(), this, PID_RENDERER, message.get()); - message->Detach(nullptr); + message->Detach(); } - } else { - // Invalid request. - NOTREACHED(); - } - - if (params.expect_response) { - DCHECK_GE(params.request_id, 0); - - // Send a response to the renderer. - Cef_Response_Params response_params; - response_params.request_id = params.request_id; - response_params.success = success; - response_params.response = response; - response_params.expect_response_ack = expect_response_ack; - Send(new CefMsg_Response(MSG_ROUTING_NONE, response_params)); } } -void CefFrameHostImpl::OnResponse(const Cef_Response_Params& params) { - CEF_REQUIRE_UIT(); +void CefFrameHostImpl::FrameAttached() { + if (!is_attached_) { + is_attached_ = true; - response_manager_->RunHandler(params); - if (params.expect_response_ack) - Send(new CefMsg_ResponseAck(MSG_ROUTING_NONE, params.request_id)); + auto& render_frame = GetRenderFrame(); + while (!queued_actions_.empty()) { + if (render_frame) { + std::move(queued_actions_.front()).Run(render_frame); + } + queued_actions_.pop(); + } + } } -void CefFrameHostImpl::OnResponseAck(int request_id) { - response_manager_->RunAckHandler(request_id); +void CefFrameHostImpl::DidFinishFrameLoad(const GURL& validated_url, + int http_status_code) { + auto browser = GetBrowserHostBase(); + if (browser) + browser->OnDidFinishLoad(this, validated_url, http_status_code); } -void CefFrameHostImpl::Send(IPC::Message* message) { - if (!CEF_CURRENTLY_ON_UIT()) { - CEF_POST_TASK(CEF_UIT, - base::BindOnce(base::IgnoreResult(&CefFrameHostImpl::Send), - this, message)); +void CefFrameHostImpl::UpdateDraggableRegions( + base::Optional> regions) { + auto browser = GetBrowserHostBase(); + if (!browser) return; - } - if (!render_frame_host_) { - // Either we're a placeholder frame without a renderer representation, or - // we've been detached. - delete message; + CefRefPtr handler; + auto client = browser->GetClient(); + if (client) + handler = client->GetDragHandler(); + if (!handler) return; - } - if (!is_attached_) { - // Queue messages until we're notified by the renderer that it's ready to - // handle them. - queued_messages_.push(base::WrapUnique(message)); - return; + std::vector draggable_regions; + if (regions) { + draggable_regions.reserve(regions->size()); + + for (const auto& region : *regions) { + const auto& rect = region->bounds; + const CefRect bounds(rect.x(), rect.y(), rect.width(), rect.height()); + draggable_regions.push_back( + CefDraggableRegion(bounds, region->draggable)); + } } - message->set_routing_id(render_frame_host_->GetRoutingID()); - render_frame_host_->Send(message); + handler->OnDraggableRegionsChanged(browser.get(), this, draggable_regions); } void CefExecuteJavaScriptWithUserGestureForTests(CefRefPtr frame, diff --git a/libcef/browser/frame_host_impl.h b/libcef/browser/frame_host_impl.h index 4d5167b40..89635beb4 100644 --- a/libcef/browser/frame_host_impl.h +++ b/libcef/browser/frame_host_impl.h @@ -11,9 +11,11 @@ #include #include "include/cef_frame.h" -#include "libcef/common/response_manager.h" #include "base/synchronization/lock.h" +#include "cef/libcef/common/mojom/cef.mojom.h" +#include "mojo/public/cpp/bindings/receiver_set.h" +#include "mojo/public/cpp/bindings/remote.h" #include "ui/base/page_transition_types.h" namespace content { @@ -21,22 +23,14 @@ class RenderFrameHost; struct Referrer; } // namespace content -namespace IPC { -class Message; -} - class GURL; -struct Cef_DraggableRegion_Params; -struct Cef_Request_Params; -struct Cef_Response_Params; class CefBrowserInfo; class CefBrowserHostBase; -struct CefNavigateParams; // Implementation of CefFrame. CefFrameHostImpl objects should always be created // or retrieved via CefBrowerInfo. -class CefFrameHostImpl : public CefFrame { +class CefFrameHostImpl : public CefFrame, public cef::mojom::BrowserFrame { public: // Create a temporary frame. CefFrameHostImpl(scoped_refptr browser_info, @@ -91,8 +85,8 @@ class CefFrameHostImpl : public CefFrame { // started. Used on Windows and Linux with the Alloy runtime. void NotifyMoveOrResizeStarted(); - // Navigate as specified by the |params| argument. - void Navigate(const CefNavigateParams& params); + // Load the specified request. + void LoadRequest(cef::mojom::RequestParamsPtr params); // Load the specified URL. void LoadURLWithExtras(const std::string& url, @@ -101,27 +95,20 @@ class CefFrameHostImpl : public CefFrame { const std::string& extra_headers); // Send a command to the renderer for execution. - void SendCommand(const std::string& command, - CefRefPtr responseHandler); - - // Send code to the renderer for execution. - void SendCode(bool is_javascript, - const std::string& code, - const std::string& script_url, - int script_start_line, - CefRefPtr responseHandler); + void SendCommand(const std::string& command); + void SendCommandWithResponse( + const std::string& command, + cef::mojom::RenderFrame::SendCommandWithResponseCallback + response_callback); // Send JavaScript to the renderer for execution. - void SendJavaScript(const std::string& jsCode, + void SendJavaScript(const std::u16string& jsCode, const std::string& scriptUrl, int startLine); // Called from CefBrowserHostBase::DidStopLoading. void MaybeSendDidStopLoading(); - // Called from CefBrowserHostBase::OnMessageReceived. - bool OnMessageReceived(const IPC::Message& message); - void ExecuteJavaScriptWithUserGestureForTests(const CefString& javascript); // Returns the RFH associated with this frame. Must be called on the UI @@ -133,6 +120,15 @@ class CefFrameHostImpl : public CefFrame { // implicitly via CefBrowserInfo::browser() returning nullptr. void Detach(); + // cef::mojom::BrowserFrame methods forwarded from CefBrowserFrame. + void SendMessage(const std::string& name, base::Value arguments) override; + void FrameAttached() override; + void DidFinishFrameLoad(const GURL& validated_url, + int32_t http_status_code) override; + void UpdateDraggableRegions( + base::Optional> regions) + override; + static int64_t MakeFrameId(const content::RenderFrameHost* host); static int64_t MakeFrameId(int32_t render_process_id, int32_t render_routing_id); @@ -151,17 +147,14 @@ class CefFrameHostImpl : public CefFrame { int64 GetFrameId() const; CefRefPtr GetBrowserHostBase() const; - // OnMessageReceived message handlers. - void OnAttached(); - void OnDidFinishLoad(const GURL& validated_url, int http_status_code); - void OnUpdateDraggableRegions( - const std::vector& regions); - void OnRequest(const Cef_Request_Params& params); - void OnResponse(const Cef_Response_Params& params); - void OnResponseAck(int request_id); + // Returns the remote RenderFrame object. + using RenderFrameType = mojo::Remote; + const RenderFrameType& GetRenderFrame(); - // Send a message to the RenderFrameHost associated with this frame. - void Send(IPC::Message* message); + // Send an action to the remote RenderFrame. This will queue the action if the + // remote frame is not yet attached. + using RenderFrameAction = base::OnceCallback; + void SendToRenderFrame(RenderFrameAction action); const bool is_main_frame_; @@ -180,11 +173,9 @@ class CefFrameHostImpl : public CefFrame { bool is_attached_ = false; - // Qeueud messages to send when the renderer process attaches. - std::queue> queued_messages_; + std::queue queued_actions_; - // Manages response registrations. - std::unique_ptr response_manager_; + mojo::Remote render_frame_; IMPLEMENT_REFCOUNTING(CefFrameHostImpl); DISALLOW_COPY_AND_ASSIGN(CefFrameHostImpl); diff --git a/libcef/browser/menu_manager.cc b/libcef/browser/menu_manager.cc index d1ccfa6f3..3bb0a3c72 100644 --- a/libcef/browser/menu_manager.cc +++ b/libcef/browser/menu_manager.cc @@ -173,7 +173,7 @@ bool CefMenuManager::CreateContextMenu( } // Do not keep references to the parameters in the callback. - paramsPtr->Detach(nullptr); + ignore_result(paramsPtr->Detach(nullptr)); DCHECK(paramsPtr->HasOneRef()); DCHECK(model_->VerifyRefCount()); @@ -215,7 +215,7 @@ void CefMenuManager::ExecuteCommand(CefRefPtr source, event_flags); // Do not keep references to the parameters in the callback. - paramsPtr->Detach(nullptr); + ignore_result(paramsPtr->Detach(nullptr)); DCHECK(paramsPtr->HasOneRef()); if (handled) diff --git a/libcef/browser/navigate_params.cc b/libcef/browser/navigate_params.cc deleted file mode 100644 index be925efaf..000000000 --- a/libcef/browser/navigate_params.cc +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) 2012 The Chromium Embedded Framework Authors. -// Portions copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "libcef/browser/navigate_params.h" - -CefNavigateParams::CefNavigateParams(const GURL& a_url, - ui::PageTransition a_transition) - : url(a_url), transition(a_transition) {} - -CefNavigateParams::~CefNavigateParams() {} diff --git a/libcef/browser/navigate_params.h b/libcef/browser/navigate_params.h deleted file mode 100644 index 12f82cf32..000000000 --- a/libcef/browser/navigate_params.h +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright (c) 2012 The Chromium Embedded Framework Authors. -// Portions copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CEF_LIBCEF_BROWSER_NAVIGATE_PARAMS_H_ -#define CEF_LIBCEF_BROWSER_NAVIGATE_PARAMS_H_ -#pragma once - -#include - -#include "libcef/common/net/upload_data.h" - -#include "content/public/browser/global_request_id.h" -#include "content/public/common/referrer.h" -#include "net/cookies/site_for_cookies.h" -#include "ui/base/page_transition_types.h" -#include "ui/base/window_open_disposition.h" -#include "url/gurl.h" - -// Parameters that tell CefFrameHostImpl::Navigate() what to do. -struct CefNavigateParams { - CefNavigateParams(const GURL& a_url, ui::PageTransition a_transition); - ~CefNavigateParams(); - - // The following parameters are sent to the renderer via CefMsg_LoadRequest. - // --------------------------------------------------------------------------- - - // Request method. - std::string method; - - // The URL/referrer to be loaded. - GURL url; - content::Referrer referrer; - - // Usually the URL of the document in the top-level window, which may be - // checked by the third-party cookie blocking policy. Leaving it empty may - // lead to undesired cookie blocking. Third-party cookie blocking can be - // bypassed by setting site_for_cookies = url, but this should ideally - // only be done if there really is no way to determine the correct value. - net::SiteForCookies site_for_cookies; - - // Additional HTTP request headers. - std::string headers; - - // net::URLRequest load flags (0 by default). - int load_flags = 0; - - // Upload data (may be NULL). - scoped_refptr upload_data; - - // The following parameters are used to define browser behavior when servicing - // the navigation request. - // --------------------------------------------------------------------------- - - // The disposition requested by the navigation source. Default is CURRENT_TAB. - WindowOpenDisposition disposition = WindowOpenDisposition::CURRENT_TAB; - - // The transition type of the navigation. - ui::PageTransition transition; - - // Whether this navigation was initiated by the renderer process. - bool is_renderer_initiated = false; - - // If non-empty, the new tab contents encoding is overriden by this value. - std::string override_encoding; - - // If false then the navigation was not initiated by a user gesture. Default - // is true. - bool user_gesture = true; - - // Refers to a navigation that was parked in the browser in order to be - // transferred to another RVH. Only used in case of a redirection of a request - // to a different site that created a new RVH. - content::GlobalRequestID transferred_global_request_id; - - private: - CefNavigateParams(); -}; - -#endif // CEF_LIBCEF_BROWSER_NAVIGATE_PARAMS_H_ diff --git a/libcef/browser/origin_whitelist_impl.cc b/libcef/browser/origin_whitelist_impl.cc index 1a8c74923..02c0dd2e5 100644 --- a/libcef/browser/origin_whitelist_impl.cc +++ b/libcef/browser/origin_whitelist_impl.cc @@ -8,13 +8,14 @@ #include #include "include/cef_origin_whitelist.h" +#include "libcef/browser/browser_manager.h" #include "libcef/browser/context.h" #include "libcef/browser/thread_util.h" -#include "libcef/common/cef_messages.h" #include "base/bind.h" #include "base/lazy_instance.h" #include "base/synchronization/lock.h" +#include "cef/libcef/common/mojom/cef.mojom.h" #include "chrome/common/webui_url_constants.h" #include "content/public/browser/render_process_host.h" #include "content/public/common/url_constants.h" @@ -36,23 +37,22 @@ class CefOriginWhitelistManager { const std::string& target_protocol, const std::string& target_domain, bool allow_target_subdomains) { - Cef_CrossOriginWhiteListEntry_Params info; - info.source_origin = source_origin; - info.target_protocol = target_protocol; - info.target_domain = target_domain; - info.allow_target_subdomains = allow_target_subdomains; + auto info = cef::mojom::CrossOriginWhiteListEntry::New(); + info->source_origin = source_origin; + info->target_protocol = target_protocol; + info->target_domain = target_domain; + info->allow_target_subdomains = allow_target_subdomains; { base::AutoLock lock_scope(lock_); // Verify that the origin entry doesn't already exist. - OriginList::const_iterator it = origin_list_.begin(); - for (; it != origin_list_.end(); ++it) { - if (IsEqual(*it, info)) + for (const auto& entry : origin_list_) { + if (entry == info) return false; } - origin_list_.push_back(info); + origin_list_.push_back(info->Clone()); } SendModifyCrossOriginWhitelistEntry(true, info); @@ -63,20 +63,20 @@ class CefOriginWhitelistManager { const std::string& target_protocol, const std::string& target_domain, bool allow_target_subdomains) { - Cef_CrossOriginWhiteListEntry_Params info; - info.source_origin = source_origin; - info.target_protocol = target_protocol; - info.target_domain = target_domain; - info.allow_target_subdomains = allow_target_subdomains; + auto info = cef::mojom::CrossOriginWhiteListEntry::New(); + info->source_origin = source_origin; + info->target_protocol = target_protocol; + info->target_domain = target_domain; + info->allow_target_subdomains = allow_target_subdomains; bool found = false; { base::AutoLock lock_scope(lock_); - OriginList::iterator it = origin_list_.begin(); + CrossOriginWhiteList::iterator it = origin_list_.begin(); for (; it != origin_list_.end(); ++it) { - if (IsEqual(*it, info)) { + if (*it == info) { origin_list_.erase(it); found = true; break; @@ -101,12 +101,30 @@ class CefOriginWhitelistManager { } void GetCrossOriginWhitelistEntries( - std::vector* entries) { + base::Optional* entries) const { base::AutoLock lock_scope(lock_); - if (origin_list_.empty()) - return; - entries->insert(entries->end(), origin_list_.begin(), origin_list_.end()); + if (!origin_list_.empty()) { + CrossOriginWhiteList vec; + for (const auto& entry : origin_list_) { + vec.push_back(entry->Clone()); + } + *entries = std::move(vec); + } + } + + bool HasCrossOriginWhitelistEntry(const url::Origin& source, + const url::Origin& target) const { + base::AutoLock lock_scope(lock_); + + if (!origin_list_.empty()) { + for (const auto& entry : origin_list_) { + if (IsMatch(source, target, entry)) + return true; + } + } + + return false; } private: @@ -114,14 +132,15 @@ class CefOriginWhitelistManager { // existing hosts. static void SendModifyCrossOriginWhitelistEntry( bool add, - Cef_CrossOriginWhiteListEntry_Params& params) { + const cef::mojom::CrossOriginWhiteListEntryPtr& info) { CEF_REQUIRE_UIT(); content::RenderProcessHost::iterator i( content::RenderProcessHost::AllHostsIterator()); for (; !i.IsAtEnd(); i.Advance()) { - i.GetCurrentValue()->Send( - new CefProcessMsg_ModifyCrossOriginWhitelistEntry(add, params)); + auto render_manager = + CefBrowserManager::GetRenderManagerForProcess(i.GetCurrentValue()); + render_manager->ModifyCrossOriginWhitelistEntry(add, info->Clone()); } } @@ -133,23 +152,44 @@ class CefOriginWhitelistManager { content::RenderProcessHost::iterator i( content::RenderProcessHost::AllHostsIterator()); for (; !i.IsAtEnd(); i.Advance()) { - i.GetCurrentValue()->Send(new CefProcessMsg_ClearCrossOriginWhitelist); + auto render_manager = + CefBrowserManager::GetRenderManagerForProcess(i.GetCurrentValue()); + render_manager->ClearCrossOriginWhitelist(); } } - static bool IsEqual(const Cef_CrossOriginWhiteListEntry_Params& param1, - const Cef_CrossOriginWhiteListEntry_Params& param2) { - return (param1.source_origin == param2.source_origin && - param1.target_protocol == param2.target_protocol && - param1.target_domain == param2.target_domain && - param1.allow_target_subdomains == param2.allow_target_subdomains); + static bool IsMatch(const url::Origin& source_origin, + const url::Origin& target_origin, + const cef::mojom::CrossOriginWhiteListEntryPtr& param) { + if (!source_origin.IsSameOriginWith( + url::Origin::Create(GURL(param->source_origin)))) { + // Source origin does not match. + return false; + } + + if (target_origin.scheme() != param->target_protocol) { + // Target scheme does not match. + return false; + } + + if (param->allow_target_subdomains) { + if (param->target_domain.empty()) { + // Any domain will match. + return true; + } else { + // Match sub-domains. + return target_origin.DomainIs(param->target_domain.c_str()); + } + } else { + // Match full domain. + return (target_origin.host() == param->target_domain); + } } - base::Lock lock_; + mutable base::Lock lock_; // List of registered origins. Access must be protected by |lock_|. - typedef std::vector OriginList; - OriginList origin_list_; + CrossOriginWhiteList origin_list_; DISALLOW_COPY_AND_ASSIGN(CefOriginWhitelistManager); }; @@ -161,34 +201,6 @@ CefOriginWhitelistManager* CefOriginWhitelistManager::GetInstance() { return g_manager.Pointer(); } -bool IsMatch(const url::Origin& source_origin, - const url::Origin& target_origin, - const Cef_CrossOriginWhiteListEntry_Params& param) { - if (!source_origin.IsSameOriginWith( - url::Origin::Create(GURL(param.source_origin)))) { - // Source origin does not match. - return false; - } - - if (target_origin.scheme() != param.target_protocol) { - // Target scheme does not match. - return false; - } - - if (param.allow_target_subdomains) { - if (param.target_domain.empty()) { - // Any domain will match. - return true; - } else { - // Match sub-domains. - return target_origin.DomainIs(param.target_domain.c_str()); - } - } else { - // Match full domain. - return (target_origin.host() == param.target_domain); - } -} - } // namespace bool CefAddCrossOriginWhitelistEntry(const CefString& source_origin, @@ -271,7 +283,7 @@ bool CefClearCrossOriginWhitelist() { } void GetCrossOriginWhitelistEntries( - std::vector* entries) { + base::Optional* entries) { CefOriginWhitelistManager::GetInstance()->GetCrossOriginWhitelistEntries( entries); } @@ -288,19 +300,6 @@ bool HasCrossOriginWhitelistEntry(const url::Origin& source, return true; } - std::vector params; - CefOriginWhitelistManager::GetInstance()->GetCrossOriginWhitelistEntries( - ¶ms); - - if (params.empty()) - return false; - - std::vector::const_iterator it = - params.begin(); - for (; it != params.end(); ++it) { - if (IsMatch(source, target, *it)) - return true; - } - - return false; + return CefOriginWhitelistManager::GetInstance()->HasCrossOriginWhitelistEntry( + source, target); } diff --git a/libcef/browser/origin_whitelist_impl.h b/libcef/browser/origin_whitelist_impl.h index 3136cad1c..fbc9d0d61 100644 --- a/libcef/browser/origin_whitelist_impl.h +++ b/libcef/browser/origin_whitelist_impl.h @@ -5,9 +5,12 @@ #ifndef CEF_LIBCEF_BROWSER_ORIGIN_WHITELIST_IMPL_H_ #define CEF_LIBCEF_BROWSER_ORIGIN_WHITELIST_IMPL_H_ -#include #include +#include "base/optional.h" + +#include "cef/libcef/common/mojom/cef.mojom-forward.h" + namespace content { class RenderProcessHost; } @@ -16,12 +19,13 @@ namespace url { class Origin; } -struct Cef_CrossOriginWhiteListEntry_Params; +using CrossOriginWhiteList = + std::vector; // Called to retrieve the current list of cross-origin white list entries. This // method is thread safe. void GetCrossOriginWhitelistEntries( - std::vector* entries); + base::Optional* entries); // Returns true if |source| can access |target| based on the cross-origin white // list settings. diff --git a/libcef/browser/print_settings_impl.cc b/libcef/browser/print_settings_impl.cc index 573c95c96..af7d76d01 100644 --- a/libcef/browser/print_settings_impl.cc +++ b/libcef/browser/print_settings_impl.cc @@ -11,12 +11,12 @@ CefPrintSettingsImpl::CefPrintSettingsImpl( std::unique_ptr settings, bool read_only) - : CefValueBase(settings.get(), - nullptr, - kOwnerNoDelete, - read_only, - nullptr), - settings_(std::move(settings)) {} + : CefValueBase( + settings.release(), + nullptr, + kOwnerWillDelete, + read_only, + nullptr) {} bool CefPrintSettingsImpl::IsValid() { return !detached(); @@ -152,8 +152,7 @@ CefPrintSettings::DuplexMode CefPrintSettingsImpl::GetDuplexMode() { } std::unique_ptr CefPrintSettingsImpl::TakeOwnership() { - Detach(nullptr); - return std::move(settings_); + return base::WrapUnique(Detach(nullptr)); } // CefPrintSettings implementation. diff --git a/libcef/browser/print_settings_impl.h b/libcef/browser/print_settings_impl.h index 589048eb7..a12d92f4d 100644 --- a/libcef/browser/print_settings_impl.h +++ b/libcef/browser/print_settings_impl.h @@ -47,8 +47,6 @@ class CefPrintSettingsImpl std::unique_ptr TakeOwnership() WARN_UNUSED_RESULT; private: - std::unique_ptr settings_; - DISALLOW_COPY_AND_ASSIGN(CefPrintSettingsImpl); }; diff --git a/libcef/browser/printing/print_view_manager.h b/libcef/browser/printing/print_view_manager.h index 31b9c260f..14843f869 100644 --- a/libcef/browser/printing/print_view_manager.h +++ b/libcef/browser/printing/print_view_manager.h @@ -21,8 +21,6 @@ class WebContentsObserver; class CefBrowserInfo; -struct PrintHostMsg_RequestPrintPreview_Params; - namespace printing { // CEF handler for print commands. diff --git a/libcef/common/alloy/alloy_main_delegate.cc b/libcef/common/alloy/alloy_main_delegate.cc index ba5b08cd7..bc5edc3b0 100644 --- a/libcef/common/alloy/alloy_main_delegate.cc +++ b/libcef/common/alloy/alloy_main_delegate.cc @@ -37,7 +37,6 @@ #include "content/public/common/content_switches.h" #include "content/public/common/main_function_params.h" #include "extensions/common/constants.h" -#include "ipc/ipc_buildflags.h" #include "net/base/features.h" #include "pdf/pdf_ppapi.h" #include "sandbox/policy/switches.h" @@ -51,14 +50,6 @@ #include "libcef/common/util_mac.h" #endif -#if BUILDFLAG(IPC_MESSAGE_LOG_ENABLED) -#define IPC_MESSAGE_MACROS_LOG_ENABLED -#include "content/public/common/content_ipc_logging.h" -#define IPC_LOG_TABLE_ADD_ENTRY(msg_id, logger) \ - content::RegisterIPCLogger(msg_id, logger) -#include "libcef/common/cef_message_generator.h" -#endif - namespace { const char* const kNonWildcardDomainNonPortSchemes[] = { @@ -302,7 +293,7 @@ bool AlloyMainDelegate::BasicStartupComplete(int* exit_code) { new CefCommandLineImpl(command_line, false, false)); application_->OnBeforeCommandLineProcessing(CefString(process_type), commandLinePtr.get()); - commandLinePtr->Detach(nullptr); + ignore_result(commandLinePtr->Detach(nullptr)); } // Initialize logging. diff --git a/libcef/common/cef_message_generator.cc b/libcef/common/cef_message_generator.cc deleted file mode 100644 index ee49889ba..000000000 --- a/libcef/common/cef_message_generator.cc +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Get basic type definitions. -#define IPC_MESSAGE_IMPL -#include "libcef/common/cef_message_generator.h" - -// Generate constructors. -#include "chrome/common/safe_browsing/ipc_protobuf_message_null_macros.h" -#include "ipc/struct_constructor_macros.h" -#include "libcef/common/cef_message_generator.h" - -// Generate param traits write methods. -#include "chrome/common/safe_browsing/protobuf_message_write_macros.h" -#include "ipc/param_traits_write_macros.h" -namespace IPC { -#include "libcef/common/cef_message_generator.h" -} // namespace IPC - -// Generate param traits read methods. -#include "chrome/common/safe_browsing/protobuf_message_read_macros.h" -#include "ipc/param_traits_read_macros.h" -namespace IPC { -#include "libcef/common/cef_message_generator.h" -} // namespace IPC - -// Generate param traits log methods. -#include "chrome/common/safe_browsing/protobuf_message_log_macros.h" -#include "ipc/param_traits_log_macros.h" -namespace IPC { -#include "libcef/common/cef_message_generator.h" -} // namespace IPC diff --git a/libcef/common/cef_message_generator.h b/libcef/common/cef_message_generator.h deleted file mode 100644 index 124361160..000000000 --- a/libcef/common/cef_message_generator.h +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Multiply-included file, hence no include guard. - -#include "libcef/common/cef_messages.h" diff --git a/libcef/common/cef_messages.cc b/libcef/common/cef_messages.cc deleted file mode 100644 index b2ebf631a..000000000 --- a/libcef/common/cef_messages.cc +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright (c) 2012 The Chromium 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/common/cef_messages.h" - -namespace IPC { - -// Extracted from chrome/common/automation_messages.cc. - -// Only the net::UploadData ParamTraits<> definition needs this definition, so -// keep this in the implementation file so we can forward declare UploadData in -// the header. -template <> -struct ParamTraits { - typedef net::UploadElement param_type; - static void Write(base::Pickle* m, const param_type& p) { - WriteParam(m, static_cast(p.type())); - switch (p.type()) { - case net::UploadElement::TYPE_BYTES: { - m->WriteData(p.bytes(), static_cast(p.bytes_length())); - break; - } - default: { - DCHECK(p.type() == net::UploadElement::TYPE_FILE); - WriteParam(m, p.file_path()); - WriteParam(m, p.file_range_offset()); - WriteParam(m, p.file_range_length()); - WriteParam(m, p.expected_file_modification_time()); - break; - } - } - } - static bool Read(const base::Pickle* m, - base::PickleIterator* iter, - param_type* r) { - int type; - if (!ReadParam(m, iter, &type)) - return false; - switch (type) { - case net::UploadElement::TYPE_BYTES: { - const char* data; - int len; - if (!iter->ReadData(&data, &len)) - return false; - r->SetToBytes(data, len); - break; - } - default: { - DCHECK(type == net::UploadElement::TYPE_FILE); - base::FilePath file_path; - uint64_t offset, length; - base::Time expected_modification_time; - if (!ReadParam(m, iter, &file_path)) - return false; - if (!ReadParam(m, iter, &offset)) - return false; - if (!ReadParam(m, iter, &length)) - return false; - if (!ReadParam(m, iter, &expected_modification_time)) - return false; - r->SetToFilePathRange(file_path, offset, length, - expected_modification_time); - break; - } - } - return true; - } - static void Log(const param_type& p, std::string* l) { - l->append(""); - } -}; - -void ParamTraits>::Write(base::Pickle* m, - const param_type& p) { - WriteParam(m, p.get() != nullptr); - if (p.get()) { - WriteParam(m, p->elements()); - WriteParam(m, p->identifier()); - WriteParam(m, p->is_chunked()); - WriteParam(m, p->last_chunk_appended()); - } -} - -bool ParamTraits>::Read( - const base::Pickle* m, - base::PickleIterator* iter, - param_type* r) { - bool has_object; - if (!ReadParam(m, iter, &has_object)) - return false; - if (!has_object) - return true; - net::UploadData::ElementsVector elements; - if (!ReadParam(m, iter, &elements)) - return false; - int64_t identifier; - if (!ReadParam(m, iter, &identifier)) - return false; - bool is_chunked = false; - if (!ReadParam(m, iter, &is_chunked)) - return false; - bool last_chunk_appended = false; - if (!ReadParam(m, iter, &last_chunk_appended)) - return false; - *r = new net::UploadData; - (*r)->swap_elements(&elements); - (*r)->set_identifier(identifier); - (*r)->set_is_chunked(is_chunked); - (*r)->set_last_chunk_appended(last_chunk_appended); - return true; -} - -void ParamTraits>::Log(const param_type& p, - std::string* l) { - l->append(""); -} - -} // namespace IPC diff --git a/libcef/common/cef_messages.h b/libcef/common/cef_messages.h deleted file mode 100644 index 82f161dd6..000000000 --- a/libcef/common/cef_messages.h +++ /dev/null @@ -1,209 +0,0 @@ -// Copyright (c) 2012 The Chromium Embedded Framework Authors. -// Portions copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// IPC messages for CEF. -// Multiply-included message file, hence no include guard. - -#include - -#include "libcef/common/net/upload_data.h" - -#include "base/memory/shared_memory_mapping.h" -#include "base/values.h" -#include "content/public/common/common_param_traits.h" -#include "content/public/common/referrer.h" -#include "ipc/ipc_message_macros.h" -#include "ui/gfx/ipc/gfx_param_traits.h" - -// Singly-included section for enums and custom IPC traits. -#ifndef CEF_LIBCEF_COMMON_CEF_MESSAGES_H_ -#define CEF_LIBCEF_COMMON_CEF_MESSAGES_H_ - -namespace IPC { - -// Extracted from chrome/common/automation_messages.h. -template <> -struct ParamTraits> { - typedef scoped_refptr param_type; - static void Write(base::Pickle* m, const param_type& p); - static bool Read(const base::Pickle* m, - base::PickleIterator* iter, - param_type* r); - static void Log(const param_type& p, std::string* l); -}; - -} // namespace IPC - -#endif // CEF_LIBCEF_COMMON_CEF_MESSAGES_H_ - -// TODO(cef): Re-using the message start for extensions may be problematic in -// the future. It would be better if ipc_message_utils.h contained a value -// reserved for consumers of the content API. -// See: http://crbug.com/110911 -#define IPC_MESSAGE_START ExtensionMsgStart - -// Common types. - -// Parameters structure for a request. -IPC_STRUCT_BEGIN(Cef_Request_Params) - // Unique request id to match requests and responses. - IPC_STRUCT_MEMBER(int, request_id) - - // True if the request is user-initiated instead of internal. - IPC_STRUCT_MEMBER(bool, user_initiated) - - // True if a response is expected. - IPC_STRUCT_MEMBER(bool, expect_response) - - // Message name. - IPC_STRUCT_MEMBER(std::string, name) - - // List of message arguments. - IPC_STRUCT_MEMBER(base::ListValue, arguments) -IPC_STRUCT_END() - -// Parameters structure for a response. -IPC_STRUCT_BEGIN(Cef_Response_Params) - // Unique request id to match requests and responses. - IPC_STRUCT_MEMBER(int, request_id) - - // True if a response ack is expected. - IPC_STRUCT_MEMBER(bool, expect_response_ack) - - // True on success. - IPC_STRUCT_MEMBER(bool, success) - - // Response or error string depending on the value of |success|. - IPC_STRUCT_MEMBER(std::string, response) -IPC_STRUCT_END() - -// Parameters structure for a cross-origin white list entry. -IPC_STRUCT_BEGIN(Cef_CrossOriginWhiteListEntry_Params) - IPC_STRUCT_MEMBER(std::string, source_origin) - IPC_STRUCT_MEMBER(std::string, target_protocol) - IPC_STRUCT_MEMBER(std::string, target_domain) - IPC_STRUCT_MEMBER(bool, allow_target_subdomains) -IPC_STRUCT_END() - -// Parameters structure for a draggable region. -IPC_STRUCT_BEGIN(Cef_DraggableRegion_Params) - IPC_STRUCT_MEMBER(gfx::Rect, bounds) - IPC_STRUCT_MEMBER(bool, draggable) -IPC_STRUCT_END() - -// Messages sent from the browser to the renderer. - -// Parameters for a resource request. -IPC_STRUCT_BEGIN(CefMsg_LoadRequest_Params) - // The request method: GET, POST, etc. - IPC_STRUCT_MEMBER(std::string, method) - - // The requested URL. - IPC_STRUCT_MEMBER(GURL, url) - - // The URL to send in the "Referer" header field. Can be empty if there is - // no referrer. - IPC_STRUCT_MEMBER(GURL, referrer) - // One of the cef_referrer_policy_t values. - IPC_STRUCT_MEMBER(int, referrer_policy) - - // Usually the URL of the document in the top-level window, which may be - // checked by the third-party cookie blocking policy. Leaving it empty may - // lead to undesired cookie blocking. Third-party cookie blocking can be - // bypassed by setting site_for_cookies = url, but this should ideally - // only be done if there really is no way to determine the correct value. - IPC_STRUCT_MEMBER(net::SiteForCookies, site_for_cookies) - - // Additional HTTP request headers. - IPC_STRUCT_MEMBER(std::string, headers) - - // net::URLRequest load flags (0 by default). - IPC_STRUCT_MEMBER(int, load_flags) - - // Optional upload data (may be null). - IPC_STRUCT_MEMBER(scoped_refptr, upload_data) -IPC_STRUCT_END() - -// Tell the renderer to load a request. -IPC_MESSAGE_ROUTED1(CefMsg_LoadRequest, CefMsg_LoadRequest_Params) - -// Sent when the browser has a request for the renderer. The renderer may -// respond with a CefHostMsg_Response. -IPC_MESSAGE_ROUTED1(CefMsg_Request, Cef_Request_Params) - -// Optional message sent in response to a CefHostMsg_Request. -IPC_MESSAGE_ROUTED1(CefMsg_Response, Cef_Response_Params) - -// Optional Ack message sent to the browser to notify that a CefHostMsg_Response -// has been processed. -IPC_MESSAGE_ROUTED1(CefMsg_ResponseAck, int /* request_id */) - -// Tells the renderer that loading has stopped. -IPC_MESSAGE_ROUTED0(CefMsg_DidStopLoading) - -// Notification that a move or resize of the renderer's containing window has -// started. Used on Windows and Linux with the Alloy runtime, and was -// previously handled by RenderViewHost::NotifyMoveOrResizeStarted() prior to -// that method's removal in https://crbug.com/1051648. -IPC_MESSAGE_ROUTED0(CefMsg_MoveOrResizeStarted) - -// Sent to child processes to add or remove a cross-origin whitelist entry. -IPC_MESSAGE_CONTROL2(CefProcessMsg_ModifyCrossOriginWhitelistEntry, - bool /* add */, - Cef_CrossOriginWhiteListEntry_Params /* params */) - -// Sent to child processes to clear the cross-origin whitelist. -IPC_MESSAGE_CONTROL0(CefProcessMsg_ClearCrossOriginWhitelist) - -// Messages sent from the renderer to the browser. - -// Parameters for a newly created render thread. -IPC_STRUCT_BEGIN(CefProcessHostMsg_GetNewRenderThreadInfo_Params) - IPC_STRUCT_MEMBER(std::vector, - cross_origin_whitelist_entries) -IPC_STRUCT_END() - -// Retrieve information about a newly created render thread. -IPC_SYNC_MESSAGE_CONTROL0_1( - CefProcessHostMsg_GetNewRenderThreadInfo, - CefProcessHostMsg_GetNewRenderThreadInfo_Params /* params*/) - -// Parameters for a newly created browser window. -IPC_STRUCT_BEGIN(CefProcessHostMsg_GetNewBrowserInfo_Params) - IPC_STRUCT_MEMBER(int, browser_id) - IPC_STRUCT_MEMBER(bool, is_popup) - IPC_STRUCT_MEMBER(bool, is_windowless) - IPC_STRUCT_MEMBER(bool, is_guest_view) - IPC_STRUCT_MEMBER(base::DictionaryValue, extra_info) -IPC_STRUCT_END() - -// Retrieve information about a newly created browser. -IPC_SYNC_MESSAGE_CONTROL1_1( - CefProcessHostMsg_GetNewBrowserInfo, - int /* render_frame_routing_id */, - CefProcessHostMsg_GetNewBrowserInfo_Params /* params*/) - -// Sent by the renderer when the frame can begin receiving messages. -IPC_MESSAGE_ROUTED0(CefHostMsg_FrameAttached) - -// Sent when a frame has finished loading. Based on ViewHostMsg_DidFinishLoad. -IPC_MESSAGE_ROUTED2(CefHostMsg_DidFinishLoad, - GURL /* validated_url */, - int /* http_status_code */) - -// Sent when the renderer has a request for the browser. The browser may respond -// with a CefMsg_Response. -IPC_MESSAGE_ROUTED1(CefHostMsg_Request, Cef_Request_Params) - -// Optional message sent in response to a CefMsg_Request. -IPC_MESSAGE_ROUTED1(CefHostMsg_Response, Cef_Response_Params) - -// Optional Ack message sent to the browser to notify that a CefMsg_Response -// has been processed. -IPC_MESSAGE_ROUTED1(CefHostMsg_ResponseAck, int /* request_id */) - -// Sent by the renderer when the draggable regions are updated. -IPC_MESSAGE_ROUTED1(CefHostMsg_UpdateDraggableRegions, - std::vector /* regions */) diff --git a/libcef/common/chrome/chrome_main_delegate_cef.cc b/libcef/common/chrome/chrome_main_delegate_cef.cc index 8469922e6..c8bf98f34 100644 --- a/libcef/common/chrome/chrome_main_delegate_cef.cc +++ b/libcef/common/chrome/chrome_main_delegate_cef.cc @@ -122,7 +122,7 @@ bool ChromeMainDelegateCef::BasicStartupComplete(int* exit_code) { new CefCommandLineImpl(command_line, false, false)); application_->OnBeforeCommandLineProcessing(process_type, commandLinePtr.get()); - commandLinePtr->Detach(nullptr); + ignore_result(commandLinePtr->Detach(nullptr)); } #if defined(OS_MAC) diff --git a/libcef/common/mojom/BUILD.gn b/libcef/common/mojom/BUILD.gn new file mode 100644 index 000000000..a8b59b55f --- /dev/null +++ b/libcef/common/mojom/BUILD.gn @@ -0,0 +1,29 @@ +# Copyright 2021 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. + +import("//mojo/public/tools/bindings/mojom.gni") + +mojom("mojom") { + sources = [ "cef.mojom" ] + + cpp_only = true + disable_variants = true + + public_deps = [ + "//content/public/common:interfaces", + "//mojo/public/mojom/base", + "//services/network/public/mojom:cookies_mojom", + "//services/network/public/mojom:url_loader_base", + "//third_party/blink/public/mojom:mojom_platform", + "//ui/gfx/geometry/mojom", + "//url/mojom:url_mojom_gurl", + ] + + overridden_deps = [ + "//content/public/common:interfaces", + "//third_party/blink/public/mojom:mojom_platform", + ] + + component_deps = [ "//content/public/common" ] +} diff --git a/libcef/common/mojom/cef.mojom b/libcef/common/mojom/cef.mojom new file mode 100644 index 000000000..821cc92f9 --- /dev/null +++ b/libcef/common/mojom/cef.mojom @@ -0,0 +1,129 @@ +// Copyright 2021 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. + +module cef.mojom; + +import "mojo/public/mojom/base/shared_memory.mojom"; +import "mojo/public/mojom/base/string16.mojom"; +import "mojo/public/mojom/base/values.mojom"; +import "services/network/public/mojom/site_for_cookies.mojom"; +import "services/network/public/mojom/url_request.mojom"; +import "third_party/blink/public/mojom/loader/referrer.mojom"; +import "ui/gfx/geometry/mojom/geometry.mojom"; +import "url/mojom/url.mojom"; + +// Structure passed to UpdateDraggableRegions(). +struct DraggableRegionEntry { + gfx.mojom.Rect bounds; + bool draggable; +}; + +// Interface for communicating with a frame in the browser process. +interface BrowserFrame { + // Send a message to the browser process. + SendMessage(string name, mojo_base.mojom.ListValue arguments); + + // The render frame is ready to begin handling actions. + FrameAttached(); + + // The render frame has finished loading. + DidFinishFrameLoad(url.mojom.Url validated_url, int32 http_status_code); + + // Draggable regions have updated. + UpdateDraggableRegions(array? regions); +}; + +// Structure passed to LoadRequest(). +struct RequestParams { + // Request method. + string method; + + // The URL to be loaded. + url.mojom.Url url; + + // The referrer for the request. + blink.mojom.Referrer referrer; + + // Usually the URL of the document in the top-level window, which may be + // checked by the third-party cookie blocking policy. Leaving it empty may + // lead to undesired cookie blocking. Third-party cookie blocking can be + // bypassed by setting site_for_cookies = url, but this should ideally + // only be done if there really is no way to determine the correct value. + network.mojom.SiteForCookies site_for_cookies; + + // Additional HTTP request headers. + string headers; + + // net::URLRequest load flags (0 by default). + int32 load_flags; + + // Upload data (may be empty). + network.mojom.URLRequestBody? upload_data; +}; + +// Interface for communicating with a frame in the renderer process. +interface RenderFrame { + // Send a message to the render process. + SendMessage(string name, mojo_base.mojom.ListValue arguments); + + // Send a command. + SendCommand(string command); + + // Send a command that returns an async response. + // The returned |response| format is command-specific and will be invalid if + // an error occurred. + SendCommandWithResponse(string command) => + (mojo_base.mojom.ReadOnlySharedMemoryRegion? response); + + // Send JavaScript for execution. + SendJavaScript(mojo_base.mojom.String16 jsCode, string scriptUrl, + int32 startLine); + + // Load a request. + LoadRequest(RequestParams params); + + // Loading has stopped. + DidStopLoading(); + + // Move or resize of the renderer's containing window has started. Used on + // Windows and Linux with the Alloy runtime. + MoveOrResizeStarted(); +}; + +struct CrossOriginWhiteListEntry { + string source_origin; + string target_protocol; + string target_domain; + bool allow_target_subdomains; +}; + +struct NewRenderThreadInfo { + array? cross_origin_whitelist_entries; +}; + +struct NewBrowserInfo { + int32 browser_id; + bool is_popup; + bool is_windowless; + bool is_guest_view; + mojo_base.mojom.DictionaryValue? extra_info; +}; + +// Interface for communicating with browser management in the browser process. +interface BrowserManager { + // Retrieve info for a new RenderThread. + [Sync] + GetNewRenderThreadInfo() => (NewRenderThreadInfo info); + + // Retrieve info for a new CefBrowser. + [Sync] + GetNewBrowserInfo(int32 render_frame_routing_id) => (NewBrowserInfo info); +}; + +// Interface for communicating with browser management to the render process. +interface RenderManager { + // Manage cross-origin whitelist contents during the render process lifespan. + ModifyCrossOriginWhitelistEntry(bool add, CrossOriginWhiteListEntry entry); + ClearCrossOriginWhitelist(); +}; diff --git a/libcef/common/net/upload_data.cc b/libcef/common/net/upload_data.cc deleted file mode 100644 index a3ca8ed98..000000000 --- a/libcef/common/net/upload_data.cc +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "cef/libcef/common/net/upload_data.h" - -#include "base/logging.h" -#include "base/memory/ptr_util.h" - -namespace net { - -UploadData::UploadData() - : identifier_(0), is_chunked_(false), last_chunk_appended_(false) {} - -void UploadData::AppendBytes(const char* bytes, int bytes_len) { - DCHECK(!is_chunked_); - if (bytes_len > 0) { - elements_.push_back(std::make_unique()); - elements_.back()->SetToBytes(bytes, bytes_len); - } -} - -void UploadData::AppendFileRange(const base::FilePath& file_path, - uint64_t offset, - uint64_t length, - const base::Time& expected_modification_time) { - DCHECK(!is_chunked_); - elements_.push_back(std::make_unique()); - elements_.back()->SetToFilePathRange(file_path, offset, length, - expected_modification_time); -} - -UploadData::~UploadData() {} - -} // namespace net diff --git a/libcef/common/net/upload_data.h b/libcef/common/net/upload_data.h deleted file mode 100644 index ef6c96041..000000000 --- a/libcef/common/net/upload_data.h +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright (c) 2012 The Chromium 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_COMMON_NET_UPLOAD_DATA_H_ -#define CEF_LIBCEF_COMMON_NET_UPLOAD_DATA_H_ - -#include - -#include -#include - -#include "libcef/common/net/upload_element.h" - -#include "base/memory/ref_counted.h" -#include "base/supports_user_data.h" -#include "net/base/net_export.h" - -namespace base { -class FilePath; -class Time; -} // namespace base - -namespace net { - -//----------------------------------------------------------------------------- -// A very concrete class representing the data to be uploaded as part of a -// URLRequest. -// -// Until there is a more abstract class for this, this one derives from -// SupportsUserData to allow users to stash random data by -// key and ensure its destruction when UploadData is finally deleted. -class UploadData : public base::RefCounted, - public base::SupportsUserData { - public: - UploadData(); - - void AppendBytes(const char* bytes, int bytes_len); - - void AppendFileRange(const base::FilePath& file_path, - uint64_t offset, - uint64_t length, - const base::Time& expected_modification_time); - - // Initializes the object to send chunks of upload data over time rather - // than all at once. Chunked data may only contain bytes, not files. - void set_is_chunked(bool set) { is_chunked_ = set; } - bool is_chunked() const { return is_chunked_; } - - // set_last_chunk_appended() is only used for serialization. - void set_last_chunk_appended(bool set) { last_chunk_appended_ = set; } - bool last_chunk_appended() const { return last_chunk_appended_; } - - using ElementsVector = std::vector>; - - const ElementsVector& elements() const { return elements_; } - - ElementsVector* elements_mutable() { return &elements_; } - - void swap_elements(ElementsVector* elements) { elements_.swap(*elements); } - - // Identifies a particular upload instance, which is used by the cache to - // formulate a cache key. This value should be unique across browser - // sessions. A value of 0 is used to indicate an unspecified identifier. - void set_identifier(int64_t id) { identifier_ = id; } - int64_t identifier() const { return identifier_; } - - private: - friend class base::RefCounted; - - ~UploadData() override; - - ElementsVector elements_; - int64_t identifier_; - bool is_chunked_; - bool last_chunk_appended_; - - DISALLOW_COPY_AND_ASSIGN(UploadData); -}; - -} // namespace net - -#endif // CEF_LIBCEF_COMMON_NET_UPLOAD_DATA_H_ diff --git a/libcef/common/net/upload_element.cc b/libcef/common/net/upload_element.cc deleted file mode 100644 index 1a401bc18..000000000 --- a/libcef/common/net/upload_element.cc +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) 2012 The Chromium 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/common/net/upload_element.h" - -#include "net/base/file_stream.h" -#include "net/base/net_errors.h" - -namespace net { - -UploadElement::UploadElement() - : type_(TYPE_BYTES), - bytes_start_(nullptr), - bytes_length_(0), - file_range_offset_(0), - file_range_length_(std::numeric_limits::max()) {} - -UploadElement::~UploadElement() {} - -} // namespace net diff --git a/libcef/common/net/upload_element.h b/libcef/common/net/upload_element.h deleted file mode 100644 index 8d0f0d3e9..000000000 --- a/libcef/common/net/upload_element.h +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright (c) 2012 The Chromium 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_COMMON_NET_UPLOAD_ELEMENT_H_ -#define CEF_LIBCEF_COMMON_NET_UPLOAD_ELEMENT_H_ - -#include - -#include -#include - -#include "base/files/file_path.h" -#include "base/macros.h" -#include "base/time/time.h" -#include "net/base/net_export.h" - -namespace net { - -// A class representing an element contained by UploadData. -class UploadElement { - public: - enum Type { - TYPE_BYTES, - TYPE_FILE, - }; - - UploadElement(); - ~UploadElement(); - - Type type() const { return type_; } - - const char* bytes() const { return bytes_start_ ? bytes_start_ : &buf_[0]; } - uint64_t bytes_length() const { return buf_.size() + bytes_length_; } - const base::FilePath& file_path() const { return file_path_; } - uint64_t file_range_offset() const { return file_range_offset_; } - uint64_t file_range_length() const { return file_range_length_; } - // If NULL time is returned, we do not do the check. - const base::Time& expected_file_modification_time() const { - return expected_file_modification_time_; - } - - void SetToBytes(const char* bytes, int bytes_len) { - type_ = TYPE_BYTES; - buf_.assign(bytes, bytes + bytes_len); - } - - // This does not copy the given data and the caller should make sure - // the data is secured somewhere else (e.g. by attaching the data - // using SetUserData). - void SetToSharedBytes(const char* bytes, int bytes_len) { - type_ = TYPE_BYTES; - bytes_start_ = bytes; - bytes_length_ = bytes_len; - } - - void SetToFilePath(const base::FilePath& path) { - SetToFilePathRange(path, 0, std::numeric_limits::max(), - base::Time()); - } - - // If expected_modification_time is NULL, we do not check for the file - // change. Also note that the granularity for comparison is time_t, not - // the full precision. - void SetToFilePathRange(const base::FilePath& path, - uint64_t offset, - uint64_t length, - const base::Time& expected_modification_time) { - type_ = TYPE_FILE; - file_path_ = path; - file_range_offset_ = offset; - file_range_length_ = length; - expected_file_modification_time_ = expected_modification_time; - } - - private: - Type type_; - std::vector buf_; - const char* bytes_start_; - uint64_t bytes_length_; - base::FilePath file_path_; - uint64_t file_range_offset_; - uint64_t file_range_length_; - base::Time expected_file_modification_time_; - - DISALLOW_COPY_AND_ASSIGN(UploadElement); -}; - -#if defined(UNIT_TEST) -inline bool operator==(const UploadElement& a, const UploadElement& b) { - if (a.type() != b.type()) - return false; - if (a.type() == UploadElement::TYPE_BYTES) - return a.bytes_length() == b.bytes_length() && - memcmp(a.bytes(), b.bytes(), b.bytes_length()) == 0; - if (a.type() == UploadElement::TYPE_FILE) { - return a.file_path() == b.file_path() && - a.file_range_offset() == b.file_range_offset() && - a.file_range_length() == b.file_range_length() && - a.expected_file_modification_time() == - b.expected_file_modification_time(); - } - return false; -} - -inline bool operator!=(const UploadElement& a, const UploadElement& b) { - return !(a == b); -} -#endif // defined(UNIT_TEST) - -} // namespace net - -#endif // CEF_LIBCEF_COMMON_NET_UPLOAD_ELEMENT_H_ diff --git a/libcef/common/process_message_impl.cc b/libcef/common/process_message_impl.cc index ed6510c45..20e6b2da4 100644 --- a/libcef/common/process_message_impl.cc +++ b/libcef/common/process_message_impl.cc @@ -3,68 +3,71 @@ // can be found in the LICENSE file. #include "libcef/common/process_message_impl.h" -#include "libcef/common/cef_messages.h" #include "libcef/common/values_impl.h" #include "base/logging.h" +#include "base/memory/ptr_util.h" -namespace { +// static +CefRefPtr CefProcessMessage::Create(const CefString& name) { + return new CefProcessMessageImpl(name, CefListValue::Create()); +} -void CopyValue(const Cef_Request_Params& source, Cef_Request_Params& target) { - target.name = source.name; - auto copy = source.arguments.CreateDeepCopy(); - target.arguments.Swap(copy.get()); +CefProcessMessageImpl::CefProcessMessageImpl(const CefString& name, + CefRefPtr arguments) + : name_(name), arguments_(arguments) { + DCHECK(!name_.empty()); + DCHECK(arguments_); } -} // namespace +CefProcessMessageImpl::CefProcessMessageImpl(const CefString& name, + base::ListValue* arguments, + bool read_only) + : name_(name), + arguments_( + new CefListValueImpl(arguments, /*will_delete=*/false, read_only)), + should_detach_(true) { + DCHECK(!name_.empty()); +} -// static -CefRefPtr CefProcessMessage::Create(const CefString& name) { - Cef_Request_Params* params = new Cef_Request_Params(); - params->name = name; - return new CefProcessMessageImpl(params, true, false); +CefProcessMessageImpl::~CefProcessMessageImpl() { + DCHECK(!should_detach_ || !arguments_->IsValid()); } -CefProcessMessageImpl::CefProcessMessageImpl(Cef_Request_Params* value, - bool will_delete, - bool read_only) - : CefValueBase( - value, - nullptr, - will_delete ? kOwnerWillDelete : kOwnerNoDelete, - read_only, - nullptr) {} +void CefProcessMessageImpl::Detach() { + DCHECK(IsValid()); + DCHECK(should_detach_); + CefListValueImpl* value_impl = + static_cast(arguments_.get()); + ignore_result(value_impl->Detach(nullptr)); +} -bool CefProcessMessageImpl::CopyTo(Cef_Request_Params& target) { - CEF_VALUE_VERIFY_RETURN(false, false); - CopyValue(const_value(), target); - return true; +base::ListValue CefProcessMessageImpl::TakeArgumentList() { + DCHECK(IsValid()); + CefListValueImpl* value_impl = + static_cast(arguments_.get()); + auto value = base::WrapUnique(value_impl->CopyOrDetachValue(nullptr)); + return std::move(*value); } bool CefProcessMessageImpl::IsValid() { - return !detached(); + return arguments_->IsValid(); } bool CefProcessMessageImpl::IsReadOnly() { - return read_only(); + return arguments_->IsReadOnly(); } CefRefPtr CefProcessMessageImpl::Copy() { - CEF_VALUE_VERIFY_RETURN(false, nullptr); - Cef_Request_Params* params = new Cef_Request_Params(); - CopyValue(const_value(), *params); - return new CefProcessMessageImpl(params, true, false); + if (!IsValid()) + return nullptr; + return new CefProcessMessageImpl(name_, arguments_->Copy()); } CefString CefProcessMessageImpl::GetName() { - CEF_VALUE_VERIFY_RETURN(false, CefString()); - return const_value().name; + return name_; } CefRefPtr CefProcessMessageImpl::GetArgumentList() { - CEF_VALUE_VERIFY_RETURN(false, nullptr); - return CefListValueImpl::GetOrCreateRef( - const_cast(&(const_value().arguments)), - const_cast(&const_value()), read_only(), - controller()); + return arguments_; } diff --git a/libcef/common/process_message_impl.h b/libcef/common/process_message_impl.h index 30dfc72ae..fd74f46fb 100644 --- a/libcef/common/process_message_impl.h +++ b/libcef/common/process_message_impl.h @@ -7,20 +7,33 @@ #pragma once #include "include/cef_process_message.h" -#include "libcef/common/value_base.h" -struct Cef_Request_Params; +namespace base { +class ListValue; +} -// CefProcessMessage implementation -class CefProcessMessageImpl - : public CefValueBase { +// CefProcessMessage implementation. +class CefProcessMessageImpl : public CefProcessMessage { public: - CefProcessMessageImpl(Cef_Request_Params* value, - bool will_delete, + // Constructor for an owned list of arguments. + CefProcessMessageImpl(const CefString& name, + CefRefPtr arguments); + + // Constructor for an unowned list of arguments. + // Call Detach() when |arguments| is no longer valid. + CefProcessMessageImpl(const CefString& name, + base::ListValue* arguments, bool read_only); - // Copies the underlying value to the specified |target| structure. - bool CopyTo(Cef_Request_Params& target); + ~CefProcessMessageImpl() override; + + // Stop referencing the underlying argument list (which we never owned). + void Detach(); + + // Transfer ownership of the underlying argument list to the caller. + // TODO: Pass by reference instead of ownership if/when Mojo adds support + // for that. + base::ListValue TakeArgumentList() WARN_UNUSED_RESULT; // CefProcessMessage methods. bool IsValid() override; @@ -29,6 +42,12 @@ class CefProcessMessageImpl CefString GetName() override; CefRefPtr GetArgumentList() override; + private: + const CefString name_; + CefRefPtr arguments_; + const bool should_detach_ = false; + + IMPLEMENT_REFCOUNTING(CefProcessMessageImpl); DISALLOW_COPY_AND_ASSIGN(CefProcessMessageImpl); }; diff --git a/libcef/common/request_impl.cc b/libcef/common/request_impl.cc index e605aed41..19642a1f3 100644 --- a/libcef/common/request_impl.cc +++ b/libcef/common/request_impl.cc @@ -8,19 +8,15 @@ #include #include -#include "libcef/browser/navigate_params.h" -#include "libcef/common/cef_messages.h" #include "libcef/common/net/http_header_utils.h" -#include "libcef/common/net/upload_data.h" #include "libcef/common/net_service/net_service_util.h" #include "libcef/common/request_impl.h" #include "base/command_line.h" #include "base/logging.h" +#include "base/strings/string_split.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" -#include "base/task/post_task.h" -#include "base/task/thread_pool.h" #include "components/navigation_interception/navigation_params.h" #include "content/public/browser/browser_thread.h" #include "content/public/common/content_switches.h" @@ -45,6 +41,7 @@ #include "third_party/blink/public/platform/web_url.h" #include "third_party/blink/public/platform/web_url_error.h" #include "third_party/blink/public/platform/web_url_request.h" +#include "third_party/blink/public/platform/web_url_request_util.h" #include "third_party/blink/public/web/web_security_policy.h" namespace { @@ -59,50 +56,6 @@ const char kCacheControlDirectiveOnlyIfCachedLowerCase[] = "only-if-cached"; const int kURCachePolicyMask = (UR_FLAG_SKIP_CACHE | UR_FLAG_ONLY_FROM_CACHE | UR_FLAG_DISABLE_CACHE); -// A subclass of net::UploadBytesElementReader that keeps the associated -// UploadElement alive until the request completes. -class BytesElementReader : public net::UploadBytesElementReader { - public: - explicit BytesElementReader(std::unique_ptr element) - : net::UploadBytesElementReader(element->bytes(), - element->bytes_length()), - element_(std::move(element)) { - DCHECK_EQ(net::UploadElement::TYPE_BYTES, element_->type()); - } - - private: - std::unique_ptr element_; - - DISALLOW_COPY_AND_ASSIGN(BytesElementReader); -}; - -scoped_refptr GetFileTaskRunner() { - return base::ThreadPool::CreateSequencedTaskRunner( - {base::MayBlock(), base::TaskPriority::USER_VISIBLE}); -} - -// A subclass of net::UploadFileElementReader that keeps the associated -// UploadElement alive until the request completes. -class FileElementReader : public net::UploadFileElementReader { - public: - explicit FileElementReader(std::unique_ptr element) - : net::UploadFileElementReader( - GetFileTaskRunner().get(), - element->file_path(), - element->file_range_offset(), - element->file_range_length(), - element->expected_file_modification_time()), - element_(std::move(element)) { - DCHECK_EQ(net::UploadElement::TYPE_FILE, element_->type()); - } - - private: - scoped_refptr task_runner_; - std::unique_ptr element_; - - DISALLOW_COPY_AND_ASSIGN(FileElementReader); -}; - // Returns the cef_urlrequest_flags_t policy specified by the Cache-Control // request header directives, if any. The directives are case-insensitive and // some have an optional argument. Multiple directives are comma-separated. @@ -167,15 +120,6 @@ blink::mojom::FetchCacheMode GetFetchCacheMode(int ur_flags) { return blink::mojom::FetchCacheMode::kDefault; } -blink::WebString FilePathStringToWebString( - const base::FilePath::StringType& str) { -#if defined(OS_POSIX) - return blink::WebString::FromUTF8(str); -#elif defined(OS_WIN) - return blink::WebString::FromUTF16(base::WideToUTF16(str)); -#endif -} - // Read |headers| into |map|. void GetHeaderMap(const net::HttpRequestHeaders& headers, CefRequest::HeaderMap& map) { @@ -209,10 +153,6 @@ void GetHeaderMap(const CefRequest::HeaderMap& source, } } -// Type used in UploadDataStream. -typedef std::vector> - UploadElementReaders; - } // namespace #define CHECK_READONLY_RETURN(val) \ @@ -601,30 +541,28 @@ void CefRequestImpl::Set( } // static -void CefRequestImpl::Get(const CefMsg_LoadRequest_Params& params, +void CefRequestImpl::Get(const cef::mojom::RequestParamsPtr& params, blink::WebURLRequest& request) { - request.SetUrl(params.url); - request.SetRequestorOrigin(blink::WebSecurityOrigin::Create(params.url)); - if (!params.method.empty()) - request.SetHttpMethod(blink::WebString::FromASCII(params.method)); + request.SetUrl(params->url); + request.SetRequestorOrigin(blink::WebSecurityOrigin::Create(params->url)); + if (!params->method.empty()) + request.SetHttpMethod(blink::WebString::FromASCII(params->method)); - if (params.referrer.is_valid()) { + if (params->referrer && params->referrer->url.is_valid()) { const blink::WebString& referrer = blink::WebSecurityPolicy::GenerateReferrerHeader( - NetReferrerPolicyToBlinkReferrerPolicy( - static_cast(params.referrer_policy)), - params.url, blink::WebString::FromUTF8(params.referrer.spec())); + params->referrer->policy, params->url, + blink::WebString::FromUTF8(params->referrer->url.spec())); if (!referrer.IsEmpty()) { request.SetReferrerString(referrer); - request.SetReferrerPolicy(NetReferrerPolicyToBlinkReferrerPolicy( - static_cast(params.referrer_policy))); + request.SetReferrerPolicy(params->referrer->policy); } } CefRequest::HeaderMap headerMap; - if (!params.headers.empty()) { - for (net::HttpUtil::HeadersIterator i(params.headers.begin(), - params.headers.end(), "\n\r"); + if (!params->headers.empty()) { + for (net::HttpUtil::HeadersIterator i(params->headers.begin(), + params->headers.end(), "\n\r"); i.GetNext();) { request.AddHttpHeaderField(blink::WebString::FromUTF8(i.name()), blink::WebString::FromUTF8(i.values())); @@ -632,7 +570,7 @@ void CefRequestImpl::Get(const CefMsg_LoadRequest_Params& params, } } - if (params.upload_data.get()) { + if (params->upload_data) { const std::u16string& method = request.HttpMethod().Utf16(); if (method == u"GET" || method == u"HEAD") { request.SetHttpMethod(blink::WebString::FromASCII("POST")); @@ -649,31 +587,14 @@ void CefRequestImpl::Get(const CefMsg_LoadRequest_Params& params, net_service::kContentTypeApplicationFormURLEncoded)); } - blink::WebHTTPBody body; - body.Initialize(); - - for (const auto& element : params.upload_data->elements()) { - if (element->type() == net::UploadElement::TYPE_BYTES) { - blink::WebData data; - data.Assign(element->bytes(), element->bytes_length()); - body.AppendData(data); - } else if (element->type() == net::UploadElement::TYPE_FILE) { - body.AppendFileRange( - FilePathStringToWebString(element->file_path().value()), - element->file_range_offset(), element->file_range_length(), - element->expected_file_modification_time()); - } else { - NOTREACHED(); - } - } - - request.SetHttpBody(body); + request.SetHttpBody( + blink::GetWebHTTPBodyForRequestBody(*params->upload_data)); } - if (!params.site_for_cookies.IsNull()) - request.SetSiteForCookies(params.site_for_cookies); + if (!params->site_for_cookies.IsNull()) + request.SetSiteForCookies(params->site_for_cookies); - int flags = params.load_flags; + int flags = params->load_flags; if (!(flags & kURCachePolicyMask)) { // Only consider the Cache-Control directives when a cache policy is not // explicitly set on the request. @@ -681,34 +602,32 @@ void CefRequestImpl::Get(const CefMsg_LoadRequest_Params& params, } request.SetCacheMode(GetFetchCacheMode(flags)); - SETBOOLFLAG(request, params.load_flags, SetAllowStoredCredentials, + SETBOOLFLAG(request, params->load_flags, SetAllowStoredCredentials, UR_FLAG_ALLOW_STORED_CREDENTIALS); - SETBOOLFLAG(request, params.load_flags, SetReportUploadProgress, + SETBOOLFLAG(request, params->load_flags, SetReportUploadProgress, UR_FLAG_REPORT_UPLOAD_PROGRESS); } -void CefRequestImpl::Get(CefNavigateParams& params) const { +void CefRequestImpl::Get(cef::mojom::RequestParamsPtr& params) const { base::AutoLock lock_scope(lock_); - params.url = url_; - params.method = method_; + params->url = url_; + params->method = method_; // Referrer policy will be applied later in the request pipeline. - params.referrer.url = referrer_url_; - params.referrer.policy = - NetReferrerPolicyToBlinkReferrerPolicy(referrer_policy_); + params->referrer = blink::mojom::Referrer::New( + referrer_url_, NetReferrerPolicyToBlinkReferrerPolicy(referrer_policy_)); if (!headermap_.empty()) - params.headers = HttpHeaderUtils::GenerateHeaders(headermap_); + params->headers = HttpHeaderUtils::GenerateHeaders(headermap_); if (postdata_) { CefPostDataImpl* impl = static_cast(postdata_.get()); - params.upload_data = new net::UploadData(); - impl->Get(*params.upload_data.get()); + params->upload_data = impl->GetBody(); } - params.site_for_cookies = site_for_cookies_; - params.load_flags = flags_; + params->site_for_cookies = site_for_cookies_; + params->load_flags = flags_; } void CefRequestImpl::SetReadOnly(bool read_only) { @@ -1048,70 +967,6 @@ scoped_refptr CefPostDataImpl::GetBody() const { return body; } -void CefPostDataImpl::Set(const net::UploadData& data) { - { - base::AutoLock lock_scope(lock_); - CHECK_READONLY_RETURN_VOID(); - } - - CefRefPtr postelem; - - for (const auto& element : data.elements()) { - postelem = CefPostDataElement::Create(); - static_cast(postelem.get())->Set(*element); - AddElement(postelem); - } -} - -void CefPostDataImpl::Set(const net::UploadDataStream& data_stream) { - { - base::AutoLock lock_scope(lock_); - CHECK_READONLY_RETURN_VOID(); - } - - CefRefPtr postelem; - - const UploadElementReaders* elements = data_stream.GetElementReaders(); - if (elements) { - UploadElementReaders::const_iterator it = elements->begin(); - for (; it != elements->end(); ++it) { - postelem = CefPostDataElement::Create(); - static_cast(postelem.get())->Set(**it); - if (postelem->GetType() != PDE_TYPE_EMPTY) - AddElement(postelem); - else if (!has_excluded_elements_) - has_excluded_elements_ = true; - } - } -} - -void CefPostDataImpl::Get(net::UploadData& data) const { - base::AutoLock lock_scope(lock_); - - net::UploadData::ElementsVector data_elements; - for (const auto& element : elements_) { - std::unique_ptr data_element = - std::make_unique(); - static_cast(element.get()) - ->Get(*data_element.get()); - data_elements.push_back(std::move(data_element)); - } - data.swap_elements(&data_elements); -} - -std::unique_ptr CefPostDataImpl::Get() const { - base::AutoLock lock_scope(lock_); - - UploadElementReaders element_readers; - for (const auto& element : elements_) { - element_readers.push_back( - static_cast(element.get())->Get()); - } - - return std::make_unique( - std::move(element_readers), 0); -} - void CefPostDataImpl::SetReadOnly(bool read_only) { base::AutoLock lock_scope(lock_); if (read_only_ == read_only) @@ -1295,78 +1150,6 @@ void CefPostDataElementImpl::Get(network::ResourceRequestBody& body) const { } } -void CefPostDataElementImpl::Set(const net::UploadElement& element) { - { - base::AutoLock lock_scope(lock_); - CHECK_READONLY_RETURN_VOID(); - } - - if (element.type() == net::UploadElement::TYPE_BYTES) { - SetToBytes(element.bytes_length(), element.bytes()); - } else if (element.type() == net::UploadElement::TYPE_FILE) { - SetToFile(element.file_path().value()); - } else { - NOTREACHED(); - } -} - -void CefPostDataElementImpl::Set( - const net::UploadElementReader& element_reader) { - { - base::AutoLock lock_scope(lock_); - CHECK_READONLY_RETURN_VOID(); - } - - const net::UploadBytesElementReader* bytes_reader = - element_reader.AsBytesReader(); - if (bytes_reader) { - SetToBytes(bytes_reader->length(), bytes_reader->bytes()); - return; - } - - const net::UploadFileElementReader* file_reader = - element_reader.AsFileReader(); - if (file_reader) { - SetToFile(file_reader->path().value()); - return; - } - - // Chunked uploads cannot currently be represented. - SetToEmpty(); -} - -void CefPostDataElementImpl::Get(net::UploadElement& element) const { - base::AutoLock lock_scope(lock_); - - if (type_ == PDE_TYPE_BYTES) { - element.SetToBytes(static_cast(data_.bytes.bytes), data_.bytes.size); - } else if (type_ == PDE_TYPE_FILE) { - base::FilePath path = base::FilePath(CefString(&data_.filename)); - element.SetToFilePath(path); - } else { - NOTREACHED(); - } -} - -std::unique_ptr CefPostDataElementImpl::Get() const { - base::AutoLock lock_scope(lock_); - - if (type_ == PDE_TYPE_BYTES) { - net::UploadElement* element = new net::UploadElement(); - element->SetToBytes(static_cast(data_.bytes.bytes), - data_.bytes.size); - return std::make_unique(base::WrapUnique(element)); - } else if (type_ == PDE_TYPE_FILE) { - net::UploadElement* element = new net::UploadElement(); - base::FilePath path = base::FilePath(CefString(&data_.filename)); - element->SetToFilePath(path); - return std::make_unique(base::WrapUnique(element)); - } else { - NOTREACHED(); - return nullptr; - } -} - void CefPostDataElementImpl::SetReadOnly(bool read_only) { base::AutoLock lock_scope(lock_); if (read_only_ == read_only) diff --git a/libcef/common/request_impl.h b/libcef/common/request_impl.h index 5b7ab2f18..cdd167e69 100644 --- a/libcef/common/request_impl.h +++ b/libcef/common/request_impl.h @@ -13,6 +13,7 @@ #include "include/cef_request.h" #include "base/synchronization/lock.h" +#include "cef/libcef/common/mojom/cef.mojom.h" #include "net/cookies/site_for_cookies.h" #include "services/network/public/mojom/referrer_policy.mojom-shared.h" #include "url/gurl.h" @@ -28,10 +29,6 @@ class NavigationParams; namespace net { class HttpRequestHeaders; struct RedirectInfo; -class UploadData; -class UploadDataStream; -class UploadElement; -class UploadElementReader; } // namespace net namespace network { @@ -40,9 +37,6 @@ struct ResourceRequest; class ResourceRequestBody; } // namespace network -struct CefMsg_LoadRequest_Params; -struct CefNavigateParams; - // Implementation of CefRequest class CefRequestImpl : public CefRequest { public: @@ -110,12 +104,12 @@ class CefRequestImpl : public CefRequest { // Populate the WebURLRequest object based on the contents of |params|. // Called from CefBrowserImpl::LoadRequest(). - static void Get(const CefMsg_LoadRequest_Params& params, + static void Get(const cef::mojom::RequestParamsPtr& params, blink::WebURLRequest& request); - // Populate the CefNavigateParams object from this object. + // Populate the RequestParams object from this object. // Called from CefFrameHostImpl::LoadRequest(). - void Get(CefNavigateParams& params) const; + void Get(cef::mojom::RequestParamsPtr& params) const; void SetReadOnly(bool read_only); @@ -208,10 +202,6 @@ class CefPostDataImpl : public CefPostData { void Set(const network::ResourceRequestBody& body); scoped_refptr GetBody() const; - void Set(const net::UploadData& data); - void Set(const net::UploadDataStream& data_stream); - void Get(net::UploadData& data) const; - std::unique_ptr Get() const; void SetReadOnly(bool read_only); @@ -259,10 +249,6 @@ class CefPostDataElementImpl : public CefPostDataElement { void Set(const network::DataElement& element); void Get(network::ResourceRequestBody& body) const; - void Set(const net::UploadElement& element); - void Set(const net::UploadElementReader& element_reader); - void Get(net::UploadElement& element) const; - std::unique_ptr Get() const; void SetReadOnly(bool read_only); diff --git a/libcef/common/response_manager.cc b/libcef/common/response_manager.cc deleted file mode 100644 index 2e97c4a92..000000000 --- a/libcef/common/response_manager.cc +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (c) 2012 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/common/response_manager.h" -#include "libcef/common/cef_messages.h" - -#include "base/logging.h" - -CefResponseManager::CefResponseManager() : next_request_id_(0) {} - -int CefResponseManager::GetNextRequestId() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - return ++next_request_id_; -} - -int CefResponseManager::RegisterHandler(CefRefPtr handler) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - int request_id = GetNextRequestId(); - TRACE_EVENT_ASYNC_BEGIN1("cef", "CefResponseManager::Handler", request_id, - "request_id", request_id); - handlers_.insert(std::make_pair(request_id, handler)); - return request_id; -} - -bool CefResponseManager::RunHandler(const Cef_Response_Params& params) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DCHECK_GT(params.request_id, 0); - HandlerMap::iterator it = handlers_.find(params.request_id); - if (it != handlers_.end()) { - TRACE_EVENT0("cef", "CefResponseManager::RunHandler"); - it->second->OnResponse(params); - handlers_.erase(it); - TRACE_EVENT_ASYNC_END1("cef", "CefResponseManager::Handler", - params.request_id, "success", 1); - return true; - } - TRACE_EVENT_ASYNC_END1("cef", "CefResponseManager::Handler", - params.request_id, "success", 0); - return false; -} - -void CefResponseManager::RegisterAckHandler(int request_id, - CefRefPtr handler) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - ack_handlers_.insert(std::make_pair(request_id, handler)); -} - -bool CefResponseManager::RunAckHandler(int request_id) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DCHECK_GT(request_id, 0); - AckHandlerMap::iterator it = ack_handlers_.find(request_id); - if (it != ack_handlers_.end()) { - it->second->OnResponseAck(); - ack_handlers_.erase(it); - return true; - } - return false; -} diff --git a/libcef/common/response_manager.h b/libcef/common/response_manager.h deleted file mode 100644 index 3e47c76ae..000000000 --- a/libcef/common/response_manager.h +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (c) 2012 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_COMMON_RESPONSE_MANAGER_H_ -#define CEF_LIBCEF_COMMON_RESPONSE_MANAGER_H_ -#pragma once - -#include - -#include "include/cef_base.h" - -#include "base/sequence_checker.h" - -struct Cef_Response_Params; - -// This class is not thread-safe. -class CefResponseManager { - public: - // Used for handling response messages. - class Handler : public virtual CefBaseRefCounted { - public: - virtual void OnResponse(const Cef_Response_Params& params) = 0; - }; - - // Used for handling response ack messages. - class AckHandler : public virtual CefBaseRefCounted { - public: - virtual void OnResponseAck() = 0; - }; - - CefResponseManager(); - - // Returns the next unique request id. - int GetNextRequestId(); - - // Register a response handler and return the unique request id. - int RegisterHandler(CefRefPtr handler); - - // Run the response handler for the specified request id. Returns true if a - // handler was run. - bool RunHandler(const Cef_Response_Params& params); - - // Register a response ack handler for the specified request id. - void RegisterAckHandler(int request_id, CefRefPtr handler); - - // Run the response ack handler for the specified request id. Returns true if - // a handler was run. - bool RunAckHandler(int request_id); - - private: - // Used for generating unique request ids. - int next_request_id_; - - // Map of unique request ids to Handler references. - typedef std::map> HandlerMap; - HandlerMap handlers_; - - // Map of unique request ids to AckHandler references. - typedef std::map> AckHandlerMap; - AckHandlerMap ack_handlers_; - - SEQUENCE_CHECKER(sequence_checker_); -}; - -#endif // CEF_LIBCEF_COMMON_RESPONSE_MANAGER_H_ diff --git a/libcef/common/string_util.cc b/libcef/common/string_util.cc new file mode 100644 index 000000000..bb187797c --- /dev/null +++ b/libcef/common/string_util.cc @@ -0,0 +1,72 @@ +// Copyright 2021 The Chromium Embedded Framework Authors. Portions copyright +// 2011 The Chromium 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/common/string_util.h" + +#include "base/memory/read_only_shared_memory_region.h" +#include "base/memory/ref_counted_memory.h" +#include "third_party/blink/public/platform/web_string.h" + +namespace string_util { + +void GetCefString(const blink::WebString& source, CefString& cef_string) { +#if defined(CEF_STRING_TYPE_UTF8) + cef_string.FromString(source.Utf8()); +#else + cef_string.FromString16(source.Utf16()); +#endif +} + +void GetCefString(scoped_refptr source, + CefString& cef_string) { + if (source && source->size() > 0U) { +#if defined(CEF_STRING_TYPE_UTF8) || defined(CEF_STRING_TYPE_UTF16) + // Reference existing UTF8 or UTF16 data. + cef_string.FromString(source->front_as(), + source->size() / sizeof(CefString::char_type), + /*copy=*/false); +#else + // Must convert from UTF16. + cef_string.FromString16( + source->front_as(), + source->size() / sizeof(std::u16string::value_type)); +#endif + } else { + cef_string.clear(); + } +} + +base::ReadOnlySharedMemoryRegion CreateSharedMemoryRegion( + const blink::WebString& source) { + base::ReadOnlySharedMemoryRegion region; + + if (!source.IsEmpty()) { +#if defined(CEF_STRING_TYPE_UTF8) + const std::string& string = source.Utf8(); + const size_t byte_size = string.length(); +#else + const std::u16string& string = source.Utf16(); + const size_t byte_size = + string.length() * sizeof(std::u16string::value_type); +#endif + auto mapped_region = base::ReadOnlySharedMemoryRegion::Create(byte_size); + if (mapped_region.IsValid()) { + memcpy(mapped_region.mapping.memory(), string.data(), byte_size); + region = std::move(mapped_region.region); + } + } + + return region; +} + +void ExecuteWithScopedCefString(base::ReadOnlySharedMemoryRegion region, + ScopedCefStringCallback callback) { + auto shared_buf = + base::RefCountedSharedMemoryMapping::CreateFromWholeRegion(region); + CefString str; + GetCefString(shared_buf, str); + std::move(callback).Run(str); +} + +} // namespace string_util \ No newline at end of file diff --git a/libcef/common/string_util.h b/libcef/common/string_util.h new file mode 100644 index 000000000..0261fbc5b --- /dev/null +++ b/libcef/common/string_util.h @@ -0,0 +1,44 @@ +// Copyright 2021 The Chromium Embedded Framework Authors. Portions copyright +// 2011 The Chromium 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_COMMON_STRING_UTIL_H_ +#define CEF_LIBCEF_COMMON_STRING_UTIL_H_ +#pragma once + +#include "include/cef_base.h" + +#include "base/callback.h" +#include "base/memory/scoped_refptr.h" + +namespace base { +class ReadOnlySharedMemoryRegion; +class RefCountedMemory; +} // namespace base + +namespace blink { +class WebString; +} + +namespace string_util { + +// Convert |source| to |cef_string|, avoiding UTF conversions if possible. +void GetCefString(const blink::WebString& source, CefString& cef_string); +void GetCefString(scoped_refptr source, + CefString& cef_string); + +// Read |source| into shared memory, avoiding UTF conversions if possible. +// Use ExecuteWithScopedCefString() to retrieve the value on the receiving end +// with zero UTF conversions and zero copies if possible. +base::ReadOnlySharedMemoryRegion CreateSharedMemoryRegion( + const blink::WebString& source); + +using ScopedCefStringCallback = base::OnceCallback; + +// Helper for executing |callback| with |region| as a scoped CefString. +void ExecuteWithScopedCefString(base::ReadOnlySharedMemoryRegion region, + ScopedCefStringCallback callback); + +} // namespace string_util + +#endif // CEF_LIBCEF_COMMON_STRING_UTIL_H_ diff --git a/libcef/common/value_base.h b/libcef/common/value_base.h index de86a418f..bd0197ea3 100644 --- a/libcef/common/value_base.h +++ b/libcef/common/value_base.h @@ -310,12 +310,9 @@ class CefValueBase : public CefType, public CefValueController::Object { // Detaches the underlying value and returns a pointer to it. If this is an // owner and a |new_controller| value is specified any existing references // will be passed to the new controller. - ValueType* Detach(CefValueController* new_controller) { + ValueType* Detach(CefValueController* new_controller) WARN_UNUSED_RESULT { CEF_VALUE_VERIFY_RETURN(false, nullptr); - // A |new_controller| value is required for mode kOwnerWillDelete. - DCHECK(!will_delete() || new_controller); - if (new_controller && !reference()) { // Pass any existing references and dependencies to the new controller. // They will be removed from this controller. diff --git a/libcef/common/values_impl.h b/libcef/common/values_impl.h index d18841159..1241c05c6 100644 --- a/libcef/common/values_impl.h +++ b/libcef/common/values_impl.h @@ -140,11 +140,12 @@ class CefBinaryValueImpl : public CefValueBase { CefBinaryValueImpl(char* data, size_t data_size); // Return a copy of the value. - base::Value* CopyValue(); + base::Value* CopyValue() WARN_UNUSED_RESULT; // If this value is a reference then return a copy. Otherwise, detach and // transfer ownership of the value. - base::Value* CopyOrDetachValue(CefValueController* new_controller); + base::Value* CopyOrDetachValue(CefValueController* new_controller) + WARN_UNUSED_RESULT; bool IsSameValue(const base::Value* that); bool IsEqualValue(const base::Value* that); @@ -195,11 +196,12 @@ class CefDictionaryValueImpl bool read_only); // Return a copy of the value. - base::DictionaryValue* CopyValue(); + base::DictionaryValue* CopyValue() WARN_UNUSED_RESULT; // If this value is a reference then return a copy. Otherwise, detach and // transfer ownership of the value. - base::DictionaryValue* CopyOrDetachValue(CefValueController* new_controller); + base::DictionaryValue* CopyOrDetachValue(CefValueController* new_controller) + WARN_UNUSED_RESULT; bool IsSameValue(const base::DictionaryValue* that); bool IsEqualValue(const base::DictionaryValue* that); @@ -273,11 +275,12 @@ class CefListValueImpl : public CefValueBase { CefListValueImpl(base::ListValue* value, bool will_delete, bool read_only); // Return a copy of the value. - base::ListValue* CopyValue(); + base::ListValue* CopyValue() WARN_UNUSED_RESULT; // If this value is a reference then return a copy. Otherwise, detach and // transfer ownership of the value. - base::ListValue* CopyOrDetachValue(CefValueController* new_controller); + base::ListValue* CopyOrDetachValue(CefValueController* new_controller) + WARN_UNUSED_RESULT; bool IsSameValue(const base::ListValue* that); bool IsEqualValue(const base::ListValue* that); diff --git a/libcef/renderer/alloy/alloy_content_renderer_client.cc b/libcef/renderer/alloy/alloy_content_renderer_client.cc index 096412f29..d2035e291 100644 --- a/libcef/renderer/alloy/alloy_content_renderer_client.cc +++ b/libcef/renderer/alloy/alloy_content_renderer_client.cc @@ -24,19 +24,18 @@ #include "libcef/browser/context.h" #include "libcef/common/alloy/alloy_content_client.h" #include "libcef/common/app_manager.h" -#include "libcef/common/cef_messages.h" #include "libcef/common/cef_switches.h" #include "libcef/common/extensions/extensions_client.h" #include "libcef/common/extensions/extensions_util.h" #include "libcef/common/request_impl.h" #include "libcef/features/runtime_checks.h" -#include "libcef/renderer/alloy/alloy_render_frame_observer.h" #include "libcef/renderer/alloy/alloy_render_thread_observer.h" #include "libcef/renderer/alloy/url_loader_throttle_provider_impl.h" #include "libcef/renderer/browser_impl.h" -#include "libcef/renderer/browser_manager.h" #include "libcef/renderer/extensions/extensions_renderer_client.h" #include "libcef/renderer/extensions/print_render_frame_helper_delegate.h" +#include "libcef/renderer/render_frame_observer.h" +#include "libcef/renderer/render_manager.h" #include "libcef/renderer/thread_util.h" #include "base/command_line.h" @@ -120,7 +119,7 @@ bool IsStandaloneExtensionProcess() { AlloyContentRendererClient::AlloyContentRendererClient() : main_entry_time_(base::TimeTicks::Now()), - browser_manager_(new CefBrowserManager) { + render_manager_(new CefRenderManager) { if (extensions::ExtensionsEnabled()) { extensions_client_.reset(new extensions::CefExtensionsClient); extensions::ExtensionsClient::Set(extensions_client_.get()); @@ -260,6 +259,8 @@ void AlloyContentRendererClient::ExposeInterfacesToBrowser( base::Unretained(spellcheck_.get())), task_runner); } + + render_manager_->ExposeInterfacesToBrowser(binders); } void AlloyContentRendererClient::RenderThreadConnected() { @@ -267,25 +268,23 @@ void AlloyContentRendererClient::RenderThreadConnected() { content::RenderThread* thread = content::RenderThread::Get(); thread->RegisterExtension(extensions_v8::LoadTimesExtension::Get()); - browser_manager_->RenderThreadConnected(); + render_manager_->RenderThreadConnected(); } void AlloyContentRendererClient::RenderFrameCreated( content::RenderFrame* render_frame) { - AlloyRenderFrameObserver* render_frame_observer = - new AlloyRenderFrameObserver(render_frame); - service_manager::BinderRegistry* registry = render_frame_observer->registry(); + auto render_frame_observer = new CefRenderFrameObserver(render_frame); new PepperHelper(render_frame); if (extensions::ExtensionsEnabled()) { - extensions_renderer_client_->RenderFrameCreated(render_frame, registry); + extensions_renderer_client_->RenderFrameCreated( + render_frame, render_frame_observer->registry()); - blink::AssociatedInterfaceRegistry* associated_interfaces = - render_frame_observer->associated_interfaces(); - associated_interfaces->AddInterface(base::BindRepeating( - &extensions::MimeHandlerViewContainerManager::BindReceiver, - render_frame->GetRoutingID())); + render_frame_observer->associated_interfaces()->AddInterface( + base::BindRepeating( + &extensions::MimeHandlerViewContainerManager::BindReceiver, + render_frame->GetRoutingID())); } const base::CommandLine* command_line = @@ -296,8 +295,8 @@ void AlloyContentRendererClient::RenderFrameCreated( bool browser_created; base::Optional is_windowless; - browser_manager_->RenderFrameCreated(render_frame, render_frame_observer, - browser_created, is_windowless); + render_manager_->RenderFrameCreated(render_frame, render_frame_observer, + browser_created, is_windowless); if (browser_created) { OnBrowserCreated(render_frame->GetRenderView(), is_windowless); } @@ -314,8 +313,8 @@ void AlloyContentRendererClient::RenderViewCreated( content::RenderView* render_view) { bool browser_created; base::Optional is_windowless; - browser_manager_->RenderViewCreated(render_view, browser_created, - is_windowless); + render_manager_->RenderViewCreated(render_view, browser_created, + is_windowless); if (browser_created) { OnBrowserCreated(render_view, is_windowless); } @@ -445,7 +444,7 @@ void AlloyContentRendererClient::DevToolsAgentAttached() { return; } - browser_manager_->DevToolsAgentAttached(); + render_manager_->DevToolsAgentAttached(); } void AlloyContentRendererClient::DevToolsAgentDetached() { @@ -458,7 +457,7 @@ void AlloyContentRendererClient::DevToolsAgentDetached() { return; } - browser_manager_->DevToolsAgentDetached(); + render_manager_->DevToolsAgentDetached(); } std::unique_ptr diff --git a/libcef/renderer/alloy/alloy_content_renderer_client.h b/libcef/renderer/alloy/alloy_content_renderer_client.h index 8add71c6b..df38d5783 100644 --- a/libcef/renderer/alloy/alloy_content_renderer_client.h +++ b/libcef/renderer/alloy/alloy_content_renderer_client.h @@ -42,8 +42,8 @@ namespace web_cache { class WebCacheImpl; } -class CefBrowserManager; -class CefRenderThreadObserver; +class AlloyRenderThreadObserver; +class CefRenderManager; class ChromePDFPrintClient; class SpellCheck; @@ -126,10 +126,10 @@ class AlloyContentRendererClient // which the RendererMain function was entered. base::TimeTicks main_entry_time_; - std::unique_ptr browser_manager_; + std::unique_ptr render_manager_; scoped_refptr render_task_runner_; - std::unique_ptr observer_; + std::unique_ptr observer_; std::unique_ptr web_cache_impl_; std::unique_ptr spellcheck_; std::unique_ptr visited_link_slave_; diff --git a/libcef/renderer/alloy/alloy_render_frame_observer.cc b/libcef/renderer/alloy/alloy_render_frame_observer.cc deleted file mode 100644 index 68d56acba..000000000 --- a/libcef/renderer/alloy/alloy_render_frame_observer.cc +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2014 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/renderer/alloy/alloy_render_frame_observer.h" - -AlloyRenderFrameObserver::AlloyRenderFrameObserver( - content::RenderFrame* render_frame) - : CefRenderFrameObserver(render_frame) {} - -AlloyRenderFrameObserver::~AlloyRenderFrameObserver() = default; - -void AlloyRenderFrameObserver::OnInterfaceRequestForFrame( - const std::string& interface_name, - mojo::ScopedMessagePipeHandle* interface_pipe) { - registry_.TryBindInterface(interface_name, interface_pipe); -} - -bool AlloyRenderFrameObserver::OnAssociatedInterfaceRequestForFrame( - const std::string& interface_name, - mojo::ScopedInterfaceEndpointHandle* handle) { - return associated_interfaces_.TryBindInterface(interface_name, handle); -} diff --git a/libcef/renderer/alloy/alloy_render_frame_observer.h b/libcef/renderer/alloy/alloy_render_frame_observer.h deleted file mode 100644 index e97a8514b..000000000 --- a/libcef/renderer/alloy/alloy_render_frame_observer.h +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2014 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 LIBCEF_RENDERER_ALLOY_ALLOY_RENDER_FRAME_OBSERVER_H_ -#define LIBCEF_RENDERER_ALLOY_ALLOY_RENDER_FRAME_OBSERVER_H_ - -#include "libcef/renderer/render_frame_observer.h" - -#include "services/service_manager/public/cpp/binder_registry.h" -#include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h" - -class AlloyRenderFrameObserver : public CefRenderFrameObserver { - public: - explicit AlloyRenderFrameObserver(content::RenderFrame* render_frame); - ~AlloyRenderFrameObserver() override; - - // RenderFrameObserver methods: - void OnInterfaceRequestForFrame( - const std::string& interface_name, - mojo::ScopedMessagePipeHandle* interface_pipe) override; - bool OnAssociatedInterfaceRequestForFrame( - const std::string& interface_name, - mojo::ScopedInterfaceEndpointHandle* handle) override; - - service_manager::BinderRegistry* registry() { return ®istry_; } - blink::AssociatedInterfaceRegistry* associated_interfaces() { - return &associated_interfaces_; - } - - private: - service_manager::BinderRegistry registry_; - blink::AssociatedInterfaceRegistry associated_interfaces_; - - DISALLOW_COPY_AND_ASSIGN(AlloyRenderFrameObserver); -}; - -#endif // LIBCEF_RENDERER_ALLOY_ALLOY_RENDER_FRAME_OBSERVER_H_ diff --git a/libcef/renderer/alloy/alloy_render_thread_observer.h b/libcef/renderer/alloy/alloy_render_thread_observer.h index b75322ede..e554d04cc 100644 --- a/libcef/renderer/alloy/alloy_render_thread_observer.h +++ b/libcef/renderer/alloy/alloy_render_thread_observer.h @@ -8,8 +8,6 @@ #include -#include "libcef/renderer/render_thread_observer.h" - #include "base/compiler_specific.h" #include "chrome/common/renderer_configuration.mojom.h" #include "components/content_settings/core/common/content_settings.h" @@ -17,7 +15,7 @@ #include "mojo/public/cpp/bindings/associated_receiver_set.h" // This class sends and receives control messages in the renderer process. -class AlloyRenderThreadObserver : public CefRenderThreadObserver, +class AlloyRenderThreadObserver : public content::RenderThreadObserver, public chrome::mojom::RendererConfiguration { public: AlloyRenderThreadObserver(); diff --git a/libcef/renderer/blink_glue.cc b/libcef/renderer/blink_glue.cc index a730e1292..ffb99bdcf 100644 --- a/libcef/renderer/blink_glue.cc +++ b/libcef/renderer/blink_glue.cc @@ -87,21 +87,20 @@ void GoForward(blink::WebView* view) { } } -std::string DumpDocumentText(blink::WebLocalFrame* frame) { +blink::WebString DumpDocumentText(blink::WebLocalFrame* frame) { // We use the document element's text instead of the body text here because // not all documents have a body, such as XML documents. blink::WebElement document_element = frame->GetDocument().DocumentElement(); if (document_element.IsNull()) - return std::string(); + return blink::WebString(); blink::Element* web_element = document_element.Unwrap(); - return blink::WebString(web_element->innerText()).Utf8(); + return blink::WebString(web_element->innerText()); } -std::string DumpDocumentMarkup(blink::WebLocalFrame* frame) { - const auto& string = blink::CreateMarkup( +blink::WebString DumpDocumentMarkup(blink::WebLocalFrame* frame) { + return blink::CreateMarkup( blink::To(frame)->GetFrame()->GetDocument()); - return string.Utf8(); } cef_dom_node_type_t GetNodeType(const blink::WebNode& node) { diff --git a/libcef/renderer/blink_glue.h b/libcef/renderer/blink_glue.h index a7db3ef45..dba2a2f20 100644 --- a/libcef/renderer/blink_glue.h +++ b/libcef/renderer/blink_glue.h @@ -41,9 +41,9 @@ BLINK_EXPORT void GoBack(blink::WebView* view); BLINK_EXPORT void GoForward(blink::WebView* view); // Returns the text of the document element. -BLINK_EXPORT std::string DumpDocumentText(blink::WebLocalFrame* frame); +BLINK_EXPORT blink::WebString DumpDocumentText(blink::WebLocalFrame* frame); // Returns the markup of the document element. -BLINK_EXPORT std::string DumpDocumentMarkup(blink::WebLocalFrame* frame); +BLINK_EXPORT blink::WebString DumpDocumentMarkup(blink::WebLocalFrame* frame); // Expose additional actions on WebNode. BLINK_EXPORT cef_dom_node_type_t GetNodeType(const blink::WebNode& node); diff --git a/libcef/renderer/browser_impl.cc b/libcef/renderer/browser_impl.cc index 007692926..3cd3a4250 100644 --- a/libcef/renderer/browser_impl.cc +++ b/libcef/renderer/browser_impl.cc @@ -9,10 +9,9 @@ #include #include "libcef/common/app_manager.h" -#include "libcef/common/cef_messages.h" #include "libcef/renderer/blink_glue.h" -#include "libcef/renderer/browser_manager.h" #include "libcef/renderer/render_frame_util.h" +#include "libcef/renderer/render_manager.h" #include "libcef/renderer/thread_util.h" #include "base/strings/string_util.h" @@ -37,13 +36,13 @@ // static CefRefPtr CefBrowserImpl::GetBrowserForView( content::RenderView* view) { - return CefBrowserManager::Get()->GetBrowserForView(view); + return CefRenderManager::Get()->GetBrowserForView(view); } // static CefRefPtr CefBrowserImpl::GetBrowserForMainFrame( blink::WebFrame* frame) { - return CefBrowserManager::Get()->GetBrowserForMainFrame(frame); + return CefRenderManager::Get()->GetBrowserForMainFrame(frame); } // CefBrowser methods. @@ -350,7 +349,7 @@ void CefBrowserImpl::OnDestruct() { handler->OnBrowserDestroyed(this); } - CefBrowserManager::Get()->OnBrowserDestroyed(this); + CefRenderManager::Get()->OnBrowserDestroyed(this); } void CefBrowserImpl::FrameDetached(int64_t frame_id) { diff --git a/libcef/renderer/chrome/chrome_content_renderer_client_cef.cc b/libcef/renderer/chrome/chrome_content_renderer_client_cef.cc index d67569886..e2527b8a7 100644 --- a/libcef/renderer/chrome/chrome_content_renderer_client_cef.cc +++ b/libcef/renderer/chrome/chrome_content_renderer_client_cef.cc @@ -5,15 +5,14 @@ #include "libcef/renderer/chrome/chrome_content_renderer_client_cef.h" -#include "libcef/renderer/browser_manager.h" #include "libcef/renderer/render_frame_observer.h" -#include "libcef/renderer/render_thread_observer.h" +#include "libcef/renderer/render_manager.h" #include "libcef/renderer/thread_util.h" #include "content/public/renderer/render_thread.h" ChromeContentRendererClientCef::ChromeContentRendererClientCef() - : browser_manager_(new CefBrowserManager) {} + : render_manager_(new CefRenderManager) {} ChromeContentRendererClientCef::~ChromeContentRendererClientCef() = default; @@ -29,16 +28,12 @@ void ChromeContentRendererClientCef::RenderThreadStarted() { ChromeContentRendererClient::RenderThreadStarted(); render_task_runner_ = base::ThreadTaskRunnerHandle::Get(); - observer_ = std::make_unique(); - - content::RenderThread* thread = content::RenderThread::Get(); - thread->AddObserver(observer_.get()); } void ChromeContentRendererClientCef::RenderThreadConnected() { ChromeContentRendererClient::RenderThreadConnected(); - browser_manager_->RenderThreadConnected(); + render_manager_->RenderThreadConnected(); } void ChromeContentRendererClientCef::RenderFrameCreated( @@ -51,8 +46,8 @@ void ChromeContentRendererClientCef::RenderFrameCreated( bool browser_created; base::Optional is_windowless; - browser_manager_->RenderFrameCreated(render_frame, render_frame_observer, - browser_created, is_windowless); + render_manager_->RenderFrameCreated(render_frame, render_frame_observer, + browser_created, is_windowless); if (is_windowless.has_value() && *is_windowless) { LOG(ERROR) << "The chrome runtime does not support windowless browsers"; } @@ -64,8 +59,8 @@ void ChromeContentRendererClientCef::RenderViewCreated( bool browser_created; base::Optional is_windowless; - browser_manager_->RenderViewCreated(render_view, browser_created, - is_windowless); + render_manager_->RenderViewCreated(render_view, browser_created, + is_windowless); if (is_windowless.has_value() && *is_windowless) { LOG(ERROR) << "The chrome runtime does not support windowless browsers"; } @@ -81,7 +76,7 @@ void ChromeContentRendererClientCef::DevToolsAgentAttached() { return; } - browser_manager_->DevToolsAgentAttached(); + render_manager_->DevToolsAgentAttached(); } void ChromeContentRendererClientCef::DevToolsAgentDetached() { @@ -94,5 +89,12 @@ void ChromeContentRendererClientCef::DevToolsAgentDetached() { return; } - browser_manager_->DevToolsAgentDetached(); + render_manager_->DevToolsAgentDetached(); } + +void ChromeContentRendererClientCef::ExposeInterfacesToBrowser( + mojo::BinderMap* binders) { + ChromeContentRendererClient::ExposeInterfacesToBrowser(binders); + + render_manager_->ExposeInterfacesToBrowser(binders); +} \ No newline at end of file diff --git a/libcef/renderer/chrome/chrome_content_renderer_client_cef.h b/libcef/renderer/chrome/chrome_content_renderer_client_cef.h index af616312d..3cfc40457 100644 --- a/libcef/renderer/chrome/chrome_content_renderer_client_cef.h +++ b/libcef/renderer/chrome/chrome_content_renderer_client_cef.h @@ -13,8 +13,7 @@ #include "base/single_thread_task_runner.h" #include "chrome/renderer/chrome_content_renderer_client.h" -class CefBrowserManager; -class CefRenderThreadObserver; +class CefRenderManager; // CEF override of ChromeContentRendererClient. class ChromeContentRendererClientCef : public ChromeContentRendererClient { @@ -38,12 +37,12 @@ class ChromeContentRendererClientCef : public ChromeContentRendererClient { void RenderViewCreated(content::RenderView* render_view) override; void DevToolsAgentAttached() override; void DevToolsAgentDetached() override; + void ExposeInterfacesToBrowser(mojo::BinderMap* binders) override; private: - std::unique_ptr browser_manager_; + std::unique_ptr render_manager_; scoped_refptr render_task_runner_; - std::unique_ptr observer_; DISALLOW_COPY_AND_ASSIGN(ChromeContentRendererClientCef); }; diff --git a/libcef/renderer/frame_impl.cc b/libcef/renderer/frame_impl.cc index d02fbb5ea..ed3687e9c 100644 --- a/libcef/renderer/frame_impl.cc +++ b/libcef/renderer/frame_impl.cc @@ -18,11 +18,10 @@ #endif #include "libcef/common/app_manager.h" -#include "libcef/common/cef_messages.h" #include "libcef/common/net/http_header_utils.h" #include "libcef/common/process_message_impl.h" #include "libcef/common/request_impl.h" -#include "libcef/common/response_manager.h" +#include "libcef/common/string_util.h" #include "libcef/renderer/blink_glue.h" #include "libcef/renderer/browser_impl.h" #include "libcef/renderer/dom_document_impl.h" @@ -51,10 +50,7 @@ CefFrameImpl::CefFrameImpl(CefBrowserImpl* browser, blink::WebLocalFrame* frame, int64_t frame_id) - : browser_(browser), - frame_(frame), - frame_id_(frame_id), - response_manager_(new CefResponseManager) {} + : browser_(browser), frame_(frame), frame_id_(frame_id) {} CefFrameImpl::~CefFrameImpl() {} @@ -65,31 +61,31 @@ bool CefFrameImpl::IsValid() { } void CefFrameImpl::Undo() { - ExecuteCommand("Undo"); + SendCommand("Undo"); } void CefFrameImpl::Redo() { - ExecuteCommand("Redo"); + SendCommand("Redo"); } void CefFrameImpl::Cut() { - ExecuteCommand("Cut"); + SendCommand("Cut"); } void CefFrameImpl::Copy() { - ExecuteCommand("Copy"); + SendCommand("Copy"); } void CefFrameImpl::Paste() { - ExecuteCommand("Paste"); + SendCommand("Paste"); } void CefFrameImpl::Delete() { - ExecuteCommand("Delete"); + SendCommand("Delete"); } void CefFrameImpl::SelectAll() { - ExecuteCommand("SelectAll"); + SendCommand("SelectAll"); } void CefFrameImpl::ViewSource() { @@ -99,7 +95,8 @@ void CefFrameImpl::ViewSource() { void CefFrameImpl::GetSource(CefRefPtr visitor) { CEF_REQUIRE_RT_RETURN_VOID(); if (frame_) { - const CefString& content = blink_glue::DumpDocumentMarkup(frame_); + CefString content; + string_util::GetCefString(blink_glue::DumpDocumentMarkup(frame_), content); visitor->Visit(content); } } @@ -107,7 +104,8 @@ void CefFrameImpl::GetSource(CefRefPtr visitor) { void CefFrameImpl::GetText(CefRefPtr visitor) { CEF_REQUIRE_RT_RETURN_VOID(); if (frame_) { - const CefString& content = blink_glue::DumpDocumentText(frame_); + CefString content; + string_util::GetCefString(blink_glue::DumpDocumentText(frame_), content); visitor->Visit(content); } } @@ -118,27 +116,9 @@ void CefFrameImpl::LoadRequest(CefRefPtr request) { if (!frame_) return; - CefMsg_LoadRequest_Params params; - params.url = GURL(std::string(request->GetURL())); - params.method = request->GetMethod(); - params.site_for_cookies = net::SiteForCookies::FromUrl( - GURL(request->GetFirstPartyForCookies().ToString())); - - CefRequest::HeaderMap headerMap; - request->GetHeaderMap(headerMap); - if (!headerMap.empty()) - params.headers = HttpHeaderUtils::GenerateHeaders(headerMap); - - CefRefPtr postData = request->GetPostData(); - if (postData.get()) { - CefPostDataImpl* impl = static_cast(postData.get()); - params.upload_data = new net::UploadData(); - impl->Get(*params.upload_data.get()); - } - - params.load_flags = request->GetFlags(); - - OnLoadRequest(params); + auto params = cef::mojom::RequestParams::New(); + static_cast(request.get())->Get(params); + LoadRequest(std::move(params)); } void CefFrameImpl::LoadURL(const CefString& url) { @@ -147,28 +127,16 @@ void CefFrameImpl::LoadURL(const CefString& url) { if (!frame_) return; - CefMsg_LoadRequest_Params params; - params.url = GURL(url.ToString()); - params.method = "GET"; - - OnLoadRequest(params); + auto params = cef::mojom::RequestParams::New(); + params->url = GURL(url.ToString()); + params->method = "GET"; + LoadRequest(std::move(params)); } void CefFrameImpl::ExecuteJavaScript(const CefString& jsCode, const CefString& scriptUrl, int startLine) { - CEF_REQUIRE_RT_RETURN_VOID(); - - if (jsCode.empty()) - return; - if (startLine < 1) - startLine = 1; - - if (frame_) { - GURL gurl = GURL(scriptUrl.ToString()); - frame_->ExecuteScript(blink::WebScriptSource( - blink::WebString::FromUTF16(jsCode.ToString16()), gurl, startLine)); - } + SendJavaScript(jsCode, scriptUrl, startLine); } bool CefFrameImpl::IsMain() { @@ -279,12 +247,21 @@ CefRefPtr CefFrameImpl::CreateURLRequest( void CefFrameImpl::SendProcessMessage(CefProcessId target_process, CefRefPtr message) { - Cef_Request_Params params; - CefProcessMessageImpl* impl = - static_cast(message.get()); - if (impl->CopyTo(params)) { - SendProcessMessage(target_process, params.name, ¶ms.arguments, true); - } + CEF_REQUIRE_RT_RETURN_VOID(); + DCHECK_EQ(PID_BROWSER, target_process); + DCHECK(message && message->IsValid()); + if (!message || !message->IsValid()) + return; + + if (!frame_) + return; + + auto& browser_frame = GetBrowserFrame(); + if (!browser_frame) + return; + + auto impl = static_cast(message.get()); + browser_frame->SendMessage(impl->GetName(), impl->TakeArgumentList()); } std::unique_ptr CefFrameImpl::CreateURLLoader() { @@ -323,22 +300,15 @@ CefFrameImpl::CreateResourceLoadInfoNotifierWrapper() { return nullptr; } -void CefFrameImpl::OnAttached() { - Send(new CefHostMsg_FrameAttached(MSG_ROUTING_NONE)); -} +void CefFrameImpl::OnAttached(service_manager::BinderRegistry* registry) { + // Called indirectly from RenderFrameCreated. + registry->AddInterface(base::BindRepeating( + &CefFrameImpl::BindRenderFrameReceiver, weak_ptr_factory_.GetWeakPtr())); -bool CefFrameImpl::OnMessageReceived(const IPC::Message& message) { - bool handled = true; - IPC_BEGIN_MESSAGE_MAP(CefFrameImpl, message) - IPC_MESSAGE_HANDLER(CefMsg_Request, OnRequest) - IPC_MESSAGE_HANDLER(CefMsg_Response, OnResponse) - IPC_MESSAGE_HANDLER(CefMsg_ResponseAck, OnResponseAck) - IPC_MESSAGE_HANDLER(CefMsg_LoadRequest, OnLoadRequest) - IPC_MESSAGE_HANDLER(CefMsg_DidStopLoading, OnDidStopLoading) - IPC_MESSAGE_HANDLER(CefMsg_MoveOrResizeStarted, OnMoveOrResizeStarted) - IPC_MESSAGE_UNHANDLED(handled = false) - IPC_END_MESSAGE_MAP() - return handled; + auto& browser_frame = GetBrowserFrame(); + if (browser_frame) { + browser_frame->FrameAttached(); + } } void CefFrameImpl::OnDidFinishLoad() { @@ -349,8 +319,10 @@ void CefFrameImpl::OnDidFinishLoad() { blink::WebDocumentLoader* dl = frame_->GetDocumentLoader(); const int http_status_code = dl->GetResponse().HttpStatusCode(); - Send(new CefHostMsg_DidFinishLoad(MSG_ROUTING_NONE, dl->GetUrl(), - http_status_code)); + auto& browser_frame = GetBrowserFrame(); + if (browser_frame) { + browser_frame->DidFinishFrameLoad(dl->GetUrl(), http_status_code); + } CefRefPtr app = CefAppManager::Get()->GetApplication(); if (app) { @@ -367,174 +339,124 @@ void CefFrameImpl::OnDidFinishLoad() { void CefFrameImpl::OnDraggableRegionsChanged() { blink::WebVector webregions = frame_->GetDocument().DraggableRegions(); - std::vector regions; - for (size_t i = 0; i < webregions.size(); ++i) { - Cef_DraggableRegion_Params region; + std::vector regions; + if (!webregions.empty()) { auto render_frame = content::RenderFrameImpl::FromWebFrame(frame_); - render_frame->ConvertViewportToWindow(&webregions[i].bounds); - region.bounds = webregions[i].bounds; - region.draggable = webregions[i].draggable; - regions.push_back(region); + + regions.reserve(webregions.size()); + for (const auto& webregion : webregions) { + auto region = cef::mojom::DraggableRegionEntry::New(webregion.bounds, + webregion.draggable); + render_frame->ConvertViewportToWindow(®ion->bounds); + regions.push_back(std::move(region)); + } + } + + auto& browser_frame = GetBrowserFrame(); + if (browser_frame) { + browser_frame->UpdateDraggableRegions( + regions.empty() ? base::nullopt + : base::make_optional(std::move(regions))); } - Send(new CefHostMsg_UpdateDraggableRegions(MSG_ROUTING_NONE, regions)); } void CefFrameImpl::OnDetached() { + // Called when this frame has been detached from the view. This *will* be + // called for child frames when a parent frame is detached. // The browser may hold the last reference to |this|. Take a reference here to // keep |this| alive until after this method returns. CefRefPtr self = this; browser_->FrameDetached(frame_id_); + receivers_.Clear(); + browser_frame_.reset(); browser_ = nullptr; frame_ = nullptr; url_loader_factory_.reset(); - response_manager_.reset(); } -void CefFrameImpl::ExecuteCommand(const std::string& command) { - CEF_REQUIRE_RT_RETURN_VOID(); - if (frame_) - frame_->ExecuteCommand(blink::WebString::FromUTF8(command)); +const mojo::Remote& CefFrameImpl::GetBrowserFrame() { + if (!browser_frame_.is_bound()) { + auto render_frame = content::RenderFrameImpl::FromWebFrame(frame_); + if (render_frame) { + // Triggers creation of a CefBrowserFrame in the browser process. + render_frame->GetBrowserInterfaceBroker()->GetInterface( + browser_frame_.BindNewPipeAndPassReceiver()); + } + } + return browser_frame_; } -void CefFrameImpl::SendProcessMessage(CefProcessId target_process, - const std::string& name, - base::ListValue* arguments, - bool user_initiated) { - DCHECK_EQ(PID_BROWSER, target_process); - DCHECK(!name.empty()); - - if (!frame_) - return; - - Cef_Request_Params params; - params.name = name; - if (arguments) - params.arguments.Swap(arguments); - params.user_initiated = user_initiated; - params.request_id = -1; - params.expect_response = false; - - Send(new CefHostMsg_Request(MSG_ROUTING_NONE, params)); +void CefFrameImpl::BindRenderFrameReceiver( + mojo::PendingReceiver receiver) { + receivers_.Add(this, std::move(receiver)); } -void CefFrameImpl::Send(IPC::Message* message) { - if (!frame_) { - delete message; - return; - } - - auto render_frame = content::RenderFrame::FromWebFrame(frame_); - message->set_routing_id(render_frame->GetRoutingID()); - render_frame->Send(message); -} - -void CefFrameImpl::OnRequest(const Cef_Request_Params& params) { - DCHECK(browser_); - DCHECK(frame_); - - bool success = false; - std::string response; - bool expect_response_ack = false; - - TRACE_EVENT2("cef", "CefBrowserImpl::OnRequest", "request_id", - params.request_id, "expect_response", - params.expect_response ? 1 : 0); - - if (params.user_initiated) { - // Give the user a chance to handle the request. - CefRefPtr app = CefAppManager::Get()->GetApplication(); - if (app.get()) { - CefRefPtr handler = - app->GetRenderProcessHandler(); - if (handler.get()) { - CefRefPtr message(new CefProcessMessageImpl( - const_cast(¶ms), false, true)); - success = handler->OnProcessMessageReceived(browser_, this, PID_BROWSER, - message.get()); - message->Detach(nullptr); - } +void CefFrameImpl::SendMessage(const std::string& name, base::Value arguments) { + if (auto app = CefAppManager::Get()->GetApplication()) { + if (auto handler = app->GetRenderProcessHandler()) { + auto& list_value = base::Value::AsListValue(arguments); + CefRefPtr message(new CefProcessMessageImpl( + name, const_cast(&list_value), /*read_only=*/true)); + handler->OnProcessMessageReceived(browser_, this, PID_BROWSER, + message.get()); + message->Detach(); } - } else if (params.name == "execute-code") { - // Execute code. - DCHECK_EQ(params.arguments.GetSize(), (size_t)4); - - bool is_javascript = false; - std::string code, script_url; - int script_start_line = 0; - - params.arguments.GetBoolean(0, &is_javascript); - params.arguments.GetString(1, &code); - DCHECK(!code.empty()); - params.arguments.GetString(2, &script_url); - params.arguments.GetInteger(3, &script_start_line); - DCHECK_GE(script_start_line, 0); - - if (is_javascript) { - frame_->ExecuteScript( - blink::WebScriptSource(blink::WebString::FromUTF8(code), - GURL(script_url), script_start_line)); - success = true; - } else { - // TODO(cef): implement support for CSS code. - NOTIMPLEMENTED(); - } - } else if (params.name == "execute-command") { - // Execute command. - DCHECK_EQ(params.arguments.GetSize(), (size_t)1); + } +} - std::string command; +void CefFrameImpl::SendCommand(const std::string& command) { + CEF_REQUIRE_RT_RETURN_VOID(); + if (frame_) { + frame_->ExecuteCommand(blink::WebString::FromUTF8(command)); + } +} - params.arguments.GetString(0, &command); - DCHECK(!command.empty()); +void CefFrameImpl::SendCommandWithResponse( + const std::string& command, + cef::mojom::RenderFrame::SendCommandWithResponseCallback callback) { + blink::WebString response; + if (frame_) { if (base::LowerCaseEqualsASCII(command, "getsource")) { response = blink_glue::DumpDocumentMarkup(frame_); - success = true; } else if (base::LowerCaseEqualsASCII(command, "gettext")) { response = blink_glue::DumpDocumentText(frame_); - success = true; - } else if (frame_->ExecuteCommand(blink::WebString::FromUTF8(command))) { - success = true; } - } else { - // Invalid request. - NOTREACHED(); } - if (params.expect_response) { - DCHECK_GE(params.request_id, 0); - - // Send a response to the browser. - Cef_Response_Params response_params; - response_params.request_id = params.request_id; - response_params.success = success; - response_params.response = response; - response_params.expect_response_ack = expect_response_ack; - Send(new CefHostMsg_Response(MSG_ROUTING_NONE, response_params)); - } + std::move(callback).Run(string_util::CreateSharedMemoryRegion(response)); } -void CefFrameImpl::OnResponse(const Cef_Response_Params& params) { - response_manager_->RunHandler(params); - if (params.expect_response_ack) - Send(new CefHostMsg_ResponseAck(MSG_ROUTING_NONE, params.request_id)); +void CefFrameImpl::SendJavaScript(const std::u16string& jsCode, + const std::string& scriptUrl, + int32_t startLine) { + CEF_REQUIRE_RT_RETURN_VOID(); + if (frame_) { + frame_->ExecuteScript(blink::WebScriptSource( + blink::WebString::FromUTF16(jsCode), GURL(scriptUrl), startLine)); + } } -void CefFrameImpl::OnResponseAck(int request_id) { - response_manager_->RunAckHandler(request_id); +void CefFrameImpl::LoadRequest(cef::mojom::RequestParamsPtr params) { + CEF_REQUIRE_RT_RETURN_VOID(); + if (frame_) { + blink::WebURLRequest request; + CefRequestImpl::Get(params, request); + blink_glue::StartNavigation(frame_, request); + } } -void CefFrameImpl::OnDidStopLoading() { +void CefFrameImpl::DidStopLoading() { // We should only receive this notification for the highest-level LocalFrame - // in this frame's in-process subtree. If there are multiple of these for the - // same browser then the other occurrences will be discarded in + // in this frame's in-process subtree. If there are multiple of these for + // the same browser then the other occurrences will be discarded in // OnLoadingStateChange. browser_->OnLoadingStateChange(false); } -void CefFrameImpl::OnMoveOrResizeStarted() { +void CefFrameImpl::MoveOrResizeStarted() { if (frame_) { auto web_view = frame_->View(); if (web_view) @@ -542,15 +464,6 @@ void CefFrameImpl::OnMoveOrResizeStarted() { } } -void CefFrameImpl::OnLoadRequest(const CefMsg_LoadRequest_Params& params) { - DCHECK(frame_); - - blink::WebURLRequest request; - CefRequestImpl::Get(params, request); - - blink_glue::StartNavigation(frame_, request); -} - // Enable deprecation warnings on Windows. See http://crbug.com/585142. #if defined(OS_WIN) #if defined(__clang__) diff --git a/libcef/renderer/frame_impl.h b/libcef/renderer/frame_impl.h index f587e0340..36b5b2bbd 100644 --- a/libcef/renderer/frame_impl.h +++ b/libcef/renderer/frame_impl.h @@ -10,6 +10,13 @@ #include "include/cef_frame.h" #include "include/cef_v8.h" +#include "base/memory/weak_ptr.h" +#include "cef/libcef/common/mojom/cef.mojom.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" +#include "mojo/public/cpp/bindings/receiver_set.h" +#include "mojo/public/cpp/bindings/remote.h" +#include "services/service_manager/public/cpp/binder_registry.h" + namespace base { class ListValue; } @@ -21,22 +28,14 @@ class WebURLLoader; class WebURLLoaderFactory; } // namespace blink -namespace IPC { -class Message; -} - class GURL; class CefBrowserImpl; -class CefResponseManager; -struct CefMsg_LoadRequest_Params; -struct Cef_Request_Params; -struct Cef_Response_Params; // Implementation of CefFrame. CefFrameImpl objects are owned by the // CefBrowerImpl and will be detached when the browser is notified that the // associated renderer WebFrame will close. -class CefFrameImpl : public CefFrame { +class CefFrameImpl : public CefFrame, public cef::mojom::RenderFrame { public: CefFrameImpl(CefBrowserImpl* browser, blink::WebLocalFrame* frame, @@ -81,8 +80,7 @@ class CefFrameImpl : public CefFrame { CreateResourceLoadInfoNotifierWrapper(); // Forwarded from CefRenderFrameObserver. - void OnAttached(); - bool OnMessageReceived(const IPC::Message& message); + void OnAttached(service_manager::BinderRegistry* registry); void OnDidFinishLoad(); void OnDraggableRegionsChanged(); void OnDetached(); @@ -90,24 +88,25 @@ class CefFrameImpl : public CefFrame { blink::WebLocalFrame* web_frame() const { return frame_; } private: - void ExecuteCommand(const std::string& command); - - // Avoids unnecessary string type conversions. - void SendProcessMessage(CefProcessId target_process, - const std::string& name, - base::ListValue* arguments, - bool user_initiated); - - // Send a message to the RenderFrame associated with this frame. - void Send(IPC::Message* message); - - // OnMessageReceived message handlers. - void OnRequest(const Cef_Request_Params& params); - void OnResponse(const Cef_Response_Params& params); - void OnResponseAck(int request_id); - void OnDidStopLoading(); - void OnMoveOrResizeStarted(); - void OnLoadRequest(const CefMsg_LoadRequest_Params& params); + // Returns the remote BrowserFrame object. + const mojo::Remote& GetBrowserFrame(); + + void BindRenderFrameReceiver( + mojo::PendingReceiver receiver); + + // cef::mojom::RenderFrame methods: + void SendMessage(const std::string& name, base::Value arguments) override; + void SendCommand(const std::string& command) override; + void SendCommandWithResponse( + const std::string& command, + cef::mojom::RenderFrame::SendCommandWithResponseCallback callback) + override; + void SendJavaScript(const std::u16string& jsCode, + const std::string& scriptUrl, + int32_t startLine) override; + void LoadRequest(cef::mojom::RequestParamsPtr params) override; + void DidStopLoading() override; + void MoveOrResizeStarted() override; CefBrowserImpl* browser_; blink::WebLocalFrame* frame_; @@ -115,8 +114,11 @@ class CefFrameImpl : public CefFrame { std::unique_ptr url_loader_factory_; - // Manages response registrations. - std::unique_ptr response_manager_; + mojo::ReceiverSet receivers_; + + mojo::Remote browser_frame_; + + base::WeakPtrFactory weak_ptr_factory_{this}; IMPLEMENT_REFCOUNTING(CefFrameImpl); DISALLOW_COPY_AND_ASSIGN(CefFrameImpl); diff --git a/libcef/renderer/render_frame_observer.cc b/libcef/renderer/render_frame_observer.cc index 0459ab60e..bb4fe8c62 100644 --- a/libcef/renderer/render_frame_observer.cc +++ b/libcef/renderer/render_frame_observer.cc @@ -180,18 +180,23 @@ void CefRenderFrameObserver::OnDestruct() { delete this; } -bool CefRenderFrameObserver::OnMessageReceived(const IPC::Message& message) { - if (frame_) { - return frame_->OnMessageReceived(message); - } - return false; +void CefRenderFrameObserver::OnInterfaceRequestForFrame( + const std::string& interface_name, + mojo::ScopedMessagePipeHandle* interface_pipe) { + registry_.TryBindInterface(interface_name, interface_pipe); +} + +bool CefRenderFrameObserver::OnAssociatedInterfaceRequestForFrame( + const std::string& interface_name, + mojo::ScopedInterfaceEndpointHandle* handle) { + return associated_interfaces_.TryBindInterface(interface_name, handle); } void CefRenderFrameObserver::AttachFrame(CefFrameImpl* frame) { DCHECK(frame); DCHECK(!frame_); frame_ = frame; - frame_->OnAttached(); + frame_->OnAttached(®istry_); } void CefRenderFrameObserver::OnLoadStart() { diff --git a/libcef/renderer/render_frame_observer.h b/libcef/renderer/render_frame_observer.h index efd93bc65..2b61e2834 100644 --- a/libcef/renderer/render_frame_observer.h +++ b/libcef/renderer/render_frame_observer.h @@ -7,6 +7,9 @@ #include "content/public/renderer/render_frame_observer.h" +#include "services/service_manager/public/cpp/binder_registry.h" +#include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h" + namespace content { class RenderFrame; class RenderView; @@ -31,7 +34,17 @@ class CefRenderFrameObserver : public content::RenderFrameObserver { void WillReleaseScriptContext(v8::Handle context, int world_id) override; void OnDestruct() override; - bool OnMessageReceived(const IPC::Message& message) override; + void OnInterfaceRequestForFrame( + const std::string& interface_name, + mojo::ScopedMessagePipeHandle* interface_pipe) override; + bool OnAssociatedInterfaceRequestForFrame( + const std::string& interface_name, + mojo::ScopedInterfaceEndpointHandle* handle) override; + + service_manager::BinderRegistry* registry() { return ®istry_; } + blink::AssociatedInterfaceRegistry* associated_interfaces() { + return &associated_interfaces_; + } void AttachFrame(CefFrameImpl* frame); @@ -41,6 +54,13 @@ class CefRenderFrameObserver : public content::RenderFrameObserver { CefFrameImpl* frame_ = nullptr; + service_manager::BinderRegistry registry_; + + // For interfaces which must be associated with some IPC::ChannelProxy, + // meaning that messages on the interface retain FIFO with respect to legacy + // Chrome IPC messages sent or dispatched on the channel. + blink::AssociatedInterfaceRegistry associated_interfaces_; + DISALLOW_COPY_AND_ASSIGN(CefRenderFrameObserver); }; diff --git a/libcef/renderer/browser_manager.cc b/libcef/renderer/render_manager.cc similarity index 65% rename from libcef/renderer/browser_manager.cc rename to libcef/renderer/render_manager.cc index 3657c2e14..7bf0203d0 100644 --- a/libcef/renderer/browser_manager.cc +++ b/libcef/renderer/render_manager.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can // be found in the LICENSE file. -#include "libcef/renderer/browser_manager.h" +#include "libcef/renderer/render_manager.h" #include "base/compiler_specific.h" @@ -18,7 +18,6 @@ #endif #include "libcef/common/app_manager.h" -#include "libcef/common/cef_messages.h" #include "libcef/common/cef_switches.h" #include "libcef/common/net/scheme_info.h" #include "libcef/common/values_impl.h" @@ -30,24 +29,28 @@ #include "base/command_line.h" #include "base/strings/string_number_conversions.h" +#include "cef/libcef/common/mojom/cef.mojom.h" #include "content/public/renderer/render_frame.h" #include "content/public/renderer/render_thread.h" #include "content/public/renderer/render_view.h" +#include "mojo/public/cpp/bindings/binder_map.h" #include "services/network/public/mojom/cors_origin_pattern.mojom.h" +#include "third_party/blink/public/platform/web_string.h" +#include "third_party/blink/public/platform/web_url.h" #include "third_party/blink/public/web/web_security_policy.h" #include "third_party/blink/public/web/web_view.h" #include "third_party/blink/public/web/web_view_observer.h" namespace { -CefBrowserManager* g_manager = nullptr; +CefRenderManager* g_manager = nullptr; } // namespace // Placeholder object for guest views. class CefGuestView : public blink::WebViewObserver { public: - CefGuestView(CefBrowserManager* manager, + CefGuestView(CefRenderManager* manager, content::RenderView* render_view, bool is_windowless) : blink::WebViewObserver(render_view->GetWebView()), @@ -60,39 +63,40 @@ class CefGuestView : public blink::WebViewObserver { // RenderViewObserver methods. void OnDestruct() override { manager_->OnGuestViewDestroyed(this); } - CefBrowserManager* const manager_; + CefRenderManager* const manager_; const bool is_windowless_; }; -CefBrowserManager::CefBrowserManager() { +CefRenderManager::CefRenderManager() { DCHECK(!g_manager); g_manager = this; } -CefBrowserManager::~CefBrowserManager() { +CefRenderManager::~CefRenderManager() { g_manager = nullptr; } // static -CefBrowserManager* CefBrowserManager::Get() { +CefRenderManager* CefRenderManager::Get() { CEF_REQUIRE_RT_RETURN(nullptr); return g_manager; } -void CefBrowserManager::RenderThreadConnected() { - content::RenderThread* thread = content::RenderThread::Get(); - +void CefRenderManager::RenderThreadConnected() { // Retrieve the new render thread information synchronously. - CefProcessHostMsg_GetNewRenderThreadInfo_Params params; - thread->Send(new CefProcessHostMsg_GetNewRenderThreadInfo(¶ms)); + auto params = cef::mojom::NewRenderThreadInfo::New(); + GetBrowserManager()->GetNewRenderThreadInfo(¶ms); // Cross-origin entries need to be added after WebKit is initialized. - cross_origin_whitelist_entries_ = params.cross_origin_whitelist_entries; + if (params->cross_origin_whitelist_entries) { + cross_origin_whitelist_entries_.swap( + *params->cross_origin_whitelist_entries); + } WebKitInitialized(); } -void CefBrowserManager::RenderFrameCreated( +void CefRenderManager::RenderFrameCreated( content::RenderFrame* render_frame, CefRenderFrameObserver* render_frame_observer, bool& browser_created, @@ -106,18 +110,18 @@ void CefBrowserManager::RenderFrameCreated( } } -void CefBrowserManager::RenderViewCreated(content::RenderView* render_view, - bool& browser_created, - base::Optional& is_windowless) { +void CefRenderManager::RenderViewCreated(content::RenderView* render_view, + bool& browser_created, + base::Optional& is_windowless) { MaybeCreateBrowser(render_view, render_view->GetMainRenderFrame(), &browser_created, &is_windowless); } -void CefBrowserManager::DevToolsAgentAttached() { +void CefRenderManager::DevToolsAgentAttached() { ++devtools_agent_count_; } -void CefBrowserManager::DevToolsAgentDetached() { +void CefRenderManager::DevToolsAgentDetached() { --devtools_agent_count_; if (devtools_agent_count_ == 0 && uncaught_exception_stack_size_ > 0) { // When the last DevToolsAgent is detached the stack size is set to 0. @@ -126,7 +130,20 @@ void CefBrowserManager::DevToolsAgentDetached() { } } -CefRefPtr CefBrowserManager::GetBrowserForView( +void CefRenderManager::ExposeInterfacesToBrowser(mojo::BinderMap* binders) { + auto task_runner = base::SequencedTaskRunnerHandle::Get(); + + binders->Add( + base::BindRepeating( + [](CefRenderManager* render_manager, + mojo::PendingReceiver receiver) { + render_manager->BindReceiver(std::move(receiver)); + }, + base::Unretained(this)), + task_runner); +} + +CefRefPtr CefRenderManager::GetBrowserForView( content::RenderView* view) { BrowserMap::const_iterator it = browsers_.find(view); if (it != browsers_.end()) @@ -134,7 +151,7 @@ CefRefPtr CefBrowserManager::GetBrowserForView( return nullptr; } -CefRefPtr CefBrowserManager::GetBrowserForMainFrame( +CefRefPtr CefRenderManager::GetBrowserForMainFrame( blink::WebFrame* frame) { BrowserMap::const_iterator it = browsers_.begin(); for (; it != browsers_.end(); ++it) { @@ -147,7 +164,44 @@ CefRefPtr CefBrowserManager::GetBrowserForMainFrame( return nullptr; } -void CefBrowserManager::WebKitInitialized() { +mojo::Remote& +CefRenderManager::GetBrowserManager() { + if (!browser_manager_) { + content::RenderThread::Get()->BindHostReceiver( + browser_manager_.BindNewPipeAndPassReceiver()); + } + return browser_manager_; +} + +void CefRenderManager::BindReceiver( + mojo::PendingReceiver receiver) { + receivers_.Add(this, std::move(receiver)); +} + +void CefRenderManager::ModifyCrossOriginWhitelistEntry( + bool add, + cef::mojom::CrossOriginWhiteListEntryPtr entry) { + GURL gurl = GURL(entry->source_origin); + if (add) { + blink::WebSecurityPolicy::AddOriginAccessAllowListEntry( + gurl, blink::WebString::FromUTF8(entry->target_protocol), + blink::WebString::FromUTF8(entry->target_domain), + /*destination_port=*/0, + entry->allow_target_subdomains + ? network::mojom::CorsDomainMatchMode::kAllowSubdomains + : network::mojom::CorsDomainMatchMode::kDisallowSubdomains, + network::mojom::CorsPortMatchMode::kAllowAnyPort, + network::mojom::CorsOriginAccessMatchPriority::kDefaultPriority); + } else { + blink::WebSecurityPolicy::ClearOriginAccessListForOrigin(gurl); + } +} + +void CefRenderManager::ClearCrossOriginWhitelist() { + blink::WebSecurityPolicy::ClearOriginAccessList(); +} + +void CefRenderManager::WebKitInitialized() { const base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); @@ -173,19 +227,8 @@ void CefBrowserManager::WebKitInitialized() { if (!cross_origin_whitelist_entries_.empty()) { // Add the cross-origin white list entries. - for (size_t i = 0; i < cross_origin_whitelist_entries_.size(); ++i) { - const Cef_CrossOriginWhiteListEntry_Params& entry = - cross_origin_whitelist_entries_[i]; - GURL gurl = GURL(entry.source_origin); - blink::WebSecurityPolicy::AddOriginAccessAllowListEntry( - gurl, blink::WebString::FromUTF8(entry.target_protocol), - blink::WebString::FromUTF8(entry.target_domain), - /*destination_port=*/0, - entry.allow_target_subdomains - ? network::mojom::CorsDomainMatchMode::kAllowSubdomains - : network::mojom::CorsDomainMatchMode::kDisallowSubdomains, - network::mojom::CorsPortMatchMode::kAllowAnyPort, - network::mojom::CorsOriginAccessMatchPriority::kDefaultPriority); + for (auto& entry : cross_origin_whitelist_entries_) { + ModifyCrossOriginWhitelistEntry(/*add=*/true, std::move(entry)); } cross_origin_whitelist_entries_.clear(); } @@ -213,7 +256,7 @@ void CefBrowserManager::WebKitInitialized() { } } -CefRefPtr CefBrowserManager::MaybeCreateBrowser( +CefRefPtr CefRenderManager::MaybeCreateBrowser( content::RenderView* render_view, content::RenderFrame* render_frame, bool* browser_created, @@ -246,30 +289,29 @@ CefRefPtr CefBrowserManager::MaybeCreateBrowser( // Retrieve the browser information synchronously. This will also register // the routing ids with the browser info object in the browser process. - CefProcessHostMsg_GetNewBrowserInfo_Params params; - content::RenderThread::Get()->Send(new CefProcessHostMsg_GetNewBrowserInfo( - render_frame_routing_id, ¶ms)); + auto params = cef::mojom::NewBrowserInfo::New(); + GetBrowserManager()->GetNewBrowserInfo(render_frame_routing_id, ¶ms); if (is_windowless) { - *is_windowless = params.is_windowless; + *is_windowless = params->is_windowless; } - if (params.browser_id == 0) { + if (params->browser_id == 0) { // The popup may have been canceled during creation. return nullptr; } - if (params.is_guest_view || params.browser_id < 0) { + if (params->is_guest_view || params->browser_id < 0) { // Don't create a CefBrowser for guest views, or if the new browser info // response has timed out. guest_views_.insert(std::make_pair( render_view, std::make_unique(this, render_view, - params.is_windowless))); + params->is_windowless))); return nullptr; } - browser = new CefBrowserImpl(render_view, params.browser_id, params.is_popup, - params.is_windowless); + browser = new CefBrowserImpl(render_view, params->browser_id, + params->is_popup, params->is_windowless); browsers_.insert(std::make_pair(render_view, browser)); // Notify the render process handler. @@ -278,10 +320,16 @@ CefRefPtr CefBrowserManager::MaybeCreateBrowser( CefRefPtr handler = application->GetRenderProcessHandler(); if (handler.get()) { - CefRefPtr dictValuePtr( - new CefDictionaryValueImpl(¶ms.extra_info, false, true)); + CefRefPtr dictValuePtr; + if (params->extra_info) { + auto& dict_value = base::Value::AsDictionaryValue(*params->extra_info); + dictValuePtr = new CefDictionaryValueImpl( + const_cast(&dict_value), + /*will_delete=*/false, /*read_only=*/true); + } handler->OnBrowserCreated(browser.get(), dictValuePtr.get()); - dictValuePtr->Detach(nullptr); + if (dictValuePtr) + ignore_result(dictValuePtr->Detach(nullptr)); } } @@ -291,7 +339,7 @@ CefRefPtr CefBrowserManager::MaybeCreateBrowser( return browser; } -void CefBrowserManager::OnBrowserDestroyed(CefBrowserImpl* browser) { +void CefRenderManager::OnBrowserDestroyed(CefBrowserImpl* browser) { BrowserMap::iterator it = browsers_.begin(); for (; it != browsers_.end(); ++it) { if (it->second.get() == browser) { @@ -304,8 +352,7 @@ void CefBrowserManager::OnBrowserDestroyed(CefBrowserImpl* browser) { NOTREACHED(); } -CefGuestView* CefBrowserManager::GetGuestViewForView( - content::RenderView* view) { +CefGuestView* CefRenderManager::GetGuestViewForView(content::RenderView* view) { CEF_REQUIRE_RT_RETURN(nullptr); GuestViewMap::const_iterator it = guest_views_.find(view); @@ -314,7 +361,7 @@ CefGuestView* CefBrowserManager::GetGuestViewForView( return nullptr; } -void CefBrowserManager::OnGuestViewDestroyed(CefGuestView* guest_view) { +void CefRenderManager::OnGuestViewDestroyed(CefGuestView* guest_view) { GuestViewMap::iterator it = guest_views_.begin(); for (; it != guest_views_.end(); ++it) { if (it->second.get() == guest_view) { diff --git a/libcef/renderer/browser_manager.h b/libcef/renderer/render_manager.h similarity index 67% rename from libcef/renderer/browser_manager.h rename to libcef/renderer/render_manager.h index 1bd1aa93f..cff83f4ba 100644 --- a/libcef/renderer/browser_manager.h +++ b/libcef/renderer/render_manager.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can // be found in the LICENSE file. -#ifndef CEF_LIBCEF_RENDERER_BROWSER_MANAGER_H_ -#define CEF_LIBCEF_RENDERER_BROWSER_MANAGER_H_ +#ifndef CEF_LIBCEF_RENDERER_RENDER_MANAGER_H_ +#define CEF_LIBCEF_RENDERER_RENDER_MANAGER_H_ #pragma once #include @@ -12,6 +12,10 @@ #include "include/internal/cef_ptr.h" #include "base/optional.h" +#include "cef/libcef/common/mojom/cef.mojom.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" +#include "mojo/public/cpp/bindings/receiver_set.h" +#include "mojo/public/cpp/bindings/remote.h" namespace blink { class WebFrame; @@ -22,20 +26,23 @@ class RenderFrame; class RenderView; } // namespace content -struct Cef_CrossOriginWhiteListEntry_Params; +namespace mojo { +class BinderMap; +} // namespace mojo + class CefBrowserImpl; class CefGuestView; class CefRenderFrameObserver; // Singleton object for managing BrowserImpl instances. Only accessed on the // main renderer thread. -class CefBrowserManager { +class CefRenderManager : public cef::mojom::RenderManager { public: - CefBrowserManager(); - ~CefBrowserManager(); + CefRenderManager(); + ~CefRenderManager(); // Returns this singleton instance of this class. - static CefBrowserManager* Get(); + static CefRenderManager* Get(); // Called from ContentRendererClient methods of the same name. void RenderThreadConnected(); @@ -48,6 +55,7 @@ class CefBrowserManager { base::Optional& is_windowless); void DevToolsAgentAttached(); void DevToolsAgentDetached(); + void ExposeInterfacesToBrowser(mojo::BinderMap* binders); // Returns the browser associated with the specified RenderView. CefRefPtr GetBrowserForView(content::RenderView* view); @@ -55,10 +63,22 @@ class CefBrowserManager { // Returns the browser associated with the specified main WebFrame. CefRefPtr GetBrowserForMainFrame(blink::WebFrame* frame); + // Connects to CefBrowserManager in the browser process. + mojo::Remote& GetBrowserManager(); + private: friend class CefBrowserImpl; friend class CefGuestView; + // Binds receivers for the RenderManager interface. + void BindReceiver(mojo::PendingReceiver receiver); + + // cef::mojom::RenderManager methods: + void ModifyCrossOriginWhitelistEntry( + bool add, + cef::mojom::CrossOriginWhiteListEntryPtr entry) override; + void ClearCrossOriginWhitelist() override; + void WebKitInitialized(); // Maybe create a new browser object, return the existing one, or return @@ -88,13 +108,17 @@ class CefBrowserManager { GuestViewMap guest_views_; // Cross-origin white list entries that need to be registered with WebKit. - typedef std::vector CrossOriginList; - CrossOriginList cross_origin_whitelist_entries_; + std::vector + cross_origin_whitelist_entries_; int devtools_agent_count_ = 0; int uncaught_exception_stack_size_ = 0; - DISALLOW_COPY_AND_ASSIGN(CefBrowserManager); + mojo::ReceiverSet receivers_; + + mojo::Remote browser_manager_; + + DISALLOW_COPY_AND_ASSIGN(CefRenderManager); }; -#endif // CEF_LIBCEF_RENDERER_BROWSER_MANAGER_H_ +#endif // CEF_LIBCEF_RENDERER_RENDER_MANAGER_H_ diff --git a/libcef/renderer/render_thread_observer.cc b/libcef/renderer/render_thread_observer.cc deleted file mode 100644 index 1f92fcf4f..000000000 --- a/libcef/renderer/render_thread_observer.cc +++ /dev/null @@ -1,52 +0,0 @@ -/// Copyright (c) 2013 The Chromium Embedded Framework Authors. -// Portions (c) 2011 The Chromium 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/renderer/render_thread_observer.h" - -#include "libcef/common/cef_messages.h" -#include "libcef/renderer/blink_glue.h" - -#include "third_party/blink/public/platform/web_string.h" -#include "third_party/blink/public/platform/web_url.h" -#include "third_party/blink/public/web/web_security_policy.h" - -CefRenderThreadObserver::CefRenderThreadObserver() = default; -CefRenderThreadObserver::~CefRenderThreadObserver() = default; - -bool CefRenderThreadObserver::OnControlMessageReceived( - const IPC::Message& message) { - bool handled = true; - IPC_BEGIN_MESSAGE_MAP(CefRenderThreadObserver, message) - IPC_MESSAGE_HANDLER(CefProcessMsg_ModifyCrossOriginWhitelistEntry, - OnModifyCrossOriginWhitelistEntry) - IPC_MESSAGE_HANDLER(CefProcessMsg_ClearCrossOriginWhitelist, - OnClearCrossOriginWhitelist) - IPC_MESSAGE_UNHANDLED(handled = false) - IPC_END_MESSAGE_MAP() - return handled; -} - -void CefRenderThreadObserver::OnModifyCrossOriginWhitelistEntry( - bool add, - const Cef_CrossOriginWhiteListEntry_Params& params) { - GURL gurl = GURL(params.source_origin); - if (add) { - blink::WebSecurityPolicy::AddOriginAccessAllowListEntry( - gurl, blink::WebString::FromUTF8(params.target_protocol), - blink::WebString::FromUTF8(params.target_domain), - /*destination_port=*/0, - params.allow_target_subdomains - ? network::mojom::CorsDomainMatchMode::kAllowSubdomains - : network::mojom::CorsDomainMatchMode::kDisallowSubdomains, - network::mojom::CorsPortMatchMode::kAllowAnyPort, - network::mojom::CorsOriginAccessMatchPriority::kDefaultPriority); - } else { - blink::WebSecurityPolicy::ClearOriginAccessListForOrigin(gurl); - } -} - -void CefRenderThreadObserver::OnClearCrossOriginWhitelist() { - blink::WebSecurityPolicy::ClearOriginAccessList(); -} diff --git a/libcef/renderer/render_thread_observer.h b/libcef/renderer/render_thread_observer.h deleted file mode 100644 index cae0e6a50..000000000 --- a/libcef/renderer/render_thread_observer.h +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) 2013 The Chromium Embedded Framework Authors. -// Portions copyright (c) 2011 The Chromium 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_RENDERER_RENDER_THREAD_OBSERVER_H_ -#define CEF_LIBCEF_RENDERER_RENDER_THREAD_OBSERVER_H_ - -#include - -#include "base/compiler_specific.h" -#include "content/public/renderer/render_thread_observer.h" - -struct Cef_CrossOriginWhiteListEntry_Params; - -// This class sends and receives control messages in the renderer process. -class CefRenderThreadObserver : public content::RenderThreadObserver { - public: - CefRenderThreadObserver(); - ~CefRenderThreadObserver() override; - - private: - // content::RenderThreadObserver: - bool OnControlMessageReceived(const IPC::Message& message) override; - - // Message handlers called on the render thread. - void OnModifyCrossOriginWhitelistEntry( - bool add, - const Cef_CrossOriginWhiteListEntry_Params& params); - void OnClearCrossOriginWhitelist(); - - DISALLOW_COPY_AND_ASSIGN(CefRenderThreadObserver); -}; - -#endif // CEF_LIBCEF_RENDERER_RENDER_THREAD_OBSERVER_H_ diff --git a/libcef_dll/cpptoc/render_process_handler_cpptoc.cc b/libcef_dll/cpptoc/render_process_handler_cpptoc.cc index f9f1aa6c5..fc93063cb 100644 --- a/libcef_dll/cpptoc/render_process_handler_cpptoc.cc +++ b/libcef_dll/cpptoc/render_process_handler_cpptoc.cc @@ -9,7 +9,7 @@ // implementations. See the translator.README.txt file in the tools directory // for more information. // -// $hash=4fc8972b57ed97feef5f00dcfa77e32b8d63cb9a$ +// $hash=a668847c77e8d15cab3c8e2db9ef68b3f43882c8$ // #include "libcef_dll/cpptoc/render_process_handler_cpptoc.h" @@ -52,10 +52,7 @@ void CEF_CALLBACK render_process_handler_on_browser_created( DCHECK(browser); if (!browser) return; - // Verify param: extra_info; type: refptr_diff - DCHECK(extra_info); - if (!extra_info) - return; + // Unverified params: extra_info // Execute CefRenderProcessHandlerCppToC::Get(self)->OnBrowserCreated( diff --git a/libcef_dll/ctocpp/render_process_handler_ctocpp.cc b/libcef_dll/ctocpp/render_process_handler_ctocpp.cc index 4d4e1f4d5..9cf0e51bb 100644 --- a/libcef_dll/ctocpp/render_process_handler_ctocpp.cc +++ b/libcef_dll/ctocpp/render_process_handler_ctocpp.cc @@ -9,7 +9,7 @@ // implementations. See the translator.README.txt file in the tools directory // for more information. // -// $hash=4cc516704229f90c49852b46f932b8882b4bf8d4$ +// $hash=ef73c2a273a05144f419aca52f32ae4b3e12882a$ // #include "libcef_dll/ctocpp/render_process_handler_ctocpp.h" @@ -51,10 +51,7 @@ void CefRenderProcessHandlerCToCpp::OnBrowserCreated( DCHECK(browser.get()); if (!browser.get()) return; - // Verify param: extra_info; type: refptr_diff - DCHECK(extra_info.get()); - if (!extra_info.get()) - return; + // Unverified params: extra_info // Execute _struct->on_browser_created(_struct, CefBrowserCppToC::Wrap(browser), diff --git a/patch/patch.cfg b/patch/patch.cfg index 52a4562b6..be25fd26b 100644 --- a/patch/patch.cfg +++ b/patch/patch.cfg @@ -152,6 +152,11 @@ patches = [ # https://bitbucket.org/chromiumembedded/cef/issues/2798 'name': 'content_main_654986', }, + { + # Make content::FrameServiceBase usable with CefBrowserFrame. + # https://bitbucket.org/chromiumembedded/cef/issues/3123 + 'name': 'content_mojo_3123', + }, { # Fix missing check for defined(ENABLE_THEMES) in # renderer_preferences_util.cc on Linux. diff --git a/patch/patches/content_mojo_3123.patch b/patch/patches/content_mojo_3123.patch new file mode 100644 index 000000000..f1e42d11e --- /dev/null +++ b/patch/patches/content_mojo_3123.patch @@ -0,0 +1,23 @@ +diff --git content/public/browser/frame_service_base.h content/public/browser/frame_service_base.h +index af3218d8f6462..da6880cc57e90 100644 +--- content/public/browser/frame_service_base.h ++++ content/public/browser/frame_service_base.h +@@ -83,6 +83,8 @@ class FrameServiceBase : public Interface, public WebContentsObserver { + + void DidFinishNavigation(NavigationHandle* navigation_handle) final { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); ++ if (!ShouldCloseOnFinishNavigation()) ++ return; + + if (!navigation_handle->HasCommitted() || + navigation_handle->IsSameDocument() || +@@ -96,6 +98,9 @@ class FrameServiceBase : public Interface, public WebContentsObserver { + } + } + ++ // Used for CEF bindings that outlive navigation. ++ virtual bool ShouldCloseOnFinishNavigation() const { return true; } ++ + // Stops observing WebContents and delete |this|. + void Close() { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); diff --git a/tests/ceftests/frame_unittest.cc b/tests/ceftests/frame_unittest.cc index cfa2a7109..9a154566a 100644 --- a/tests/ceftests/frame_unittest.cc +++ b/tests/ceftests/frame_unittest.cc @@ -278,7 +278,7 @@ class FrameNavRendererTest : public ClientAppRenderer::Delegate, void OnBrowserCreated(CefRefPtr app, CefRefPtr browser, CefRefPtr extra_info) override { - if (!extra_info->HasKey(kFrameNavTestCmdKey)) + if (!extra_info || !extra_info->HasKey(kFrameNavTestCmdKey)) return; FrameNavFactoryId factory_id = diff --git a/tests/ceftests/navigation_unittest.cc b/tests/ceftests/navigation_unittest.cc index f0f98007d..f200b416e 100644 --- a/tests/ceftests/navigation_unittest.cc +++ b/tests/ceftests/navigation_unittest.cc @@ -67,7 +67,7 @@ class HistoryNavRendererTest : public ClientAppRenderer::Delegate, void OnBrowserCreated(CefRefPtr app, CefRefPtr browser, CefRefPtr extra_info) override { - run_test_ = extra_info->HasKey(kHistoryNavTestCmdKey); + run_test_ = extra_info && extra_info->HasKey(kHistoryNavTestCmdKey); } CefRefPtr GetLoadHandler( @@ -1147,7 +1147,7 @@ class OrderNavRendererTest : public ClientAppRenderer::Delegate, void OnBrowserCreated(CefRefPtr app, CefRefPtr browser, CefRefPtr extra_info) override { - run_test_ = extra_info->HasKey(kOrderNavTestCmdKey); + run_test_ = extra_info && extra_info->HasKey(kOrderNavTestCmdKey); if (!run_test_) return; @@ -1619,7 +1619,7 @@ class LoadNavRendererTest : public ClientAppRenderer::Delegate, void OnBrowserCreated(CefRefPtr app, CefRefPtr browser, CefRefPtr extra_info) override { - run_test_ = extra_info->HasKey(kLoadNavTestCmdKey); + run_test_ = extra_info && extra_info->HasKey(kLoadNavTestCmdKey); if (!run_test_) return; @@ -3394,7 +3394,7 @@ class ExtraInfoNavRendererTest : public ClientAppRenderer::Delegate { void OnBrowserCreated(CefRefPtr app, CefRefPtr browser, CefRefPtr extra_info) override { - run_test_ = extra_info->HasKey(kExtraInfoTestCmdKey); + run_test_ = extra_info && extra_info->HasKey(kExtraInfoTestCmdKey); if (!run_test_) return; diff --git a/tests/ceftests/process_message_unittest.cc b/tests/ceftests/process_message_unittest.cc index 262612871..598b0c0c3 100644 --- a/tests/ceftests/process_message_unittest.cc +++ b/tests/ceftests/process_message_unittest.cc @@ -78,8 +78,6 @@ class SendRecvTestHandler : public TestHandler { : send_thread_(send_thread) {} void RunTest() override { - message_ = CreateTestMessage(); - AddResource(kSendRecvUrl, "TEST", "text/html"); CreateBrowser(kSendRecvUrl); @@ -113,7 +111,7 @@ class SendRecvTestHandler : public TestHandler { EXPECT_TRUE(message->IsReadOnly()); // Verify that the recieved message is the same as the sent message. - TestProcessMessageEqual(message_, message); + TestProcessMessageEqual(CreateTestMessage(), message); got_message_.yes(); @@ -132,12 +130,10 @@ class SendRecvTestHandler : public TestHandler { private: void SendMessage(CefRefPtr browser, CefRefPtr frame) { EXPECT_TRUE(CefCurrentlyOn(send_thread_)); - frame->SendProcessMessage(PID_RENDERER, message_); + frame->SendProcessMessage(PID_RENDERER, CreateTestMessage()); } cef_thread_id_t send_thread_; - - CefRefPtr message_; TrackCallback got_message_; IMPLEMENT_REFCOUNTING(SendRecvTestHandler); @@ -171,7 +167,7 @@ TEST(ProcessMessageTest, Create) { CefRefPtr args = message->GetArgumentList(); EXPECT_TRUE(args.get()); EXPECT_TRUE(args->IsValid()); - EXPECT_TRUE(args->IsOwned()); + EXPECT_FALSE(args->IsOwned()); EXPECT_FALSE(args->IsReadOnly()); } diff --git a/tests/ceftests/request_handler_unittest.cc b/tests/ceftests/request_handler_unittest.cc index b04482e62..88b2ebe14 100644 --- a/tests/ceftests/request_handler_unittest.cc +++ b/tests/ceftests/request_handler_unittest.cc @@ -401,7 +401,7 @@ class NetNotifyRendererTest : public ClientAppRenderer::Delegate, void OnBrowserCreated(CefRefPtr app, CefRefPtr browser, CefRefPtr extra_info) override { - run_test_ = extra_info->HasKey(kNetNotifyTestCmdKey); + run_test_ = extra_info && extra_info->HasKey(kNetNotifyTestCmdKey); } CefRefPtr GetLoadHandler( diff --git a/tests/ceftests/v8_unittest.cc b/tests/ceftests/v8_unittest.cc index 95d22633d..509243ade 100644 --- a/tests/ceftests/v8_unittest.cc +++ b/tests/ceftests/v8_unittest.cc @@ -2467,7 +2467,7 @@ class V8RendererTest : public ClientAppRenderer::Delegate, void OnBrowserCreated(CefRefPtr app, CefRefPtr browser, CefRefPtr extra_info) override { - if (extra_info->HasKey(kV8TestCmdKey)) { + if (extra_info && extra_info->HasKey(kV8TestCmdKey)) { test_mode_ = static_cast(extra_info->GetInt(kV8TestCmdKey)); } if (test_mode_ > V8TEST_NONE)