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().
This commit is contained in:
Marshall Greenblatt 2021-05-14 12:58:55 -04:00
parent 4f0b7b4511
commit ebee84755e
82 changed files with 1615 additions and 2386 deletions

View File

@ -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",

View File

@ -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,

View File

@ -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

View File

@ -246,10 +246,12 @@ class CefFrame : public virtual CefBaseRefCounted {
CefRefPtr<CefURLRequestClient> 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,

View File

@ -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<CefBrowser> browser,
CefRefPtr<CefDictionaryValue> extra_info) {}

View File

@ -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<const char16*>(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<const char16*>(data),
length, s)
? true
: false;
}
@ -113,13 +124,18 @@ struct CefStringTraitsWide {
return std::u16string(
reinterpret_cast<const std::u16string::value_type*>(s->str), s->length);
}
static inline bool from_string16(const std::u16string& str, struct_type* s) {
return cef_string_wide_set(reinterpret_cast<const wchar_t*>(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<const wchar_t*>(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<const char16*>(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<const char16*>(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<const std::u16string::value_type*>(s->str), s->length);
}
static inline bool from_string16(const std::u16string& str, struct_type* s) {
return cef_string_utf16_set(reinterpret_cast<const char16*>(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<const char16*>(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<const std::u16string::value_type*>(src)));
FromString16(reinterpret_cast<const std::u16string::value_type*>(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<std::string::value_type>::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<std::wstring::value_type>::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<std::u16string::value_type>::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<const std::u16string::value_type*>(str)));
FromString16(reinterpret_cast<const std::u16string::value_type*>(str));
return *this;
}
#endif // WCHAR_T_IS_UTF32

View File

@ -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"

View File

@ -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<CefCommandLineImpl> 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<net::ClientCertStore>
@ -1292,6 +1293,8 @@ void AlloyContentBrowserClient::RegisterBrowserInterfaceBindersForFrame(
content::RenderFrameHost* render_frame_host,
mojo::BinderMapWithContext<content::RenderFrameHost*>* map) {
PopulateChromeFrameBinders(map);
CefBrowserFrame::RegisterBrowserInterfaceBindersForFrame(render_frame_host,
map);
if (!extensions::ExtensionsEnabled())
return;

View File

@ -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<CefFrameHostImpl*>(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.

View File

@ -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;

View File

@ -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<cef::mojom::BrowserFrame> receiver)
: FrameServiceBase(render_frame_host, std::move(receiver)) {}
CefBrowserFrame::~CefBrowserFrame() = default;
// static
void CefBrowserFrame::RegisterBrowserInterfaceBindersForFrame(
content::RenderFrameHost* render_frame_host,
mojo::BinderMapWithContext<content::RenderFrameHost*>* map) {
map->Add<cef::mojom::BrowserFrame>(base::BindRepeating(
[](content::RenderFrameHost* frame_host,
mojo::PendingReceiver<cef::mojom::BrowserFrame> 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<std::vector<cef::mojom::DraggableRegionEntryPtr>> regions) {
if (auto host = GetFrameHost()) {
host->UpdateDraggableRegions(std::move(regions));
}
}
CefRefPtr<CefFrameHostImpl> 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;
}

View File

@ -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<cef::mojom::BrowserFrame> {
public:
CefBrowserFrame(content::RenderFrameHost* render_frame_host,
mojo::PendingReceiver<cef::mojom::BrowserFrame> receiver);
~CefBrowserFrame() override;
// Called from the ContentBrowserClient method of the same name.
static void RegisterBrowserInterfaceBindersForFrame(
content::RenderFrameHost* render_frame_host,
mojo::BinderMapWithContext<content::RenderFrameHost*>* 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<std::vector<cef::mojom::DraggableRegionEntryPtr>> regions)
override;
// FrameServiceBase methods:
bool ShouldCloseOnFinishNavigation() const override { return false; }
CefRefPtr<CefFrameHostImpl> GetFrameHost() const;
DISALLOW_COPY_AND_ASSIGN(CefBrowserFrame);
};
#endif // CEF_LIBCEF_BROWSER_BROWSER_FRAME_H_

View File

@ -367,7 +367,7 @@ void CefBrowserHostBase::GetNavigationEntries(
CefRefPtr<CefNavigationEntryImpl> 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<CefNavigationEntryImpl> entry =
new CefNavigationEntryImpl(controller.GetEntryAtIndex(i));
cont = visitor->Visit(entry.get(), (i == current), i, total);
entry->Detach(nullptr);
ignore_result(entry->Detach(nullptr));
}
}
}

View File

@ -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<CefBrowserInfo> 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<CefBrowserInfo> 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<base::SequencedTaskRunner> 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<CefDictionaryValueImpl*>(extra_info.get());
auto extra_info_value = extra_info_impl->CopyValue();
extra_info_value->Swap(&params.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);
}
}

View File

@ -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<CefBrowserPlatformDelegate>& platform_delegate,
CefRefPtr<CefDictionaryValue>& 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<CefBrowserInfo> 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<base::SequencedTaskRunner> 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<base::SequencedTaskRunner> 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_|.

View File

@ -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<cef::mojom::BrowserManager> receiver) {
mojo::MakeSelfOwnedReceiver(
std::make_unique<CefBrowserManager>(render_process_id),
std::move(receiver));
},
host->GetID()));
}
// static
mojo::Remote<cef::mojom::RenderManager>
CefBrowserManager::GetRenderManagerForProcess(
content::RenderProcessHost* host) {
mojo::Remote<cef::mojom::RenderManager> 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));
}

View File

@ -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<cef::mojom::RenderManager> 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_

View File

@ -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(&params->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;
}
}

View File

@ -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 <stdint.h>
#include <string>
#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_

View File

@ -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<CefCommandLineImpl> 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<content::RenderFrameHost*>* map) {
ChromeContentBrowserClient::RegisterBrowserInterfaceBindersForFrame(
render_frame_host, map);
CefBrowserFrame::RegisterBrowserInterfaceBindersForFrame(render_frame_host,
map);
}
CefRefPtr<CefRequestContextImpl>
ChromeContentBrowserClientCef::request_context() const {
return browser_main_parts_->request_context();

View File

@ -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<content::RenderFrameHost*>* map) override;
CefRefPtr<CefRequestContextImpl> request_context() const;

View File

@ -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;

View File

@ -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"

View File

@ -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<CefStringVisitor> visitor)
: visitor_(visitor) {}
void OnResponse(const Cef_Response_Params& params) override {
visitor_->Visit(params.response);
void StringVisitCallback(CefRefPtr<CefStringVisitor> visitor,
base::ReadOnlySharedMemoryRegion response) {
string_util::ExecuteWithScopedCefString(
std::move(response),
base::BindOnce([](CefRefPtr<CefStringVisitor> visitor,
const CefString& str) { visitor->Visit(str); },
visitor));
}
void ViewTextCallback(CefRefPtr<CefFrameHostImpl> frame,
base::ReadOnlySharedMemoryRegion response) {
if (auto browser = frame->GetBrowser()) {
string_util::ExecuteWithScopedCefString(
std::move(response),
base::BindOnce(
[](CefRefPtr<CefBrowser> browser, const CefString& str) {
static_cast<CefBrowserHostBase*>(browser.get())->ViewText(str);
},
browser));
}
private:
CefRefPtr<CefStringVisitor> visitor_;
IMPLEMENT_REFCOUNTING(StringVisitHandler);
};
// Implementation of CommandResponseHandler for calling ViewText().
class ViewTextHandler : public CefResponseManager::Handler {
public:
explicit ViewTextHandler(CefRefPtr<CefFrameHostImpl> frame) : frame_(frame) {}
void OnResponse(const Cef_Response_Params& params) override {
CefRefPtr<CefBrowser> browser = frame_->GetBrowser();
if (browser.get()) {
static_cast<CefBrowserHostBase*>(browser.get())
->ViewText(params.response);
}
}
private:
CefRefPtr<CefFrameHostImpl> frame_;
IMPLEMENT_REFCOUNTING(ViewTextHandler);
};
}
} // namespace
@ -80,17 +69,13 @@ CefFrameHostImpl::CefFrameHostImpl(scoped_refptr<CefBrowserInfo> browser_info,
CefFrameHostImpl::CefFrameHostImpl(scoped_refptr<CefBrowserInfo> 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<CefFrameHostImpl>(this)));
}
void CefFrameHostImpl::GetSource(CefRefPtr<CefStringVisitor> visitor) {
SendCommand("GetSource", new StringVisitHandler(visitor));
SendCommandWithResponse("GetSource",
base::BindOnce(&StringVisitCallback, visitor));
}
void CefFrameHostImpl::GetText(CefRefPtr<CefStringVisitor> visitor) {
SendCommand("GetText", new StringVisitHandler(visitor));
SendCommandWithResponse("GetText",
base::BindOnce(&StringVisitCallback, visitor));
}
void CefFrameHostImpl::LoadRequest(CefRefPtr<CefRequest> request) {
CefNavigateParams params(GURL(), kPageTransitionExplicit);
auto params = cef::mojom::RequestParams::New();
static_cast<CefRequestImpl*>(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<CefProcessMessage> message) {
DCHECK_EQ(PID_RENDERER, target_process);
DCHECK(message.get());
Cef_Request_Params params;
CefProcessMessageImpl* impl =
static_cast<CefProcessMessageImpl*>(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<CefProcessMessage> message,
const RenderFrameType& render_frame) {
auto impl = static_cast<CefProcessMessageImpl*>(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<CefResponseManager::Handler> 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));
SendToRenderFrame(base::BindOnce(
[](const std::string& command, const RenderFrameType& render_frame) {
render_frame->SendCommand(command);
},
command));
}
void CefFrameHostImpl::SendCode(
bool is_javascript,
const std::string& code,
const std::string& script_url,
int script_start_line,
CefRefPtr<CefResponseManager::Handler> 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));
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::string& jsCode,
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,25 +478,84 @@ CefRefPtr<CefBrowserHostBase> CefFrameHostImpl::GetBrowserHostBase() const {
return nullptr;
}
void CefFrameHostImpl::OnAttached() {
const mojo::Remote<cef::mojom::RenderFrame>&
CefFrameHostImpl::GetRenderFrame() {
CEF_REQUIRE_UIT();
DCHECK(is_attached_);
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::SendToRenderFrame(RenderFrameAction action) {
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(CEF_UIT, base::BindOnce(&CefFrameHostImpl::SendToRenderFrame,
this, std::move(action)));
return;
}
if (!render_frame_host_) {
// Either we're a placeholder frame without a renderer representation, or
// we've been detached.
return;
}
if (!is_attached_) {
is_attached_ = true;
while (!queued_messages_.empty()) {
Send(queued_messages_.front().release());
queued_messages_.pop();
// Queue actions until we're notified by the renderer that it's ready to
// handle them.
queued_actions_.push(std::move(action));
return;
}
auto& render_frame = GetRenderFrame();
if (!render_frame)
return;
std::move(action).Run(render_frame);
}
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<CefProcessMessageImpl> message(new CefProcessMessageImpl(
name, const_cast<base::ListValue*>(&list_value), /*read_only=*/true));
browser->GetClient()->OnProcessMessageReceived(
browser.get(), this, PID_RENDERER, message.get());
message->Detach();
}
}
}
void CefFrameHostImpl::OnDidFinishLoad(const GURL& validated_url,
int http_status_code) {
void CefFrameHostImpl::FrameAttached() {
if (!is_attached_) {
is_attached_ = true;
auto& render_frame = GetRenderFrame();
while (!queued_actions_.empty()) {
if (render_frame) {
std::move(queued_actions_.front()).Run(render_frame);
}
queued_actions_.pop();
}
}
}
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::OnUpdateDraggableRegions(
const std::vector<Cef_DraggableRegion_Params>& regions) {
void CefFrameHostImpl::UpdateDraggableRegions(
base::Optional<std::vector<cef::mojom::DraggableRegionEntryPtr>> regions) {
auto browser = GetBrowserHostBase();
if (!browser)
return;
@ -602,91 +568,20 @@ void CefFrameHostImpl::OnUpdateDraggableRegions(
return;
std::vector<CefDraggableRegion> draggable_regions;
draggable_regions.reserve(regions.size());
if (regions) {
draggable_regions.reserve(regions->size());
std::vector<Cef_DraggableRegion_Params>::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));
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));
}
}
handler->OnDraggableRegionsChanged(browser.get(), this, draggable_regions);
}
void CefFrameHostImpl::OnRequest(const Cef_Request_Params& params) {
CEF_REQUIRE_UIT();
bool success = false;
std::string response;
bool expect_response_ack = false;
if (params.user_initiated) {
auto browser = GetBrowserHostBase();
if (browser && browser->GetClient()) {
// Give the user a chance to handle the request.
CefRefPtr<CefProcessMessageImpl> message(new CefProcessMessageImpl(
const_cast<Cef_Request_Params*>(&params), false, true));
success = browser->GetClient()->OnProcessMessageReceived(
browser.get(), this, PID_RENDERER, message.get());
message->Detach(nullptr);
}
} 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();
response_manager_->RunHandler(params);
if (params.expect_response_ack)
Send(new CefMsg_ResponseAck(MSG_ROUTING_NONE, params.request_id));
}
void CefFrameHostImpl::OnResponseAck(int request_id) {
response_manager_->RunAckHandler(request_id);
}
void CefFrameHostImpl::Send(IPC::Message* message) {
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(CEF_UIT,
base::BindOnce(base::IgnoreResult(&CefFrameHostImpl::Send),
this, message));
return;
}
if (!render_frame_host_) {
// Either we're a placeholder frame without a renderer representation, or
// we've been detached.
delete message;
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;
}
message->set_routing_id(render_frame_host_->GetRoutingID());
render_frame_host_->Send(message);
}
void CefExecuteJavaScriptWithUserGestureForTests(CefRefPtr<CefFrame> frame,
const CefString& javascript) {
CefFrameHostImpl* impl = static_cast<CefFrameHostImpl*>(frame.get());

View File

@ -11,9 +11,11 @@
#include <string>
#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<CefBrowserInfo> 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<CefResponseManager::Handler> 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<CefResponseManager::Handler> 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<std::vector<cef::mojom::DraggableRegionEntryPtr>> 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<CefBrowserHostBase> GetBrowserHostBase() const;
// OnMessageReceived message handlers.
void OnAttached();
void OnDidFinishLoad(const GURL& validated_url, int http_status_code);
void OnUpdateDraggableRegions(
const std::vector<Cef_DraggableRegion_Params>& 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<cef::mojom::RenderFrame>;
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(const RenderFrameType&)>;
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<std::unique_ptr<IPC::Message>> queued_messages_;
std::queue<RenderFrameAction> queued_actions_;
// Manages response registrations.
std::unique_ptr<CefResponseManager> response_manager_;
mojo::Remote<cef::mojom::RenderFrame> render_frame_;
IMPLEMENT_REFCOUNTING(CefFrameHostImpl);
DISALLOW_COPY_AND_ASSIGN(CefFrameHostImpl);

View File

@ -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<CefMenuModelImpl> 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)

View File

@ -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() {}

View File

@ -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 <string>
#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<net::UploadData> 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_

View File

@ -8,13 +8,14 @@
#include <vector>
#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<Cef_CrossOriginWhiteListEntry_Params>* entries) {
base::Optional<CrossOriginWhiteList>* 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<Cef_CrossOriginWhiteListEntry_Params> 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<Cef_CrossOriginWhiteListEntry_Params>* entries) {
base::Optional<CrossOriginWhiteList>* entries) {
CefOriginWhitelistManager::GetInstance()->GetCrossOriginWhitelistEntries(
entries);
}
@ -288,19 +300,6 @@ bool HasCrossOriginWhitelistEntry(const url::Origin& source,
return true;
}
std::vector<Cef_CrossOriginWhiteListEntry_Params> params;
CefOriginWhitelistManager::GetInstance()->GetCrossOriginWhitelistEntries(
&params);
if (params.empty())
return false;
std::vector<Cef_CrossOriginWhiteListEntry_Params>::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);
}

View File

@ -5,9 +5,12 @@
#ifndef CEF_LIBCEF_BROWSER_ORIGIN_WHITELIST_IMPL_H_
#define CEF_LIBCEF_BROWSER_ORIGIN_WHITELIST_IMPL_H_
#include <list>
#include <vector>
#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<cef::mojom::CrossOriginWhiteListEntryPtr>;
// Called to retrieve the current list of cross-origin white list entries. This
// method is thread safe.
void GetCrossOriginWhitelistEntries(
std::vector<Cef_CrossOriginWhiteListEntry_Params>* entries);
base::Optional<CrossOriginWhiteList>* entries);
// Returns true if |source| can access |target| based on the cross-origin white
// list settings.

View File

@ -11,12 +11,12 @@
CefPrintSettingsImpl::CefPrintSettingsImpl(
std::unique_ptr<printing::PrintSettings> settings,
bool read_only)
: CefValueBase<CefPrintSettings, printing::PrintSettings>(settings.get(),
nullptr,
kOwnerNoDelete,
read_only,
nullptr),
settings_(std::move(settings)) {}
: CefValueBase<CefPrintSettings, printing::PrintSettings>(
settings.release(),
nullptr,
kOwnerWillDelete,
read_only,
nullptr) {}
bool CefPrintSettingsImpl::IsValid() {
return !detached();
@ -152,8 +152,7 @@ CefPrintSettings::DuplexMode CefPrintSettingsImpl::GetDuplexMode() {
}
std::unique_ptr<printing::PrintSettings> CefPrintSettingsImpl::TakeOwnership() {
Detach(nullptr);
return std::move(settings_);
return base::WrapUnique(Detach(nullptr));
}
// CefPrintSettings implementation.

View File

@ -47,8 +47,6 @@ class CefPrintSettingsImpl
std::unique_ptr<printing::PrintSettings> TakeOwnership() WARN_UNUSED_RESULT;
private:
std::unique_ptr<printing::PrintSettings> settings_;
DISALLOW_COPY_AND_ASSIGN(CefPrintSettingsImpl);
};

View File

@ -21,8 +21,6 @@ class WebContentsObserver;
class CefBrowserInfo;
struct PrintHostMsg_RequestPrintPreview_Params;
namespace printing {
// CEF handler for print commands.

View File

@ -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.

View File

@ -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

View File

@ -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"

View File

@ -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<net::UploadElement> {
typedef net::UploadElement param_type;
static void Write(base::Pickle* m, const param_type& p) {
WriteParam(m, static_cast<int>(p.type()));
switch (p.type()) {
case net::UploadElement::TYPE_BYTES: {
m->WriteData(p.bytes(), static_cast<int>(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("<net::UploadElement>");
}
};
void ParamTraits<scoped_refptr<net::UploadData>>::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<scoped_refptr<net::UploadData>>::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<scoped_refptr<net::UploadData>>::Log(const param_type& p,
std::string* l) {
l->append("<net::UploadData>");
}
} // namespace IPC

View File

@ -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 <stdint.h>
#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<scoped_refptr<net::UploadData>> {
typedef scoped_refptr<net::UploadData> 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<net::UploadData>, 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<Cef_CrossOriginWhiteListEntry_Params>,
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<Cef_DraggableRegion_Params> /* regions */)

View File

@ -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)

View File

@ -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" ]
}

View File

@ -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<DraggableRegionEntry>? 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<CrossOriginWhiteListEntry>? 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();
};

View File

@ -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<UploadElement>());
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<UploadElement>());
elements_.back()->SetToFilePathRange(file_path, offset, length,
expected_modification_time);
}
UploadData::~UploadData() {}
} // namespace net

View File

@ -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 <stdint.h>
#include <memory>
#include <vector>
#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<UploadData>,
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<std::unique_ptr<UploadElement>>;
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>;
~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_

View File

@ -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<uint64_t>::max()) {}
UploadElement::~UploadElement() {}
} // namespace net

View File

@ -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 <stdint.h>
#include <limits>
#include <vector>
#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<uint64_t>::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<char> 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_

View File

@ -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"
namespace {
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());
}
} // namespace
#include "base/memory/ptr_util.h"
// static
CefRefPtr<CefProcessMessage> CefProcessMessage::Create(const CefString& name) {
Cef_Request_Params* params = new Cef_Request_Params();
params->name = name;
return new CefProcessMessageImpl(params, true, false);
return new CefProcessMessageImpl(name, CefListValue::Create());
}
CefProcessMessageImpl::CefProcessMessageImpl(Cef_Request_Params* value,
bool will_delete,
bool read_only)
: CefValueBase<CefProcessMessage, Cef_Request_Params>(
value,
nullptr,
will_delete ? kOwnerWillDelete : kOwnerNoDelete,
read_only,
nullptr) {}
CefProcessMessageImpl::CefProcessMessageImpl(const CefString& name,
CefRefPtr<CefListValue> arguments)
: name_(name), arguments_(arguments) {
DCHECK(!name_.empty());
DCHECK(arguments_);
}
bool CefProcessMessageImpl::CopyTo(Cef_Request_Params& target) {
CEF_VALUE_VERIFY_RETURN(false, false);
CopyValue(const_value(), target);
return true;
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());
}
CefProcessMessageImpl::~CefProcessMessageImpl() {
DCHECK(!should_detach_ || !arguments_->IsValid());
}
void CefProcessMessageImpl::Detach() {
DCHECK(IsValid());
DCHECK(should_detach_);
CefListValueImpl* value_impl =
static_cast<CefListValueImpl*>(arguments_.get());
ignore_result(value_impl->Detach(nullptr));
}
base::ListValue CefProcessMessageImpl::TakeArgumentList() {
DCHECK(IsValid());
CefListValueImpl* value_impl =
static_cast<CefListValueImpl*>(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<CefProcessMessage> 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<CefListValue> CefProcessMessageImpl::GetArgumentList() {
CEF_VALUE_VERIFY_RETURN(false, nullptr);
return CefListValueImpl::GetOrCreateRef(
const_cast<base::ListValue*>(&(const_value().arguments)),
const_cast<Cef_Request_Params*>(&const_value()), read_only(),
controller());
return arguments_;
}

View File

@ -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, Cef_Request_Params> {
// 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<CefListValue> 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<CefListValue> GetArgumentList() override;
private:
const CefString name_;
CefRefPtr<CefListValue> arguments_;
const bool should_detach_ = false;
IMPLEMENT_REFCOUNTING(CefProcessMessageImpl);
DISALLOW_COPY_AND_ASSIGN(CefProcessMessageImpl);
};

View File

@ -8,19 +8,15 @@
#include <utility>
#include <vector>
#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<net::UploadElement> element)
: net::UploadBytesElementReader(element->bytes(),
element->bytes_length()),
element_(std::move(element)) {
DCHECK_EQ(net::UploadElement::TYPE_BYTES, element_->type());
}
private:
std::unique_ptr<net::UploadElement> element_;
DISALLOW_COPY_AND_ASSIGN(BytesElementReader);
};
scoped_refptr<base::SequencedTaskRunner> 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<net::UploadElement> 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<base::SequencedTaskRunner> task_runner_;
std::unique_ptr<net::UploadElement> 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<std::unique_ptr<net::UploadElementReader>>
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<cef_referrer_policy_t>(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<cef_referrer_policy_t>(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<CefPostDataImpl*>(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<network::ResourceRequestBody> CefPostDataImpl::GetBody() const {
return body;
}
void CefPostDataImpl::Set(const net::UploadData& data) {
{
base::AutoLock lock_scope(lock_);
CHECK_READONLY_RETURN_VOID();
}
CefRefPtr<CefPostDataElement> postelem;
for (const auto& element : data.elements()) {
postelem = CefPostDataElement::Create();
static_cast<CefPostDataElementImpl*>(postelem.get())->Set(*element);
AddElement(postelem);
}
}
void CefPostDataImpl::Set(const net::UploadDataStream& data_stream) {
{
base::AutoLock lock_scope(lock_);
CHECK_READONLY_RETURN_VOID();
}
CefRefPtr<CefPostDataElement> 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<CefPostDataElementImpl*>(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<net::UploadElement> data_element =
std::make_unique<net::UploadElement>();
static_cast<CefPostDataElementImpl*>(element.get())
->Get(*data_element.get());
data_elements.push_back(std::move(data_element));
}
data.swap_elements(&data_elements);
}
std::unique_ptr<net::UploadDataStream> CefPostDataImpl::Get() const {
base::AutoLock lock_scope(lock_);
UploadElementReaders element_readers;
for (const auto& element : elements_) {
element_readers.push_back(
static_cast<CefPostDataElementImpl*>(element.get())->Get());
}
return std::make_unique<net::ElementsUploadDataStream>(
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<char*>(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<net::UploadElementReader> CefPostDataElementImpl::Get() const {
base::AutoLock lock_scope(lock_);
if (type_ == PDE_TYPE_BYTES) {
net::UploadElement* element = new net::UploadElement();
element->SetToBytes(static_cast<char*>(data_.bytes.bytes),
data_.bytes.size);
return std::make_unique<BytesElementReader>(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<FileElementReader>(base::WrapUnique(element));
} else {
NOTREACHED();
return nullptr;
}
}
void CefPostDataElementImpl::SetReadOnly(bool read_only) {
base::AutoLock lock_scope(lock_);
if (read_only_ == read_only)

View File

@ -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<network::ResourceRequestBody> GetBody() const;
void Set(const net::UploadData& data);
void Set(const net::UploadDataStream& data_stream);
void Get(net::UploadData& data) const;
std::unique_ptr<net::UploadDataStream> 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<net::UploadElementReader> Get() const;
void SetReadOnly(bool read_only);

View File

@ -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> 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<AckHandler> 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;
}

View File

@ -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 <map>
#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> 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<AckHandler> 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<int, CefRefPtr<Handler>> HandlerMap;
HandlerMap handlers_;
// Map of unique request ids to AckHandler references.
typedef std::map<int, CefRefPtr<AckHandler>> AckHandlerMap;
AckHandlerMap ack_handlers_;
SEQUENCE_CHECKER(sequence_checker_);
};
#endif // CEF_LIBCEF_COMMON_RESPONSE_MANAGER_H_

View File

@ -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<base::RefCountedMemory> 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<CefString::char_type>(),
source->size() / sizeof(CefString::char_type),
/*copy=*/false);
#else
// Must convert from UTF16.
cef_string.FromString16(
source->front_as<std::u16string::value_type>(),
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

View File

@ -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<base::RefCountedMemory> 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<void(const CefString&)>;
// 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_

View File

@ -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.

View File

@ -140,11 +140,12 @@ class CefBinaryValueImpl : public CefValueBase<CefBinaryValue, base::Value> {
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<CefListValue, base::ListValue> {
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);

View File

@ -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<bool> 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<bool> 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<blink::URLLoaderThrottleProvider>

View File

@ -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<CefBrowserManager> browser_manager_;
std::unique_ptr<CefRenderManager> render_manager_;
scoped_refptr<base::SingleThreadTaskRunner> render_task_runner_;
std::unique_ptr<CefRenderThreadObserver> observer_;
std::unique_ptr<AlloyRenderThreadObserver> observer_;
std::unique_ptr<web_cache::WebCacheImpl> web_cache_impl_;
std::unique_ptr<SpellCheck> spellcheck_;
std::unique_ptr<visitedlink::VisitedLinkReader> visited_link_slave_;

View File

@ -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);
}

View File

@ -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 &registry_; }
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_

View File

@ -8,8 +8,6 @@
#include <memory>
#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();

View File

@ -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<blink::Element>();
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<blink::WebLocalFrameImpl>(frame)->GetFrame()->GetDocument());
return string.Utf8();
}
cef_dom_node_type_t GetNodeType(const blink::WebNode& node) {

View File

@ -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);

View File

@ -9,10 +9,9 @@
#include <vector>
#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> CefBrowserImpl::GetBrowserForView(
content::RenderView* view) {
return CefBrowserManager::Get()->GetBrowserForView(view);
return CefRenderManager::Get()->GetBrowserForView(view);
}
// static
CefRefPtr<CefBrowserImpl> 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) {

View File

@ -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<CefRenderThreadObserver>();
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<bool> 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<bool> 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);
}

View File

@ -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<CefBrowserManager> browser_manager_;
std::unique_ptr<CefRenderManager> render_manager_;
scoped_refptr<base::SingleThreadTaskRunner> render_task_runner_;
std::unique_ptr<CefRenderThreadObserver> observer_;
DISALLOW_COPY_AND_ASSIGN(ChromeContentRendererClientCef);
};

View File

@ -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<CefStringVisitor> 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<CefStringVisitor> visitor) {
void CefFrameImpl::GetText(CefRefPtr<CefStringVisitor> 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<CefRequest> 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<CefPostData> postData = request->GetPostData();
if (postData.get()) {
CefPostDataImpl* impl = static_cast<CefPostDataImpl*>(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<CefRequestImpl*>(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<CefURLRequest> CefFrameImpl::CreateURLRequest(
void CefFrameImpl::SendProcessMessage(CefProcessId target_process,
CefRefPtr<CefProcessMessage> message) {
Cef_Request_Params params;
CefProcessMessageImpl* impl =
static_cast<CefProcessMessageImpl*>(message.get());
if (impl->CopyTo(params)) {
SendProcessMessage(target_process, params.name, &params.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<CefProcessMessageImpl*>(message.get());
browser_frame->SendMessage(impl->GetName(), impl->TakeArgumentList());
}
std::unique_ptr<blink::WebURLLoader> 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<CefApp> app = CefAppManager::Get()->GetApplication();
if (app) {
@ -367,174 +339,124 @@ void CefFrameImpl::OnDidFinishLoad() {
void CefFrameImpl::OnDraggableRegionsChanged() {
blink::WebVector<blink::WebDraggableRegion> webregions =
frame_->GetDocument().DraggableRegions();
std::vector<Cef_DraggableRegion_Params> regions;
for (size_t i = 0; i < webregions.size(); ++i) {
Cef_DraggableRegion_Params region;
std::vector<cef::mojom::DraggableRegionEntryPtr> 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(&region->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<CefFrameImpl> 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));
}
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::Send(IPC::Message* message) {
if (!frame_) {
delete message;
return;
const mojo::Remote<cef::mojom::BrowserFrame>& 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());
}
}
auto render_frame = content::RenderFrame::FromWebFrame(frame_);
message->set_routing_id(render_frame->GetRoutingID());
render_frame->Send(message);
return browser_frame_;
}
void CefFrameImpl::OnRequest(const Cef_Request_Params& params) {
DCHECK(browser_);
DCHECK(frame_);
void CefFrameImpl::BindRenderFrameReceiver(
mojo::PendingReceiver<cef::mojom::RenderFrame> receiver) {
receivers_.Add(this, std::move(receiver));
}
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<CefApp> app = CefAppManager::Get()->GetApplication();
if (app.get()) {
CefRefPtr<CefRenderProcessHandler> handler =
app->GetRenderProcessHandler();
if (handler.get()) {
CefRefPtr<CefProcessMessageImpl> message(new CefProcessMessageImpl(
const_cast<Cef_Request_Params*>(&params), 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<CefProcessMessageImpl> message(new CefProcessMessageImpl(
name, const_cast<base::ListValue*>(&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;
void CefFrameImpl::SendCommand(const std::string& command) {
CEF_REQUIRE_RT_RETURN_VOID();
if (frame_) {
frame_->ExecuteCommand(blink::WebString::FromUTF8(command));
}
}
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;
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);
std::move(callback).Run(string_util::CreateSharedMemoryRegion(response));
}
// 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));
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::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::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::OnResponseAck(int request_id) {
response_manager_->RunAckHandler(request_id);
}
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__)

View File

@ -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);
// Returns the remote BrowserFrame object.
const mojo::Remote<cef::mojom::BrowserFrame>& GetBrowserFrame();
// Avoids unnecessary string type conversions.
void SendProcessMessage(CefProcessId target_process,
const std::string& name,
base::ListValue* arguments,
bool user_initiated);
void BindRenderFrameReceiver(
mojo::PendingReceiver<cef::mojom::RenderFrame> receiver);
// 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);
// 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<blink::WebURLLoaderFactory> url_loader_factory_;
// Manages response registrations.
std::unique_ptr<CefResponseManager> response_manager_;
mojo::ReceiverSet<cef::mojom::RenderFrame> receivers_;
mojo::Remote<cef::mojom::BrowserFrame> browser_frame_;
base::WeakPtrFactory<CefFrameImpl> weak_ptr_factory_{this};
IMPLEMENT_REFCOUNTING(CefFrameImpl);
DISALLOW_COPY_AND_ASSIGN(CefFrameImpl);

View File

@ -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(&registry_);
}
void CefRenderFrameObserver::OnLoadStart() {

View File

@ -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<v8::Context> 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 &registry_; }
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);
};

View File

@ -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(&params));
auto params = cef::mojom::NewRenderThreadInfo::New();
GetBrowserManager()->GetNewRenderThreadInfo(&params);
// 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<bool>& is_windowless) {
void CefRenderManager::RenderViewCreated(content::RenderView* render_view,
bool& browser_created,
base::Optional<bool>& 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<CefBrowserImpl> CefBrowserManager::GetBrowserForView(
void CefRenderManager::ExposeInterfacesToBrowser(mojo::BinderMap* binders) {
auto task_runner = base::SequencedTaskRunnerHandle::Get();
binders->Add(
base::BindRepeating(
[](CefRenderManager* render_manager,
mojo::PendingReceiver<cef::mojom::RenderManager> receiver) {
render_manager->BindReceiver(std::move(receiver));
},
base::Unretained(this)),
task_runner);
}
CefRefPtr<CefBrowserImpl> CefRenderManager::GetBrowserForView(
content::RenderView* view) {
BrowserMap::const_iterator it = browsers_.find(view);
if (it != browsers_.end())
@ -134,7 +151,7 @@ CefRefPtr<CefBrowserImpl> CefBrowserManager::GetBrowserForView(
return nullptr;
}
CefRefPtr<CefBrowserImpl> CefBrowserManager::GetBrowserForMainFrame(
CefRefPtr<CefBrowserImpl> CefRenderManager::GetBrowserForMainFrame(
blink::WebFrame* frame) {
BrowserMap::const_iterator it = browsers_.begin();
for (; it != browsers_.end(); ++it) {
@ -147,7 +164,44 @@ CefRefPtr<CefBrowserImpl> CefBrowserManager::GetBrowserForMainFrame(
return nullptr;
}
void CefBrowserManager::WebKitInitialized() {
mojo::Remote<cef::mojom::BrowserManager>&
CefRenderManager::GetBrowserManager() {
if (!browser_manager_) {
content::RenderThread::Get()->BindHostReceiver(
browser_manager_.BindNewPipeAndPassReceiver());
}
return browser_manager_;
}
void CefRenderManager::BindReceiver(
mojo::PendingReceiver<cef::mojom::RenderManager> 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<CefBrowserImpl> CefBrowserManager::MaybeCreateBrowser(
CefRefPtr<CefBrowserImpl> CefRenderManager::MaybeCreateBrowser(
content::RenderView* render_view,
content::RenderFrame* render_frame,
bool* browser_created,
@ -246,30 +289,29 @@ CefRefPtr<CefBrowserImpl> 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, &params));
auto params = cef::mojom::NewBrowserInfo::New();
GetBrowserManager()->GetNewBrowserInfo(render_frame_routing_id, &params);
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<CefGuestView>(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<CefBrowserImpl> CefBrowserManager::MaybeCreateBrowser(
CefRefPtr<CefRenderProcessHandler> handler =
application->GetRenderProcessHandler();
if (handler.get()) {
CefRefPtr<CefDictionaryValueImpl> dictValuePtr(
new CefDictionaryValueImpl(&params.extra_info, false, true));
CefRefPtr<CefDictionaryValueImpl> dictValuePtr;
if (params->extra_info) {
auto& dict_value = base::Value::AsDictionaryValue(*params->extra_info);
dictValuePtr = new CefDictionaryValueImpl(
const_cast<base::DictionaryValue*>(&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<CefBrowserImpl> 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) {

View File

@ -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 <map>
@ -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<bool>& is_windowless);
void DevToolsAgentAttached();
void DevToolsAgentDetached();
void ExposeInterfacesToBrowser(mojo::BinderMap* binders);
// Returns the browser associated with the specified RenderView.
CefRefPtr<CefBrowserImpl> GetBrowserForView(content::RenderView* view);
@ -55,10 +63,22 @@ class CefBrowserManager {
// Returns the browser associated with the specified main WebFrame.
CefRefPtr<CefBrowserImpl> GetBrowserForMainFrame(blink::WebFrame* frame);
// Connects to CefBrowserManager in the browser process.
mojo::Remote<cef::mojom::BrowserManager>& GetBrowserManager();
private:
friend class CefBrowserImpl;
friend class CefGuestView;
// Binds receivers for the RenderManager interface.
void BindReceiver(mojo::PendingReceiver<cef::mojom::RenderManager> 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<Cef_CrossOriginWhiteListEntry_Params> CrossOriginList;
CrossOriginList cross_origin_whitelist_entries_;
std::vector<cef::mojom::CrossOriginWhiteListEntryPtr>
cross_origin_whitelist_entries_;
int devtools_agent_count_ = 0;
int uncaught_exception_stack_size_ = 0;
DISALLOW_COPY_AND_ASSIGN(CefBrowserManager);
mojo::ReceiverSet<cef::mojom::RenderManager> receivers_;
mojo::Remote<cef::mojom::BrowserManager> browser_manager_;
DISALLOW_COPY_AND_ASSIGN(CefRenderManager);
};
#endif // CEF_LIBCEF_RENDERER_BROWSER_MANAGER_H_
#endif // CEF_LIBCEF_RENDERER_RENDER_MANAGER_H_

View File

@ -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();
}

View File

@ -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 <memory>
#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_

View File

@ -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(

View File

@ -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),

View File

@ -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.

View File

@ -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_);

View File

@ -278,7 +278,7 @@ class FrameNavRendererTest : public ClientAppRenderer::Delegate,
void OnBrowserCreated(CefRefPtr<ClientAppRenderer> app,
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefDictionaryValue> extra_info) override {
if (!extra_info->HasKey(kFrameNavTestCmdKey))
if (!extra_info || !extra_info->HasKey(kFrameNavTestCmdKey))
return;
FrameNavFactoryId factory_id =

View File

@ -67,7 +67,7 @@ class HistoryNavRendererTest : public ClientAppRenderer::Delegate,
void OnBrowserCreated(CefRefPtr<ClientAppRenderer> app,
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefDictionaryValue> extra_info) override {
run_test_ = extra_info->HasKey(kHistoryNavTestCmdKey);
run_test_ = extra_info && extra_info->HasKey(kHistoryNavTestCmdKey);
}
CefRefPtr<CefLoadHandler> GetLoadHandler(
@ -1147,7 +1147,7 @@ class OrderNavRendererTest : public ClientAppRenderer::Delegate,
void OnBrowserCreated(CefRefPtr<ClientAppRenderer> app,
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefDictionaryValue> 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<ClientAppRenderer> app,
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefDictionaryValue> 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<ClientAppRenderer> app,
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefDictionaryValue> extra_info) override {
run_test_ = extra_info->HasKey(kExtraInfoTestCmdKey);
run_test_ = extra_info && extra_info->HasKey(kExtraInfoTestCmdKey);
if (!run_test_)
return;

View File

@ -78,8 +78,6 @@ class SendRecvTestHandler : public TestHandler {
: send_thread_(send_thread) {}
void RunTest() override {
message_ = CreateTestMessage();
AddResource(kSendRecvUrl, "<html><body>TEST</body></html>", "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<CefBrowser> browser, CefRefPtr<CefFrame> frame) {
EXPECT_TRUE(CefCurrentlyOn(send_thread_));
frame->SendProcessMessage(PID_RENDERER, message_);
frame->SendProcessMessage(PID_RENDERER, CreateTestMessage());
}
cef_thread_id_t send_thread_;
CefRefPtr<CefProcessMessage> message_;
TrackCallback got_message_;
IMPLEMENT_REFCOUNTING(SendRecvTestHandler);
@ -171,7 +167,7 @@ TEST(ProcessMessageTest, Create) {
CefRefPtr<CefListValue> args = message->GetArgumentList();
EXPECT_TRUE(args.get());
EXPECT_TRUE(args->IsValid());
EXPECT_TRUE(args->IsOwned());
EXPECT_FALSE(args->IsOwned());
EXPECT_FALSE(args->IsReadOnly());
}

View File

@ -401,7 +401,7 @@ class NetNotifyRendererTest : public ClientAppRenderer::Delegate,
void OnBrowserCreated(CefRefPtr<ClientAppRenderer> app,
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefDictionaryValue> extra_info) override {
run_test_ = extra_info->HasKey(kNetNotifyTestCmdKey);
run_test_ = extra_info && extra_info->HasKey(kNetNotifyTestCmdKey);
}
CefRefPtr<CefLoadHandler> GetLoadHandler(

View File

@ -2467,7 +2467,7 @@ class V8RendererTest : public ClientAppRenderer::Delegate,
void OnBrowserCreated(CefRefPtr<ClientAppRenderer> app,
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefDictionaryValue> extra_info) override {
if (extra_info->HasKey(kV8TestCmdKey)) {
if (extra_info && extra_info->HasKey(kV8TestCmdKey)) {
test_mode_ = static_cast<V8TestMode>(extra_info->GetInt(kV8TestCmdKey));
}
if (test_mode_ > V8TEST_NONE)