diff --git a/BUILD.gn b/BUILD.gn index fe7a31a9e..b190d1509 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -448,6 +448,8 @@ static_library("libcef_static") { "libcef/browser/browser_util.cc", "libcef/browser/browser_util.h", "libcef/browser/chrome/browser_delegate.h", + "libcef/browser/chrome/browser_platform_delegate_chrome.cc", + "libcef/browser/chrome/browser_platform_delegate_chrome.h", "libcef/browser/chrome/chrome_browser_context.cc", "libcef/browser/chrome/chrome_browser_context.h", "libcef/browser/chrome/chrome_browser_delegate.cc", @@ -567,6 +569,8 @@ static_library("libcef_static") { "libcef/browser/net/internal_scheme_handler.h", "libcef/browser/net/scheme_handler.cc", "libcef/browser/net/scheme_handler.h", + "libcef/browser/net/throttle_handler.cc", + "libcef/browser/net/throttle_handler.h", "libcef/browser/net_service/browser_urlrequest_impl.cc", "libcef/browser/net_service/browser_urlrequest_impl.h", "libcef/browser/net_service/cookie_helper.cc", @@ -759,8 +763,18 @@ 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", "libcef/renderer/dom_document_impl.h", "libcef/renderer/dom_node_impl.cc", @@ -782,8 +796,6 @@ static_library("libcef_static") { "libcef/renderer/render_urlrequest_impl.cc", "libcef/renderer/render_urlrequest_impl.h", "libcef/renderer/thread_util.h", - "libcef/renderer/url_loader_throttle_provider_impl.cc", - "libcef/renderer/url_loader_throttle_provider_impl.h", "libcef/renderer/v8_impl.cc", "libcef/renderer/v8_impl.h", diff --git a/include/capi/cef_browser_process_handler_capi.h b/include/capi/cef_browser_process_handler_capi.h index e546a564a..f616cba1d 100644 --- a/include/capi/cef_browser_process_handler_capi.h +++ b/include/capi/cef_browser_process_handler_capi.h @@ -33,7 +33,7 @@ // by hand. See the translator.README.txt file in the tools directory for // more information. // -// $hash=17e60bfb954ddf6c40b90b9a117d90a0fe3f08d6$ +// $hash=d56cbf83d6faefa9f716c7308bf7007dad98697d$ // #ifndef CEF_INCLUDE_CAPI_CEF_BROWSER_PROCESS_HANDLER_CAPI_H_ @@ -61,6 +61,25 @@ typedef struct _cef_browser_process_handler_t { /// cef_base_ref_counted_t base; + /// + // Called on the browser process UI thread to retrieve the list of schemes + // that should support cookies. If |include_defaults| is true (1) the default + // schemes ("http", "https", "ws" and "wss") will also be supported. Providing + // an NULL |schemes| value and setting |include_defaults| to false (0) will + // disable all loading and saving of cookies. + // + // This state will apply to the cef_cookie_manager_t associated with the + // global cef_request_context_t. It will also be used as the initial state for + // any new cef_request_context_ts created by the client. After creating a new + // cef_request_context_t the cef_cookie_manager_t::SetSupportedSchemes + // function may be called on the associated cef_cookie_manager_t to futher + // override these values. + /// + void(CEF_CALLBACK* get_cookieable_schemes)( + struct _cef_browser_process_handler_t* self, + cef_string_list_t schemes, + int* include_defaults); + /// // Called on the browser process UI thread immediately after the CEF context // has been initialized. diff --git a/include/cef_api_hash.h b/include/cef_api_hash.h index 841de18a2..3e3d07aa0 100644 --- a/include/cef_api_hash.h +++ b/include/cef_api_hash.h @@ -42,13 +42,13 @@ // way that may cause binary incompatibility with other builds. The universal // hash value will change if any platform is affected whereas the platform hash // values will change only if that particular platform is affected. -#define CEF_API_HASH_UNIVERSAL "c148b1a4fd1d29c2e14b1ab8ce1c04f29013de73" +#define CEF_API_HASH_UNIVERSAL "988c60ace9a075ec0d6d5439f8a845296549f666" #if defined(OS_WIN) -#define CEF_API_HASH_PLATFORM "1f380ef6bde94cd7331d090b7aee0a08f2515541" +#define CEF_API_HASH_PLATFORM "9928400d4500073e22954f2793c9ab78749b7b67" #elif defined(OS_MAC) -#define CEF_API_HASH_PLATFORM "c42f0866e58d3f96183e1f8931a4d01a7900b0b4" +#define CEF_API_HASH_PLATFORM "1c49b8f3d13ac6dd5b04d827f283ede33c7aba7b" #elif defined(OS_LINUX) -#define CEF_API_HASH_PLATFORM "92824ced77603246263f1f2ecf95ff4fad73885d" +#define CEF_API_HASH_PLATFORM "7634bb7366cf7be31efdbf7c86815ad47b412317" #endif #ifdef __cplusplus diff --git a/include/cef_browser_process_handler.h b/include/cef_browser_process_handler.h index b6906c09a..c82b93deb 100644 --- a/include/cef_browser_process_handler.h +++ b/include/cef_browser_process_handler.h @@ -51,6 +51,23 @@ /*--cef(source=client,no_debugct_check)--*/ class CefBrowserProcessHandler : public virtual CefBaseRefCounted { public: + /// + // Called on the browser process UI thread to retrieve the list of schemes + // that should support cookies. If |include_defaults| is true the default + // schemes ("http", "https", "ws" and "wss") will also be supported. Providing + // an empty |schemes| value and setting |include_defaults| to false will + // disable all loading and saving of cookies. + // + // This state will apply to the CefCookieManager associated with the global + // CefRequestContext. It will also be used as the initial state for any new + // CefRequestContexts created by the client. After creating a new + // CefRequestContext the CefCookieManager::SetSupportedSchemes method may be + // called on the associated CefCookieManager to futher override these values. + /// + /*--cef()--*/ + virtual void GetCookieableSchemes(std::vector& schemes, + bool& include_defaults) {} + /// // Called on the browser process UI thread immediately after the CEF context // has been initialized. diff --git a/libcef/browser/alloy/alloy_browser_context.h b/libcef/browser/alloy/alloy_browser_context.h index f6438b5e8..ce153d3f8 100644 --- a/libcef/browser/alloy/alloy_browser_context.h +++ b/libcef/browser/alloy/alloy_browser_context.h @@ -103,9 +103,6 @@ class AlloyBrowserContext : public ChromeProfileAlloy, bool ShouldPersistSessionCookies() const override { return !!settings_.persist_session_cookies; } - base::Optional> GetCookieableSchemes() override { - return cookieable_schemes(); - } // visitedlink::VisitedLinkDelegate methods. void RebuildTable(const scoped_refptr& enumerator) override; diff --git a/libcef/browser/alloy/alloy_browser_host_impl.cc b/libcef/browser/alloy/alloy_browser_host_impl.cc index 7fe66702b..bd979a416 100644 --- a/libcef/browser/alloy/alloy_browser_host_impl.cc +++ b/libcef/browser/alloy/alloy_browser_host_impl.cc @@ -14,7 +14,6 @@ #include "libcef/browser/browser_info.h" #include "libcef/browser/browser_info_manager.h" #include "libcef/browser/browser_platform_delegate.h" -#include "libcef/browser/browser_util.h" #include "libcef/browser/context.h" #include "libcef/browser/devtools/devtools_manager.h" #include "libcef/browser/media_capture_devices_dispatcher.h" @@ -42,15 +41,13 @@ #include "content/public/browser/native_web_keyboard_event.h" #include "content/public/browser/navigation_controller.h" #include "content/public/browser/navigation_handle.h" -#include "content/public/browser/notification_details.h" -#include "content/public/browser/notification_source.h" -#include "content/public/browser/notification_types.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_process_host.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/render_widget_host.h" #include "content/public/browser/render_widget_host_observer.h" #include "content/public/browser/web_contents.h" +#include "extensions/common/constants.h" #include "extensions/common/extension.h" #include "net/base/net_errors.h" #include "third_party/blink/public/mojom/page/widget.mojom-test-utils.h" @@ -137,7 +134,7 @@ static constexpr base::TimeDelta kRecentlyAudibleTimeout = // static CefRefPtr AlloyBrowserHostImpl::Create( - CreateParams& create_params) { + CefBrowserCreateParams& create_params) { std::unique_ptr platform_delegate = CefBrowserPlatformDelegate::Create(create_params); CHECK(platform_delegate); @@ -182,9 +179,11 @@ CefRefPtr AlloyBrowserHostImpl::Create( create_params.extension, create_params.url, create_params.extension_host_type); } else if (!create_params.url.is_empty()) { - browser->LoadMainFrameURL(create_params.url.spec(), content::Referrer(), - CefFrameHostImpl::kPageTransitionExplicit, - std::string()); + content::OpenURLParams params(create_params.url, content::Referrer(), + WindowOpenDisposition::CURRENT_TAB, + CefFrameHostImpl::kPageTransitionExplicit, + /*is_renderer_initiated=*/false); + browser->LoadMainFrameURL(params); } return browser.get(); @@ -733,67 +732,6 @@ void AlloyBrowserHostImpl::SendExternalBeginFrame() { platform_delegate_->SendExternalBeginFrame(); } -void AlloyBrowserHostImpl::SendKeyEvent(const CefKeyEvent& event) { - if (!CEF_CURRENTLY_ON_UIT()) { - CEF_POST_TASK(CEF_UIT, base::BindOnce(&AlloyBrowserHostImpl::SendKeyEvent, - this, event)); - return; - } - - if (platform_delegate_) - platform_delegate_->SendKeyEvent(event); -} - -void AlloyBrowserHostImpl::SendMouseClickEvent(const CefMouseEvent& event, - MouseButtonType type, - bool mouseUp, - int clickCount) { - if (!CEF_CURRENTLY_ON_UIT()) { - CEF_POST_TASK(CEF_UIT, - base::BindOnce(&AlloyBrowserHostImpl::SendMouseClickEvent, - this, event, type, mouseUp, clickCount)); - return; - } - - if (platform_delegate_) { - platform_delegate_->SendMouseClickEvent(event, type, mouseUp, clickCount); - } -} - -void AlloyBrowserHostImpl::SendMouseMoveEvent(const CefMouseEvent& event, - bool mouseLeave) { - if (!CEF_CURRENTLY_ON_UIT()) { - CEF_POST_TASK( - CEF_UIT, base::BindOnce(&AlloyBrowserHostImpl::SendMouseMoveEvent, this, - event, mouseLeave)); - return; - } - - if (platform_delegate_) { - platform_delegate_->SendMouseMoveEvent(event, mouseLeave); - } -} - -void AlloyBrowserHostImpl::SendMouseWheelEvent(const CefMouseEvent& event, - int deltaX, - int deltaY) { - if (deltaX == 0 && deltaY == 0) { - // Nothing to do. - return; - } - - if (!CEF_CURRENTLY_ON_UIT()) { - CEF_POST_TASK(CEF_UIT, - base::BindOnce(&AlloyBrowserHostImpl::SendMouseWheelEvent, - this, event, deltaX, deltaY)); - return; - } - - if (platform_delegate_) { - platform_delegate_->SendMouseWheelEvent(event, deltaX, deltaY); - } -} - void AlloyBrowserHostImpl::SendTouchEvent(const CefTouchEvent& event) { if (!IsWindowless()) { NOTREACHED() << "Window rendering is not disabled"; @@ -864,90 +802,6 @@ void AlloyBrowserHostImpl::SetWindowlessFrameRate(int frame_rate) { platform_delegate_->SetWindowlessFrameRate(frame_rate); } -// CefBrowser methods. -// ----------------------------------------------------------------------------- - -void AlloyBrowserHostImpl::GoBack() { - auto callback = base::BindOnce(&AlloyBrowserHostImpl::GoBack, this); - if (!CEF_CURRENTLY_ON_UIT()) { - CEF_POST_TASK(CEF_UIT, std::move(callback)); - } - - if (browser_info_->IsNavigationLocked(std::move(callback))) { - return; - } - - auto wc = web_contents(); - if (wc && wc->GetController().CanGoBack()) { - wc->GetController().GoBack(); - } -} - -void AlloyBrowserHostImpl::GoForward() { - auto callback = base::BindOnce(&AlloyBrowserHostImpl::GoForward, this); - if (!CEF_CURRENTLY_ON_UIT()) { - CEF_POST_TASK(CEF_UIT, std::move(callback)); - } - - if (browser_info_->IsNavigationLocked(std::move(callback))) { - return; - } - - auto wc = web_contents(); - if (wc && wc->GetController().CanGoForward()) { - wc->GetController().GoForward(); - } -} - -void AlloyBrowserHostImpl::Reload() { - auto callback = base::BindOnce(&AlloyBrowserHostImpl::Reload, this); - if (!CEF_CURRENTLY_ON_UIT()) { - CEF_POST_TASK(CEF_UIT, std::move(callback)); - } - - if (browser_info_->IsNavigationLocked(std::move(callback))) { - return; - } - - auto wc = web_contents(); - if (wc) { - wc->GetController().Reload(content::ReloadType::NORMAL, true); - } -} - -void AlloyBrowserHostImpl::ReloadIgnoreCache() { - auto callback = - base::BindOnce(&AlloyBrowserHostImpl::ReloadIgnoreCache, this); - if (!CEF_CURRENTLY_ON_UIT()) { - CEF_POST_TASK(CEF_UIT, std::move(callback)); - } - - if (browser_info_->IsNavigationLocked(std::move(callback))) { - return; - } - - auto wc = web_contents(); - if (wc) { - wc->GetController().Reload(content::ReloadType::BYPASSING_CACHE, true); - } -} - -void AlloyBrowserHostImpl::StopLoad() { - auto callback = base::BindOnce(&AlloyBrowserHostImpl::StopLoad, this); - if (!CEF_CURRENTLY_ON_UIT()) { - CEF_POST_TASK(CEF_UIT, std::move(callback)); - } - - if (browser_info_->IsNavigationLocked(std::move(callback))) { - return; - } - - auto wc = web_contents(); - if (wc) { - wc->Stop(); - } -} - // AlloyBrowserHostImpl public methods. // ----------------------------------------------------------------------------- @@ -1007,8 +861,6 @@ void AlloyBrowserHostImpl::DestroyBrowser() { // Disassociate the platform delegate from this browser. platform_delegate_->BrowserDestroyed(this); - registrar_.reset(nullptr); - // Delete objects created by the platform delegate that may be referenced by // the WebContents. file_dialog_manager_.reset(nullptr); @@ -1021,9 +873,6 @@ void AlloyBrowserHostImpl::DestroyBrowser() { devtools_manager_.reset(nullptr); - // Delete the platform delegate. - platform_delegate_.reset(nullptr); - CefBrowserHostBase::DestroyBrowser(); } @@ -1049,15 +898,24 @@ void AlloyBrowserHostImpl::CancelContextMenu() { menu_manager_->CancelContextMenu(); } -void AlloyBrowserHostImpl::ViewText(const std::string& text) { - if (!CEF_CURRENTLY_ON_UIT()) { - CEF_POST_TASK(CEF_UIT, - base::BindOnce(&AlloyBrowserHostImpl::ViewText, this, text)); - return; +bool AlloyBrowserHostImpl::MaybeAllowNavigation( + content::RenderFrameHost* opener, + bool is_guest_view, + const content::OpenURLParams& params) { + if (is_guest_view && !params.url.SchemeIs(extensions::kExtensionScheme) && + !params.url.SchemeIs(content::kChromeUIScheme)) { + // The PDF viewer will load the PDF extension in the guest view, and print + // preview will load chrome://print in the guest view. All other navigations + // are passed to the owner browser. + CEF_POST_TASK( + CEF_UIT, + base::Bind(base::IgnoreResult(&AlloyBrowserHostImpl::OpenURLFromTab), + this, nullptr, params)); + + return false; } - if (platform_delegate_) - platform_delegate_->ViewText(text); + return true; } SkColor AlloyBrowserHostImpl::GetBackgroundColor() const { @@ -1073,29 +931,17 @@ extensions::ExtensionHost* AlloyBrowserHostImpl::GetExtensionHost() const { } void AlloyBrowserHostImpl::OnSetFocus(cef_focus_source_t source) { - if (CEF_CURRENTLY_ON_UIT()) { - // SetFocus() might be called while inside the OnSetFocus() callback. If - // so, don't re-enter the callback. - if (!is_in_onsetfocus_) { - if (client_.get()) { - CefRefPtr handler = client_->GetFocusHandler(); - if (handler.get()) { - is_in_onsetfocus_ = true; - bool handled = handler->OnSetFocus(this, source); - is_in_onsetfocus_ = false; - - if (handled) - return; - } - } - } - - if (platform_delegate_) - platform_delegate_->SendFocusEvent(true); - } else { + if (!CEF_CURRENTLY_ON_UIT()) { CEF_POST_TASK(CEF_UIT, base::BindOnce(&AlloyBrowserHostImpl::OnSetFocus, this, source)); + return; } + + if (contents_delegate_->OnSetFocus(source)) + return; + + if (platform_delegate_) + platform_delegate_->SendFocusEvent(true); } void AlloyBrowserHostImpl::RunFileChooser( @@ -1372,32 +1218,18 @@ bool AlloyBrowserHostImpl::IsAudioMuted() { // content::WebContentsDelegate methods. // ----------------------------------------------------------------------------- -// |source| may be NULL if the navigation originates from a guest view via -// AlloyContentBrowserClient::CanCreateWindow. content::WebContents* AlloyBrowserHostImpl::OpenURLFromTab( content::WebContents* source, const content::OpenURLParams& params) { - bool cancel = false; - - if (client_.get()) { - CefRefPtr handler = client_->GetRequestHandler(); - if (handler.get()) { - cancel = handler->OnOpenURLFromTab( - this, GetFrame(params.frame_tree_node_id), params.url.spec(), - static_cast(params.disposition), - params.user_gesture); - } - } - - if (!cancel) { + auto target_contents = contents_delegate_->OpenURLFromTab(source, params); + if (target_contents) { // Start a navigation in the current browser that will result in the // creation of a new render process. - LoadMainFrameURL(params.url.spec(), params.referrer, params.transition, - params.extra_headers); - return source; + LoadMainFrameURL(params); + return target_contents; } - // We don't know where the navigation, if any, will occur. + // Cancel the navigation. return nullptr; } @@ -1510,26 +1342,7 @@ bool AlloyBrowserHostImpl::HandleContextMenu( KeyboardEventProcessingResult AlloyBrowserHostImpl::PreHandleKeyboardEvent( content::WebContents* source, const content::NativeWebKeyboardEvent& event) { - if (platform_delegate_ && client_.get()) { - CefRefPtr handler = client_->GetKeyboardHandler(); - if (handler.get()) { - CefKeyEvent cef_event; - if (browser_util::GetCefKeyEvent(event, cef_event)) { - cef_event.focus_on_editable_field = focus_on_editable_field_; - - CefEventHandle event_handle = platform_delegate_->GetEventHandle(event); - bool is_keyboard_shortcut = false; - bool result = handler->OnPreKeyEvent(this, cef_event, event_handle, - &is_keyboard_shortcut); - if (result) - return KeyboardEventProcessingResult::HANDLED; - else if (is_keyboard_shortcut) - return KeyboardEventProcessingResult::NOT_HANDLED_IS_SHORTCUT; - } - } - } - - return KeyboardEventProcessingResult::NOT_HANDLED; + return contents_delegate_->PreHandleKeyboardEvent(source, event); } bool AlloyBrowserHostImpl::HandleKeyboardEvent( @@ -1539,24 +1352,12 @@ bool AlloyBrowserHostImpl::HandleKeyboardEvent( if (event.skip_in_browser) return false; - if (!platform_delegate_) - return false; + if (contents_delegate_->HandleKeyboardEvent(source, event)) + return true; - if (client_.get()) { - CefRefPtr handler = client_->GetKeyboardHandler(); - if (handler.get()) { - CefKeyEvent cef_event; - if (browser_util::GetCefKeyEvent(event, cef_event)) { - cef_event.focus_on_editable_field = focus_on_editable_field_; - - CefEventHandle event_handle = platform_delegate_->GetEventHandle(event); - if (handler->OnKeyEvent(this, cef_event, event_handle)) - return true; - } - } - } - - return platform_delegate_->HandleKeyboardEvent(event); + if (platform_delegate_) + return platform_delegate_->HandleKeyboardEvent(event); + return false; } bool AlloyBrowserHostImpl::PreHandleGestureEvent( @@ -1787,30 +1588,11 @@ void AlloyBrowserHostImpl::ExitPictureInPicture() { void AlloyBrowserHostImpl::RenderViewCreated( content::RenderViewHost* render_view_host) { - // May be already registered if the renderer crashed previously. - if (!registrar_->IsRegistered( - this, content::NOTIFICATION_FOCUS_CHANGED_IN_PAGE, - content::Source(render_view_host))) { - registrar_->Add(this, content::NOTIFICATION_FOCUS_CHANGED_IN_PAGE, - content::Source(render_view_host)); - } - new CefWidgetHostInterceptor(this, render_view_host); platform_delegate_->RenderViewCreated(render_view_host); } -void AlloyBrowserHostImpl::RenderViewDeleted( - content::RenderViewHost* render_view_host) { - if (registrar_->IsRegistered( - this, content::NOTIFICATION_FOCUS_CHANGED_IN_PAGE, - content::Source(render_view_host))) { - registrar_->Remove( - this, content::NOTIFICATION_FOCUS_CHANGED_IN_PAGE, - content::Source(render_view_host)); - } -} - void AlloyBrowserHostImpl::RenderViewReady() { platform_delegate_->RenderViewReady(); } @@ -1895,25 +1677,6 @@ void AlloyBrowserHostImpl::StartAudioCapturer() { audio_capturer_.reset(new CefAudioCapturer(params, this, audio_handler)); } -// content::NotificationObserver methods. -// ----------------------------------------------------------------------------- - -void AlloyBrowserHostImpl::Observe( - int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) { - DCHECK(type == content::NOTIFICATION_LOAD_STOP || - type == content::NOTIFICATION_FOCUS_CHANGED_IN_PAGE); - - if (type == content::NOTIFICATION_LOAD_STOP) { - content::NavigationController* controller = - content::Source(source).ptr(); - contents_delegate_->OnTitleChange(controller->GetWebContents()->GetTitle()); - } else if (type == content::NOTIFICATION_FOCUS_CHANGED_IN_PAGE) { - focus_on_editable_field_ = *content::Details(details).ptr(); - } -} - // AlloyBrowserHostImpl private methods. // ----------------------------------------------------------------------------- @@ -1926,10 +1689,13 @@ AlloyBrowserHostImpl::AlloyBrowserHostImpl( CefRefPtr request_context, std::unique_ptr platform_delegate, CefRefPtr extension) - : CefBrowserHostBase(settings, client, browser_info, request_context), + : CefBrowserHostBase(settings, + client, + std::move(platform_delegate), + browser_info, + request_context), content::WebContentsObserver(web_contents), opener_(kNullWindowHandle), - platform_delegate_(std::move(platform_delegate)), is_windowless_(platform_delegate_->IsWindowless()), is_views_hosted_(platform_delegate_->IsViewsHosted()), extension_(extension) { @@ -1941,17 +1707,6 @@ AlloyBrowserHostImpl::AlloyBrowserHostImpl( opener_ = opener->GetWindowHandle(); } - registrar_.reset(new content::NotificationRegistrar); - - // When navigating through the history, the restored NavigationEntry's title - // will be used. If the entry ends up having the same title after we return - // to it, as will usually be the case, the - // NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED will then be suppressed, since - // the NavigationEntry's title hasn't changed. - registrar_->Add(this, content::NOTIFICATION_LOAD_STOP, - content::Source( - &web_contents->GetController())); - // Associate the platform delegate with this browser. platform_delegate_->BrowserCreated(this); diff --git a/libcef/browser/alloy/alloy_browser_host_impl.h b/libcef/browser/alloy/alloy_browser_host_impl.h index d6f65d1f1..c97936c79 100644 --- a/libcef/browser/alloy/alloy_browser_host_impl.h +++ b/libcef/browser/alloy/alloy_browser_host_impl.h @@ -24,36 +24,13 @@ #include "base/strings/string16.h" #include "base/synchronization/lock.h" -#include "content/public/browser/notification_observer.h" -#include "content/public/browser/notification_registrar.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_delegate.h" #include "content/public/browser/web_contents_observer.h" #include "extensions/common/view_type.h" -namespace content { -struct DragEventSourceInfo; -class RenderWidgetHostImpl; -} // namespace content - -namespace extensions { -class Extension; -class ExtensionHost; -} // namespace extensions - -namespace gfx { -class ImageSkia; -} - -#if defined(USE_AURA) -namespace views { -class Widget; -} -#endif // defined(USE_AURA) - class CefAudioCapturer; class CefBrowserInfo; -class CefBrowserPlatformDelegate; class CefDevToolsManager; class SiteInstance; @@ -72,12 +49,9 @@ class SiteInstance; // messages sent using AlloyBrowserHostImpl::Send() will be forwarded to the // RenderViewHost (after posting to the UI thread if necessary). Use // WebContentsObserver::routing_id() when sending IPC messages. -// -// NotificationObserver: Interface for observing post-processed notifications. class AlloyBrowserHostImpl : public CefBrowserHostBase, public content::WebContentsDelegate, - public content::WebContentsObserver, - public content::NotificationObserver { + public content::WebContentsObserver { public: // Used for handling the response to command messages. class CommandResponseHandler : public virtual CefBaseRefCounted { @@ -88,7 +62,8 @@ class AlloyBrowserHostImpl : public CefBrowserHostBase, ~AlloyBrowserHostImpl() override; // Create a new AlloyBrowserHostImpl instance with owned WebContents. - static CefRefPtr Create(CreateParams& create_params); + static CefRefPtr Create( + CefBrowserCreateParams& create_params); // Returns the browser associated with the specified RenderViewHost. static CefRefPtr GetBrowserForHost( @@ -152,15 +127,6 @@ class AlloyBrowserHostImpl : public CefBrowserHostBase, void NotifyScreenInfoChanged() override; void Invalidate(PaintElementType type) override; void SendExternalBeginFrame() override; - void SendKeyEvent(const CefKeyEvent& event) override; - void SendMouseClickEvent(const CefMouseEvent& event, - MouseButtonType type, - bool mouseUp, - int clickCount) override; - void SendMouseMoveEvent(const CefMouseEvent& event, bool mouseLeave) override; - void SendMouseWheelEvent(const CefMouseEvent& event, - int deltaX, - int deltaY) override; void SendTouchEvent(const CefTouchEvent& event) override; void SendFocusEvent(bool setFocus) override; void SendCaptureLostEvent() override; @@ -194,13 +160,6 @@ class AlloyBrowserHostImpl : public CefBrowserHostBase, CefRefPtr GetExtension() override; bool IsBackgroundHost() override; - // CefBrowser methods. - void GoBack() override; - void GoForward() override; - void Reload() override; - void ReloadIgnoreCache() override; - void StopLoad() override; - // Returns true if windowless rendering is enabled. bool IsWindowless() const; @@ -230,8 +189,9 @@ class AlloyBrowserHostImpl : public CefBrowserHostBase, CefRefPtr GetBrowserView() const; #endif - // Open the specified text in the default text editor. - void ViewText(const std::string& text) override; + bool MaybeAllowNavigation(content::RenderFrameHost* opener, + bool is_guest_view, + const content::OpenURLParams& params) override; // Convert from view coordinates to screen coordinates. Potential display // scaling will be applied to the result. @@ -364,7 +324,6 @@ class AlloyBrowserHostImpl : public CefBrowserHostBase, // content::WebContentsObserver methods. using content::WebContentsObserver::BeforeUnloadFired; void RenderViewCreated(content::RenderViewHost* render_view_host) override; - void RenderViewDeleted(content::RenderViewHost* render_view_host) override; void RenderViewReady() override; void DidFinishNavigation( content::NavigationHandle* navigation_handle) override; @@ -391,11 +350,6 @@ class AlloyBrowserHostImpl : public CefBrowserHostBase, std::unique_ptr platform_delegate, CefRefPtr extension); - // content::NotificationObserver methods. - void Observe(int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) override; - AlloyBrowserHostImpl( const CefBrowserSettings& settings, CefRefPtr client, @@ -420,7 +374,6 @@ class AlloyBrowserHostImpl : public CefBrowserHostBase, CefRefPtr registration); CefWindowHandle opener_; - std::unique_ptr platform_delegate_; const bool is_windowless_; const bool is_views_hosted_; CefWindowHandle host_window_handle_ = kNullWindowHandle; @@ -435,20 +388,9 @@ class AlloyBrowserHostImpl : public CefBrowserHostBase, // on the UI thread. bool window_destroyed_ = false; - // True if currently in the OnSetFocus callback. Only accessed on the UI - // thread. - bool is_in_onsetfocus_ = false; - - // True if the focus is currently on an editable field on the page. Only - // accessed on the UI thread. - bool focus_on_editable_field_ = false; - // True if mouse cursor change is disabled. bool mouse_cursor_change_disabled_ = false; - // Used for managing notification subscriptions. - std::unique_ptr registrar_; - // Used for creating and managing file dialogs. std::unique_ptr file_dialog_manager_; diff --git a/libcef/browser/alloy/alloy_content_browser_client.cc b/libcef/browser/alloy/alloy_content_browser_client.cc index 6943ee2f7..9f393fdd3 100644 --- a/libcef/browser/alloy/alloy_content_browser_client.cc +++ b/libcef/browser/alloy/alloy_content_browser_client.cc @@ -22,6 +22,8 @@ #include "libcef/browser/extensions/extension_web_contents_observer.h" #include "libcef/browser/media_capture_devices_dispatcher.h" #include "libcef/browser/net/chrome_scheme_handler.h" +#include "libcef/browser/net/throttle_handler.h" +#include "libcef/browser/net_service/cookie_manager_impl.h" #include "libcef/browser/net_service/login_delegate.h" #include "libcef/browser/net_service/proxy_url_loader_factory.h" #include "libcef/browser/net_service/resource_request_handler_wrapper.h" @@ -71,8 +73,6 @@ #include "chrome/grit/generated_resources.h" #include "chrome/services/printing/printing_service.h" #include "components/content_settings/core/browser/cookie_settings.h" -#include "components/navigation_interception/intercept_navigation_throttle.h" -#include "components/navigation_interception/navigation_params.h" #include "components/spellcheck/common/spellcheck.mojom.h" #include "components/version_info/version_info.h" #include "content/browser/frame_host/render_frame_host_impl.h" @@ -440,72 +440,6 @@ int GetCrashSignalFD(const base::CommandLine& command_line) { } #endif // defined(OS_POSIX) && !defined(OS_MAC) -// TODO(cef): We can't currently trust NavigationParams::is_main_frame() because -// it's always set to true in -// InterceptNavigationThrottle::CheckIfShouldIgnoreNavigation. Remove the -// |is_main_frame| argument once this problem is fixed. -bool NavigationOnUIThread( - bool is_main_frame, - int64_t frame_id, - int64_t parent_frame_id, - int frame_tree_node_id, - content::WebContents* source, - const navigation_interception::NavigationParams& params) { - CEF_REQUIRE_UIT(); - - content::OpenURLParams open_params( - params.url(), params.referrer(), WindowOpenDisposition::CURRENT_TAB, - params.transition_type(), params.is_renderer_initiated()); - open_params.user_gesture = params.has_user_gesture(); - open_params.initiator_origin = params.initiator_origin(); - - CefRefPtr browser; - if (!CefBrowserInfoManager::GetInstance()->MaybeAllowNavigation( - source->GetMainFrame(), open_params, browser)) { - // Cancel the navigation. - return true; - } - - bool ignore_navigation = false; - - if (browser.get()) { - CefRefPtr client = browser->GetClient(); - if (client.get()) { - CefRefPtr handler = client->GetRequestHandler(); - if (handler.get()) { - CefRefPtr frame; - if (is_main_frame) { - frame = browser->GetMainFrame(); - } else if (frame_id >= 0) { - frame = browser->GetFrame(frame_id); - } - if (!frame && frame_tree_node_id >= 0) { - frame = browser->GetFrameForFrameTreeNode(frame_tree_node_id); - } - if (!frame) { - // Create a temporary frame object for navigation of sub-frames that - // don't yet exist. - frame = browser->browser_info()->CreateTempSubFrame(parent_frame_id); - } - - CefRefPtr request = new CefRequestImpl(); - request->Set(params, is_main_frame); - request->SetReadOnly(true); - - // Initiating a new navigation in OnBeforeBrowse will delete the - // InterceptNavigationThrottle that currently owns this callback, - // resulting in a crash. Use the lock to prevent that. - auto navigation_lock = browser->browser_info()->CreateNavigationLock(); - ignore_navigation = handler->OnBeforeBrowse( - browser.get(), frame, request.get(), params.has_user_gesture(), - params.is_redirect()); - } - } - } - - return ignore_navigation; -} - // From chrome/browser/plugins/chrome_content_browser_client_plugins_part.cc. void BindPluginInfoHost( int render_process_id, @@ -1074,33 +1008,8 @@ AlloyContentBrowserClient::GetDevToolsManagerDelegate() { std::vector> AlloyContentBrowserClient::CreateThrottlesForNavigation( content::NavigationHandle* navigation_handle) { - CEF_REQUIRE_UIT(); - - std::vector> throttles; - - const bool is_main_frame = navigation_handle->IsInMainFrame(); - - // Identify the RenderFrameHost that originated the navigation. - const int64_t parent_frame_id = - !is_main_frame - ? CefFrameHostImpl::MakeFrameId(navigation_handle->GetParentFrame()) - : CefFrameHostImpl::kInvalidFrameId; - - const int64_t frame_id = !is_main_frame && navigation_handle->HasCommitted() - ? CefFrameHostImpl::MakeFrameId( - navigation_handle->GetRenderFrameHost()) - : CefFrameHostImpl::kInvalidFrameId; - - // Must use SynchronyMode::kSync to ensure that OnBeforeBrowse is always - // called before OnBeforeResourceLoad. - std::unique_ptr throttle = - std::make_unique( - navigation_handle, - base::Bind(&NavigationOnUIThread, is_main_frame, frame_id, - parent_frame_id, navigation_handle->GetFrameTreeNodeId()), - navigation_interception::SynchronyMode::kSync); - throttles.push_back(std::move(throttle)); - + throttle::NavigationThrottleList throttles; + throttle::CreateThrottlesForNavigation(navigation_handle, throttles); return throttles; } @@ -1306,10 +1215,16 @@ void AlloyContentBrowserClient::ConfigureNetworkContextParams( return; } - Profile* profile = Profile::FromBrowserContext(context); + auto cef_context = CefBrowserContext::FromBrowserContext(context); + + Profile* profile = cef_context->AsProfile(); profile->ConfigureNetworkContextParams(in_memory, relative_partition_path, network_context_params, cert_verifier_creation_params); + + network_context_params->cookieable_schemes = + cef_context->GetCookieableSchemes(); + // TODO(cef): Remove this and add required NetworkIsolationKeys, // this is currently not the case and this was not required pre M84. network_context_params->require_network_isolation_key = false; @@ -1336,7 +1251,7 @@ AlloyContentBrowserClient::GetNetworkContextsParentDirectory() { bool AlloyContentBrowserClient::HandleExternalProtocol( const GURL& url, - base::OnceCallback web_contents_getter, + content::WebContents::OnceGetter web_contents_getter, int child_id, content::NavigationUIData* navigation_data, bool is_main_frame, @@ -1356,32 +1271,16 @@ bool AlloyContentBrowserClient::HandleExternalProtocol( mojo::PendingRemote* out_factory) { mojo::PendingReceiver receiver = out_factory->InitWithNewPipeAndPassReceiver(); + // CefBrowserPlatformDelegate::HandleExternalProtocol may be called if // nothing handles the request. - if (CEF_CURRENTLY_ON_IOT()) { - auto request_handler = net_service::CreateInterceptedRequestHandler( - web_contents_getter, frame_tree_node_id, resource_request); - net_service::ProxyURLLoaderFactory::CreateProxy( - web_contents_getter, std::move(receiver), std::move(request_handler)); - } else { - auto request_handler = net_service::CreateInterceptedRequestHandler( - web_contents_getter, frame_tree_node_id, resource_request); - CEF_POST_TASK( - CEF_IOT, - base::BindOnce( - [](mojo::PendingReceiver receiver, - std::unique_ptr - request_handler, - content::WebContents::Getter web_contents_getter) { - // Manages its own lifetime. + auto request_handler = net_service::CreateInterceptedRequestHandler( + web_contents_getter, frame_tree_node_id, resource_request, + base::Bind(CefBrowserPlatformDelegate::HandleExternalProtocol, + resource_request.url)); - net_service::ProxyURLLoaderFactory::CreateProxy( - web_contents_getter, std::move(receiver), - std::move(request_handler)); - }, - std::move(receiver), std::move(request_handler), - std::move(web_contents_getter))); - } + net_service::ProxyURLLoaderFactory::CreateProxy( + web_contents_getter, std::move(receiver), std::move(request_handler)); return true; } diff --git a/libcef/browser/alloy/alloy_content_browser_client.h b/libcef/browser/alloy/alloy_content_browser_client.h index 5493da1a9..781c55d77 100644 --- a/libcef/browser/alloy/alloy_content_browser_client.h +++ b/libcef/browser/alloy/alloy_content_browser_client.h @@ -181,7 +181,7 @@ class AlloyContentBrowserClient : public content::ContentBrowserClient { std::vector GetNetworkContextsParentDirectory() override; bool HandleExternalProtocol( const GURL& url, - base::OnceCallback web_contents_getter, + content::WebContents::OnceGetter web_contents_getter, int child_id, content::NavigationUIData* navigation_data, bool is_main_frame, diff --git a/libcef/browser/alloy/browser_platform_delegate_alloy.cc b/libcef/browser/alloy/browser_platform_delegate_alloy.cc index 8e466cebf..35b1463ed 100644 --- a/libcef/browser/alloy/browser_platform_delegate_alloy.cc +++ b/libcef/browser/alloy/browser_platform_delegate_alloy.cc @@ -12,6 +12,7 @@ #include "libcef/browser/extensions/extension_web_contents_observer.h" #include "libcef/browser/printing/print_view_manager.h" #include "libcef/common/extensions/extensions_util.h" +#include "libcef/features/runtime_checks.h" #include "base/logging.h" #include "chrome/browser/printing/print_view_manager.h" @@ -28,8 +29,11 @@ CefBrowserPlatformDelegateAlloy::CefBrowserPlatformDelegateAlloy() : weak_ptr_factory_(this) {} content::WebContents* CefBrowserPlatformDelegateAlloy::CreateWebContents( - CefBrowserHostBase::CreateParams& create_params, + CefBrowserCreateParams& create_params, bool& own_web_contents) { + REQUIRE_ALLOY_RUNTIME(); + DCHECK(primary_); + // Get or create the request context and browser context. CefRefPtr request_context_impl = CefRequestContextImpl::GetOrCreateForRequestContext( @@ -105,6 +109,9 @@ void CefBrowserPlatformDelegateAlloy::AddNewContents( const gfx::Rect& initial_rect, bool user_gesture, bool* was_blocked) { + REQUIRE_ALLOY_RUNTIME(); + DCHECK(primary_); + CefRefPtr owner = AlloyBrowserHostImpl::GetBrowserForContents(new_contents.get()); if (owner) { @@ -143,10 +150,15 @@ void CefBrowserPlatformDelegateAlloy::RenderViewReady() { } void CefBrowserPlatformDelegateAlloy::BrowserCreated( - AlloyBrowserHostImpl* browser) { + CefBrowserHostBase* browser) { CefBrowserPlatformDelegate::BrowserCreated(browser); - web_contents_->SetDelegate(browser); + // Only register WebContents delegate/observers if we're the primary delegate. + if (!primary_) + return; + + DCHECK(!web_contents_->GetDelegate()); + web_contents_->SetDelegate(static_cast(browser)); PrefsTabHelper::CreateForWebContents(web_contents_); printing::CefPrintViewManager::CreateForWebContents(web_contents_); @@ -169,24 +181,29 @@ void CefBrowserPlatformDelegateAlloy::CreateExtensionHost( const extensions::Extension* extension, const GURL& url, extensions::ViewType host_type) { + REQUIRE_ALLOY_RUNTIME(); + DCHECK(primary_); + // Should get WebContentsCreated and BrowserCreated calls first. DCHECK(web_contents_); DCHECK(browser_); DCHECK(!extension_host_); + auto alloy_browser = static_cast(browser_); + if (host_type == extensions::VIEW_TYPE_EXTENSION_DIALOG || host_type == extensions::VIEW_TYPE_EXTENSION_POPUP) { // Create an extension host that we own. extension_host_ = new extensions::CefExtensionViewHost( - browser_, extension, web_contents_, url, host_type); + alloy_browser, extension, web_contents_, url, host_type); // Trigger load of the extension URL. extension_host_->CreateRenderViewSoon(); } else if (host_type == extensions::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) { is_background_host_ = true; - browser_->is_background_host_ = true; + alloy_browser->is_background_host_ = true; // Create an extension host that will be owned by ProcessManager. extension_host_ = new extensions::CefExtensionBackgroundHost( - browser_, + alloy_browser, base::BindOnce(&CefBrowserPlatformDelegateAlloy::OnExtensionHostDeleted, weak_ptr_factory_.GetWeakPtr()), extension, web_contents_, url, host_type); @@ -202,9 +219,11 @@ extensions::ExtensionHost* CefBrowserPlatformDelegateAlloy::GetExtensionHost() } void CefBrowserPlatformDelegateAlloy::BrowserDestroyed( - AlloyBrowserHostImpl* browser) { - DestroyExtensionHost(); - owned_web_contents_.reset(); + CefBrowserHostBase* browser) { + if (primary_) { + DestroyExtensionHost(); + owned_web_contents_.reset(); + } CefBrowserPlatformDelegate::BrowserDestroyed(browser); } @@ -303,6 +322,8 @@ void CefBrowserPlatformDelegateAlloy::SetAccessibilityState( } bool CefBrowserPlatformDelegateAlloy::IsPrintPreviewSupported() const { + REQUIRE_ALLOY_RUNTIME(); + auto actionable_contents = GetActionableWebContents(); if (!actionable_contents) return false; @@ -318,6 +339,8 @@ bool CefBrowserPlatformDelegateAlloy::IsPrintPreviewSupported() const { } void CefBrowserPlatformDelegateAlloy::Print() { + REQUIRE_ALLOY_RUNTIME(); + auto actionable_contents = GetActionableWebContents(); if (!actionable_contents) return; @@ -337,6 +360,8 @@ void CefBrowserPlatformDelegateAlloy::PrintToPDF( const CefString& path, const CefPdfPrintSettings& settings, CefRefPtr callback) { + REQUIRE_ALLOY_RUNTIME(); + content::WebContents* actionable_contents = GetActionableWebContents(); if (!actionable_contents) return; @@ -405,6 +430,8 @@ CefBrowserPlatformDelegateAlloy::GetActionableWebContents() const { void CefBrowserPlatformDelegateAlloy::SetOwnedWebContents( content::WebContents* owned_contents) { + DCHECK(primary_); + // Should not currently own a WebContents. CHECK(!owned_web_contents_); owned_web_contents_.reset(owned_contents); diff --git a/libcef/browser/alloy/browser_platform_delegate_alloy.h b/libcef/browser/alloy/browser_platform_delegate_alloy.h index 8114f99fd..fde6106c9 100644 --- a/libcef/browser/alloy/browser_platform_delegate_alloy.h +++ b/libcef/browser/alloy/browser_platform_delegate_alloy.h @@ -10,13 +10,14 @@ #include "libcef/browser/web_contents_dialog_helper.h" #include "base/memory/weak_ptr.h" +#include "content/public/browser/web_contents.h" +#include "ui/gfx/geometry/size.h" // Implementation of Alloy-based browser functionality. class CefBrowserPlatformDelegateAlloy : public CefBrowserPlatformDelegate { public: - content::WebContents* CreateWebContents( - CefBrowserHostBase::CreateParams& create_params, - bool& own_web_contents) override; + content::WebContents* CreateWebContents(CefBrowserCreateParams& create_params, + bool& own_web_contents) override; void WebContentsCreated(content::WebContents* web_contents, bool owned) override; void AddNewContents(content::WebContents* source, @@ -29,12 +30,12 @@ class CefBrowserPlatformDelegateAlloy : public CefBrowserPlatformDelegate { bool ShouldTransferNavigation(bool is_main_frame_navigation) override; void RenderViewCreated(content::RenderViewHost* render_view_host) override; void RenderViewReady() override; - void BrowserCreated(AlloyBrowserHostImpl* browser) override; + void BrowserCreated(CefBrowserHostBase* browser) override; void CreateExtensionHost(const extensions::Extension* extension, const GURL& url, extensions::ViewType host_type) override; extensions::ExtensionHost* GetExtensionHost() const override; - void BrowserDestroyed(AlloyBrowserHostImpl* browser) override; + void BrowserDestroyed(CefBrowserHostBase* browser) override; void SendCaptureLostEvent() override; #if defined(OS_WIN) || (defined(OS_POSIX) && !defined(OS_MAC)) void NotifyMoveOrResizeStarted() override; @@ -69,6 +70,9 @@ class CefBrowserPlatformDelegateAlloy : public CefBrowserPlatformDelegate { // Otherwise, the browser's WebContents will be returned. content::WebContents* GetActionableWebContents() const; + // Called from BrowserPlatformDelegateNative::set_windowless_handler(). + void set_as_secondary() { primary_ = false; } + private: void SetOwnedWebContents(content::WebContents* owned_contents); @@ -98,6 +102,10 @@ class CefBrowserPlatformDelegateAlloy : public CefBrowserPlatformDelegate { gfx::Size auto_resize_min_; gfx::Size auto_resize_max_; + // True if this is the primary platform delegate, in which case it will + // register WebContents delegate/observers. + bool primary_ = true; + base::WeakPtrFactory weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(CefBrowserPlatformDelegateAlloy); diff --git a/libcef/browser/browser_contents_delegate.cc b/libcef/browser/browser_contents_delegate.cc index 406ed4543..048953a2e 100644 --- a/libcef/browser/browser_contents_delegate.cc +++ b/libcef/browser/browser_contents_delegate.cc @@ -5,11 +5,20 @@ #include "libcef/browser/browser_contents_delegate.h" #include "libcef/browser/browser_host_base.h" +#include "libcef/browser/browser_platform_delegate.h" +#include "libcef/browser/browser_util.h" +#include "content/public/browser/keyboard_event_processing_result.h" +#include "content/public/browser/native_web_keyboard_event.h" #include "content/public/browser/navigation_entry.h" #include "content/public/browser/navigation_handle.h" +#include "content/public/browser/notification_details.h" +#include "content/public/browser/notification_source.h" +#include "content/public/browser/notification_types.h" #include "content/public/browser/render_view_host.h" +using content::KeyboardEventProcessingResult; + CefBrowserContentsDelegate::CefBrowserContentsDelegate( scoped_refptr browser_info) : browser_info_(browser_info) { @@ -18,13 +27,29 @@ CefBrowserContentsDelegate::CefBrowserContentsDelegate( void CefBrowserContentsDelegate::ObserveWebContents( content::WebContents* new_contents) { - Observe(new_contents); + WebContentsObserver::Observe(new_contents); if (new_contents) { + registrar_.reset(new content::NotificationRegistrar); + + // When navigating through the history, the restored NavigationEntry's title + // will be used. If the entry ends up having the same title after we return + // to it, as will usually be the case, the + // NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED will then be suppressed, since + // the NavigationEntry's title hasn't changed. + registrar_->Add(this, content::NOTIFICATION_LOAD_STOP, + content::Source( + &new_contents->GetController())); + + // Make sure RenderViewCreated is called at least one time. + RenderViewCreated(new_contents->GetRenderViewHost()); + // Create the frame representation before OnAfterCreated is called for a new // browser. Additionally, RenderFrameCreated is otherwise not called at all // for new popup browsers. RenderFrameCreated(new_contents->GetMainFrame()); + } else { + registrar_.reset(); } } @@ -36,6 +61,27 @@ void CefBrowserContentsDelegate::RemoveObserver(Observer* observer) { observers_.RemoveObserver(observer); } +// |source| may be NULL for navigations in the current tab, or if the +// navigation originates from a guest view via MaybeAllowNavigation. +content::WebContents* CefBrowserContentsDelegate::OpenURLFromTab( + content::WebContents* source, + const content::OpenURLParams& params) { + bool cancel = false; + + if (auto c = client()) { + if (auto handler = c->GetRequestHandler()) { + cancel = handler->OnOpenURLFromTab( + browser(), browser()->GetFrame(params.frame_tree_node_id), + params.url.spec(), + static_cast(params.disposition), + params.user_gesture); + } + } + + // Returning nullptr will cancel the navigation. + return cancel ? nullptr : web_contents(); +} + void CefBrowserContentsDelegate::LoadingStateChanged( content::WebContents* source, bool to_different_document) { @@ -126,6 +172,60 @@ void CefBrowserContentsDelegate::ExitFullscreenModeForTab( OnFullscreenModeChange(/*fullscreen=*/false); } +KeyboardEventProcessingResult +CefBrowserContentsDelegate::PreHandleKeyboardEvent( + content::WebContents* source, + const content::NativeWebKeyboardEvent& event) { + if (auto delegate = platform_delegate()) { + if (auto c = client()) { + if (auto handler = c->GetKeyboardHandler()) { + CefKeyEvent cef_event; + if (browser_util::GetCefKeyEvent(event, cef_event)) { + cef_event.focus_on_editable_field = focus_on_editable_field_; + + auto event_handle = delegate->GetEventHandle(event); + bool is_keyboard_shortcut = false; + bool result = handler->OnPreKeyEvent( + browser(), cef_event, event_handle, &is_keyboard_shortcut); + if (result) { + return KeyboardEventProcessingResult::HANDLED; + } else if (is_keyboard_shortcut) { + return KeyboardEventProcessingResult::NOT_HANDLED_IS_SHORTCUT; + } + } + } + } + } + + return KeyboardEventProcessingResult::NOT_HANDLED; +} + +bool CefBrowserContentsDelegate::HandleKeyboardEvent( + content::WebContents* source, + const content::NativeWebKeyboardEvent& event) { + // Check to see if event should be ignored. + if (event.skip_in_browser) + return false; + + if (auto delegate = platform_delegate()) { + if (auto c = client()) { + if (auto handler = c->GetKeyboardHandler()) { + CefKeyEvent cef_event; + if (browser_util::GetCefKeyEvent(event, cef_event)) { + cef_event.focus_on_editable_field = focus_on_editable_field_; + + auto event_handle = delegate->GetEventHandle(event); + if (handler->OnKeyEvent(browser(), cef_event, event_handle)) { + return true; + } + } + } + } + } + + return false; +} + void CefBrowserContentsDelegate::RenderFrameCreated( content::RenderFrameHost* render_frame_host) { browser_info_->MaybeCreateFrame(render_frame_host, false /* is_guest_view */); @@ -149,6 +249,28 @@ void CefBrowserContentsDelegate::RenderFrameDeleted( } } +void CefBrowserContentsDelegate::RenderViewCreated( + content::RenderViewHost* render_view_host) { + // May be already registered if the renderer crashed previously. + if (!registrar_->IsRegistered( + this, content::NOTIFICATION_FOCUS_CHANGED_IN_PAGE, + content::Source(render_view_host))) { + registrar_->Add(this, content::NOTIFICATION_FOCUS_CHANGED_IN_PAGE, + content::Source(render_view_host)); + } +} + +void CefBrowserContentsDelegate::RenderViewDeleted( + content::RenderViewHost* render_view_host) { + if (registrar_->IsRegistered( + this, content::NOTIFICATION_FOCUS_CHANGED_IN_PAGE, + content::Source(render_view_host))) { + registrar_->Remove( + this, content::NOTIFICATION_FOCUS_CHANGED_IN_PAGE, + content::Source(render_view_host)); + } +} + void CefBrowserContentsDelegate::RenderViewReady() { if (auto c = client()) { if (auto handler = c->GetRequestHandler()) { @@ -358,12 +480,77 @@ void CefBrowserContentsDelegate::OnWebContentsFocused( } void CefBrowserContentsDelegate::WebContentsDestroyed() { + auto wc = web_contents(); ObserveWebContents(nullptr); for (auto& observer : observers_) { - observer.OnWebContentsDestroyed(); + observer.OnWebContentsDestroyed(wc); } } +void CefBrowserContentsDelegate::Observe( + int type, + const content::NotificationSource& source, + const content::NotificationDetails& details) { + DCHECK(type == content::NOTIFICATION_LOAD_STOP || + type == content::NOTIFICATION_FOCUS_CHANGED_IN_PAGE); + + if (type == content::NOTIFICATION_LOAD_STOP) { + content::NavigationController* controller = + content::Source(source).ptr(); + OnTitleChange(controller->GetWebContents()->GetTitle()); + } else if (type == content::NOTIFICATION_FOCUS_CHANGED_IN_PAGE) { + focus_on_editable_field_ = *content::Details(details).ptr(); + } +} + +void CefBrowserContentsDelegate::OnLoadEnd(CefRefPtr frame, + const GURL& url, + int http_status_code) { + if (auto c = client()) { + if (auto handler = c->GetLoadHandler()) { + handler->OnLoadEnd(browser(), frame, http_status_code); + } + } +} + +bool CefBrowserContentsDelegate::OnSetFocus(cef_focus_source_t source) { + // SetFocus() might be called while inside the OnSetFocus() callback. If + // so, don't re-enter the callback. + if (is_in_onsetfocus_) + return true; + + if (auto c = client()) { + if (auto handler = c->GetFocusHandler()) { + is_in_onsetfocus_ = true; + bool handled = handler->OnSetFocus(browser(), source); + is_in_onsetfocus_ = false; + + return handled; + } + } + + return false; +} + +CefRefPtr CefBrowserContentsDelegate::client() const { + if (auto b = browser()) { + return b->GetHost()->GetClient(); + } + return nullptr; +} + +CefRefPtr CefBrowserContentsDelegate::browser() const { + return browser_info_->browser(); +} + +CefBrowserPlatformDelegate* CefBrowserContentsDelegate::platform_delegate() + const { + auto browser = browser_info_->browser(); + if (browser) + return browser->platform_delegate(); + return nullptr; +} + void CefBrowserContentsDelegate::OnAddressChange(const GURL& url) { if (auto c = client()) { if (auto handler = c->GetDisplayHandler()) { @@ -400,16 +587,6 @@ void CefBrowserContentsDelegate::OnLoadError(CefRefPtr frame, } } -void CefBrowserContentsDelegate::OnLoadEnd(CefRefPtr frame, - const GURL& url, - int http_status_code) { - if (auto c = client()) { - if (auto handler = c->GetLoadHandler()) { - handler->OnLoadEnd(browser(), frame, http_status_code); - } - } -} - void CefBrowserContentsDelegate::OnTitleChange(const base::string16& title) { if (auto c = client()) { if (auto handler = c->GetDisplayHandler()) { @@ -418,17 +595,6 @@ void CefBrowserContentsDelegate::OnTitleChange(const base::string16& title) { } } -CefRefPtr CefBrowserContentsDelegate::client() const { - if (auto b = browser()) { - return b->GetHost()->GetClient(); - } - return nullptr; -} - -CefRefPtr CefBrowserContentsDelegate::browser() const { - return browser_info_->browser(); -} - void CefBrowserContentsDelegate::OnFullscreenModeChange(bool fullscreen) { if (fullscreen == is_fullscreen_) return; diff --git a/libcef/browser/browser_contents_delegate.h b/libcef/browser/browser_contents_delegate.h index 31ec6cad6..7567a3542 100644 --- a/libcef/browser/browser_contents_delegate.h +++ b/libcef/browser/browser_contents_delegate.h @@ -11,11 +11,14 @@ #include "libcef/browser/frame_host_impl.h" #include "base/observer_list.h" +#include "content/public/browser/notification_observer.h" +#include "content/public/browser/notification_registrar.h" #include "content/public/browser/web_contents_delegate.h" #include "content/public/browser/web_contents_observer.h" class CefBrowser; class CefBrowserInfo; +class CefBrowserPlatformDelegate; class CefClient; // Flags that represent which states have changed. @@ -45,7 +48,8 @@ constexpr inline CefBrowserContentsState operator|( // Includes functionality that is shared by the alloy and chrome runtimes. // Only accessed on the UI thread. class CefBrowserContentsDelegate : public content::WebContentsDelegate, - public content::WebContentsObserver { + public content::WebContentsObserver, + public content::NotificationObserver { public: using State = CefBrowserContentsState; @@ -58,7 +62,7 @@ class CefBrowserContentsDelegate : public content::WebContentsDelegate, virtual void OnStateChanged(State state_changed) = 0; // Called when the associated WebContents is destroyed. - virtual void OnWebContentsDestroyed() = 0; + virtual void OnWebContentsDestroyed(content::WebContents* web_contents) = 0; protected: ~Observer() override {} @@ -75,6 +79,9 @@ class CefBrowserContentsDelegate : public content::WebContentsDelegate, void RemoveObserver(Observer* observer); // WebContentsDelegate methods: + content::WebContents* OpenURLFromTab( + content::WebContents* source, + const content::OpenURLParams& params) override; void LoadingStateChanged(content::WebContents* source, bool to_different_document) override; void UpdateTargetURL(content::WebContents* source, const GURL& url) override; @@ -89,12 +96,20 @@ class CefBrowserContentsDelegate : public content::WebContentsDelegate, content::RenderFrameHost* requesting_frame, const blink::mojom::FullscreenOptions& options) override; void ExitFullscreenModeForTab(content::WebContents* web_contents) override; + content::KeyboardEventProcessingResult PreHandleKeyboardEvent( + content::WebContents* source, + const content::NativeWebKeyboardEvent& event) override; + bool HandleKeyboardEvent( + content::WebContents* source, + const content::NativeWebKeyboardEvent& event) override; // WebContentsObserver methods: void RenderFrameCreated(content::RenderFrameHost* render_frame_host) override; void RenderFrameHostChanged(content::RenderFrameHost* old_host, content::RenderFrameHost* new_host) override; void RenderFrameDeleted(content::RenderFrameHost* render_frame_host) override; + void RenderViewCreated(content::RenderViewHost* render_view_host) override; + void RenderViewDeleted(content::RenderViewHost* render_view_host) override; void RenderViewReady() override; void RenderProcessGone(base::TerminationStatus status) override; void OnFrameFocused(content::RenderFrameHost* render_frame_host) override; @@ -118,6 +133,11 @@ class CefBrowserContentsDelegate : public content::WebContentsDelegate, content::RenderWidgetHost* render_widget_host) override; void WebContentsDestroyed() override; + // NotificationObserver methods. + void Observe(int type, + const content::NotificationSource& source, + const content::NotificationDetails& details) override; + // Accessors for state information. Changes will be signaled to // Observer::OnStateChanged. bool is_loading() const { return is_loading_; } @@ -128,20 +148,25 @@ class CefBrowserContentsDelegate : public content::WebContentsDelegate, CefRefPtr focused_frame() const { return focused_frame_; } // Helpers for executing client callbacks. - void OnAddressChange(const GURL& url); - void OnLoadStart(CefRefPtr frame, - ui::PageTransition transition_type); - void OnLoadError(CefRefPtr frame, const GURL& url, int error_code); + // TODO(cef): Make this private if/when possible. void OnLoadEnd(CefRefPtr frame, const GURL& url, int http_status_code); - void OnTitleChange(const base::string16& title); + bool OnSetFocus(cef_focus_source_t source); private: CefRefPtr client() const; CefRefPtr browser() const; + CefBrowserPlatformDelegate* platform_delegate() const; + // Helpers for executing client callbacks. + void OnAddressChange(const GURL& url); + void OnLoadStart(CefRefPtr frame, + ui::PageTransition transition_type); + void OnLoadError(CefRefPtr frame, const GURL& url, int error_code); + void OnTitleChange(const base::string16& title); void OnFullscreenModeChange(bool fullscreen); + void OnStateChanged(State state_changed); scoped_refptr browser_info_; @@ -155,9 +180,18 @@ class CefBrowserContentsDelegate : public content::WebContentsDelegate, // The currently focused frame, or nullptr if the main frame is focused. CefRefPtr focused_frame_; + // True if currently in the OnSetFocus callback. + bool is_in_onsetfocus_ = false; + // Observers that want to be notified of changes to this object. base::ObserverList observers_; + // Used for managing notification subscriptions. + std::unique_ptr registrar_; + + // True if the focus is currently on an editable field on the page. + bool focus_on_editable_field_ = false; + DISALLOW_COPY_AND_ASSIGN(CefBrowserContentsDelegate); }; diff --git a/libcef/browser/browser_context.cc b/libcef/browser/browser_context.cc index 934767794..c585fa660 100644 --- a/libcef/browser/browser_context.cc +++ b/libcef/browser/browser_context.cc @@ -470,3 +470,12 @@ CefMediaRouterManager* CefBrowserContext::GetMediaRouterManager() { } return media_router_manager_.get(); } + +CefBrowserContext::CookieableSchemes CefBrowserContext::GetCookieableSchemes() + const { + CEF_REQUIRE_UIT(); + if (cookieable_schemes_) + return cookieable_schemes_; + + return CefCookieManagerImpl::GetGlobalCookieableSchemes(); +} diff --git a/libcef/browser/browser_context.h b/libcef/browser/browser_context.h index 4dd51ae96..2e8673f55 100644 --- a/libcef/browser/browser_context.h +++ b/libcef/browser/browser_context.h @@ -193,10 +193,15 @@ class CefBrowserContext { CefMediaRouterManager* GetMediaRouterManager(); using CookieableSchemes = base::Optional>; + + // Returns the schemes associated with this context specifically, or the + // global configuration if unset. + CookieableSchemes GetCookieableSchemes() const; + + // Set the schemes associated with this context specifically. void set_cookieable_schemes(const CookieableSchemes& schemes) { cookieable_schemes_ = schemes; } - CookieableSchemes cookieable_schemes() const { return cookieable_schemes_; } // These accessors are safe to call from any thread because the values don't // change during this object's lifespan. diff --git a/libcef/browser/browser_host_base.cc b/libcef/browser/browser_host_base.cc index a6ba02d26..38e0ac124 100644 --- a/libcef/browser/browser_host_base.cc +++ b/libcef/browser/browser_host_base.cc @@ -5,6 +5,7 @@ #include "libcef/browser/browser_host_base.h" #include "libcef/browser/browser_info_manager.h" +#include "libcef/browser/browser_platform_delegate.h" #include "libcef/browser/image_impl.h" #include "libcef/browser/navigation_entry_impl.h" #include "libcef/browser/net/scheme_handler.h" @@ -155,10 +156,12 @@ CefRefPtr CefBrowserHostBase::GetBrowserForFrameRoute( CefBrowserHostBase::CefBrowserHostBase( const CefBrowserSettings& settings, CefRefPtr client, + std::unique_ptr platform_delegate, scoped_refptr browser_info, CefRefPtr request_context) : settings_(settings), client_(client), + platform_delegate_(std::move(platform_delegate)), browser_info_(browser_info), request_context_(request_context) { CEF_REQUIRE_UIT(); @@ -181,6 +184,8 @@ void CefBrowserHostBase::InitializeBrowser() { void CefBrowserHostBase::DestroyBrowser() { CEF_REQUIRE_UIT(); + platform_delegate_.reset(nullptr); + contents_delegate_->RemoveObserver(this); contents_delegate_->ObserveWebContents(nullptr); @@ -375,6 +380,67 @@ void CefBrowserHostBase::AddWordToDictionary(const CefString& word) { #endif } +void CefBrowserHostBase::SendKeyEvent(const CefKeyEvent& event) { + if (!CEF_CURRENTLY_ON_UIT()) { + CEF_POST_TASK(CEF_UIT, base::BindOnce(&CefBrowserHostBase::SendKeyEvent, + this, event)); + return; + } + + if (platform_delegate_) + platform_delegate_->SendKeyEvent(event); +} + +void CefBrowserHostBase::SendMouseClickEvent(const CefMouseEvent& event, + MouseButtonType type, + bool mouseUp, + int clickCount) { + if (!CEF_CURRENTLY_ON_UIT()) { + CEF_POST_TASK(CEF_UIT, + base::BindOnce(&CefBrowserHostBase::SendMouseClickEvent, this, + event, type, mouseUp, clickCount)); + return; + } + + if (platform_delegate_) { + platform_delegate_->SendMouseClickEvent(event, type, mouseUp, clickCount); + } +} + +void CefBrowserHostBase::SendMouseMoveEvent(const CefMouseEvent& event, + bool mouseLeave) { + if (!CEF_CURRENTLY_ON_UIT()) { + CEF_POST_TASK(CEF_UIT, + base::BindOnce(&CefBrowserHostBase::SendMouseMoveEvent, this, + event, mouseLeave)); + return; + } + + if (platform_delegate_) { + platform_delegate_->SendMouseMoveEvent(event, mouseLeave); + } +} + +void CefBrowserHostBase::SendMouseWheelEvent(const CefMouseEvent& event, + int deltaX, + int deltaY) { + if (deltaX == 0 && deltaY == 0) { + // Nothing to do. + return; + } + + if (!CEF_CURRENTLY_ON_UIT()) { + CEF_POST_TASK(CEF_UIT, + base::BindOnce(&CefBrowserHostBase::SendMouseWheelEvent, this, + event, deltaX, deltaY)); + return; + } + + if (platform_delegate_) { + platform_delegate_->SendMouseWheelEvent(event, deltaX, deltaY); + } +} + CefRefPtr CefBrowserHostBase::GetHost() { return this; } @@ -384,16 +450,96 @@ bool CefBrowserHostBase::CanGoBack() { return can_go_back_; } +void CefBrowserHostBase::GoBack() { + auto callback = base::BindOnce(&CefBrowserHostBase::GoBack, this); + if (!CEF_CURRENTLY_ON_UIT()) { + CEF_POST_TASK(CEF_UIT, std::move(callback)); + } + + if (browser_info_->IsNavigationLocked(std::move(callback))) { + return; + } + + auto wc = GetWebContents(); + if (wc && wc->GetController().CanGoBack()) { + wc->GetController().GoBack(); + } +} + bool CefBrowserHostBase::CanGoForward() { base::AutoLock lock_scope(state_lock_); return can_go_forward_; } +void CefBrowserHostBase::GoForward() { + auto callback = base::BindOnce(&CefBrowserHostBase::GoForward, this); + if (!CEF_CURRENTLY_ON_UIT()) { + CEF_POST_TASK(CEF_UIT, std::move(callback)); + } + + if (browser_info_->IsNavigationLocked(std::move(callback))) { + return; + } + + auto wc = GetWebContents(); + if (wc && wc->GetController().CanGoForward()) { + wc->GetController().GoForward(); + } +} + bool CefBrowserHostBase::IsLoading() { base::AutoLock lock_scope(state_lock_); return is_loading_; } +void CefBrowserHostBase::Reload() { + auto callback = base::BindOnce(&CefBrowserHostBase::Reload, this); + if (!CEF_CURRENTLY_ON_UIT()) { + CEF_POST_TASK(CEF_UIT, std::move(callback)); + } + + if (browser_info_->IsNavigationLocked(std::move(callback))) { + return; + } + + auto wc = GetWebContents(); + if (wc) { + wc->GetController().Reload(content::ReloadType::NORMAL, true); + } +} + +void CefBrowserHostBase::ReloadIgnoreCache() { + auto callback = base::BindOnce(&CefBrowserHostBase::ReloadIgnoreCache, this); + if (!CEF_CURRENTLY_ON_UIT()) { + CEF_POST_TASK(CEF_UIT, std::move(callback)); + } + + if (browser_info_->IsNavigationLocked(std::move(callback))) { + return; + } + + auto wc = GetWebContents(); + if (wc) { + wc->GetController().Reload(content::ReloadType::BYPASSING_CACHE, true); + } +} + +void CefBrowserHostBase::StopLoad() { + auto callback = base::BindOnce(&CefBrowserHostBase::StopLoad, this); + if (!CEF_CURRENTLY_ON_UIT()) { + CEF_POST_TASK(CEF_UIT, std::move(callback)); + } + + if (browser_info_->IsNavigationLocked(std::move(callback))) { + return; + } + + auto wc = GetWebContents(); + if (wc) { + wc->Stop(); + } +} + int CefBrowserHostBase::GetIdentifier() { return browser_id(); } @@ -501,7 +647,8 @@ void CefBrowserHostBase::OnStateChanged(CefBrowserContentsState state_changed) { } } -void CefBrowserHostBase::OnWebContentsDestroyed() {} +void CefBrowserHostBase::OnWebContentsDestroyed( + content::WebContents* web_contents) {} CefRefPtr CefBrowserHostBase::GetFrameForHost( const content::RenderFrameHost* host) { @@ -532,12 +679,15 @@ bool CefBrowserHostBase::HasObserver(Observer* observer) const { return observers_.HasObserver(observer); } -void CefBrowserHostBase::LoadMainFrameURL(const std::string& url, - const content::Referrer& referrer, - ui::PageTransition transition, - const std::string& extra_headers) { - auto callback = base::BindOnce(&CefBrowserHostBase::LoadMainFrameURL, this, - url, referrer, transition, extra_headers); +void CefBrowserHostBase::LoadMainFrameURL( + const content::OpenURLParams& params) { + if (!params.url.is_valid()) { + LOG(ERROR) << "Invalid URL: " << params.url.spec(); + return; + } + + auto callback = + base::BindOnce(&CefBrowserHostBase::LoadMainFrameURL, this, params); if (!CEF_CURRENTLY_ON_UIT()) { CEF_POST_TASK(CEF_UIT, std::move(callback)); return; @@ -547,27 +697,22 @@ void CefBrowserHostBase::LoadMainFrameURL(const std::string& url, return; } - auto web_contents = GetWebContents(); - if (web_contents) { - GURL gurl = GURL(url); - - if (!gurl.is_valid() && !gurl.has_scheme()) { - // Try to add "http://" at the beginning - std::string new_url = std::string("http://") + url; - gurl = GURL(new_url); - } - - if (!gurl.is_valid()) { - LOG(ERROR) << "Invalid URL: " << url; - return; - } - - web_contents->GetController().LoadURL(gurl, referrer, transition, - extra_headers); + if (Navigate(params)) { OnSetFocus(FOCUS_SOURCE_NAVIGATION); } } +bool CefBrowserHostBase::Navigate(const content::OpenURLParams& params) { + CEF_REQUIRE_UIT(); + auto web_contents = GetWebContents(); + if (web_contents) { + web_contents->GetController().LoadURL( + params.url, params.referrer, params.transition, params.extra_headers); + return true; + } + return false; +} + void CefBrowserHostBase::OnDidFinishLoad(CefRefPtr frame, const GURL& validated_url, int http_status_code) { @@ -579,6 +724,24 @@ void CefBrowserHostBase::OnDidFinishLoad(CefRefPtr frame, contents_delegate_->OnLoadEnd(frame, validated_url, http_status_code); } +void CefBrowserHostBase::ViewText(const std::string& text) { + if (!CEF_CURRENTLY_ON_UIT()) { + CEF_POST_TASK(CEF_UIT, + base::BindOnce(&CefBrowserHostBase::ViewText, this, text)); + return; + } + + if (platform_delegate_) + platform_delegate_->ViewText(text); +} + +bool CefBrowserHostBase::MaybeAllowNavigation( + content::RenderFrameHost* opener, + bool is_guest_view, + const content::OpenURLParams& params) { + return true; +} + void CefBrowserHostBase::OnAfterCreated() { CEF_REQUIRE_UIT(); if (client_) { diff --git a/libcef/browser/browser_host_base.h b/libcef/browser/browser_host_base.h index a26844bae..957d53416 100644 --- a/libcef/browser/browser_host_base.h +++ b/libcef/browser/browser_host_base.h @@ -11,6 +11,7 @@ #include "include/views/cef_browser_view.h" #include "libcef/browser/browser_contents_delegate.h" #include "libcef/browser/browser_info.h" +#include "libcef/browser/browser_platform_delegate.h" #include "libcef/browser/frame_host_impl.h" #include "libcef/browser/request_context_impl.h" @@ -22,6 +23,64 @@ namespace extensions { class Extension; } +// Parameters that are passed to the runtime-specific Create methods. +struct CefBrowserCreateParams { + CefBrowserCreateParams() {} + + // Copy constructor used with the chrome runtime only. + CefBrowserCreateParams(const CefBrowserCreateParams& that) { + operator=(that); + } + CefBrowserCreateParams& operator=(const CefBrowserCreateParams& that) { + // Not all parameters can be copied. + client = that.client; + url = that.url; + settings = that.settings; + request_context = that.request_context; + extra_info = that.extra_info; + return *this; + } + + // Platform-specific window creation info. Will be nullptr when creating a + // views-hosted browser. Currently used with the alloy runtime only. + std::unique_ptr window_info; + +#if defined(USE_AURA) + // The BrowserView that will own a views-hosted browser. Will be nullptr for + // popup browsers (the BrowserView will be created later in that case). + // Currently used with the alloy runtime only. + CefRefPtr browser_view; +#endif + + // Client implementation. May be nullptr. + CefRefPtr client; + + // Initial URL to load. May be empty. If this is a valid extension URL then + // the browser will be created as an app view extension host. + GURL url; + + // Browser settings. + CefBrowserSettings settings; + + // Other browser that opened this DevTools browser. Will be nullptr for non- + // DevTools browsers. Currently used with the alloy runtime only. + CefRefPtr devtools_opener; + + // Request context to use when creating the browser. If nullptr the global + // request context will be used. + CefRefPtr request_context; + + // Extra information that will be passed to + // CefRenderProcessHandler::OnBrowserCreated. + CefRefPtr extra_info; + + // Used when explicitly creating the browser as an extension host via + // ProcessManager::CreateBackgroundHost. Currently used with the alloy + // runtime only. + const extensions::Extension* extension = nullptr; + extensions::ViewType extension_host_type = extensions::VIEW_TYPE_INVALID; +}; + // Base class for CefBrowserHost implementations. Includes functionality that is // shared by the alloy and chrome runtimes. All methods are thread-safe unless // otherwise indicated. @@ -29,62 +88,6 @@ class CefBrowserHostBase : public CefBrowserHost, public CefBrowser, public CefBrowserContentsDelegate::Observer { public: - // Parameters that are passed to the runtime-specific Create methods. - struct CreateParams { - CreateParams() {} - - // Copy constructor used with the chrome runtime only. - CreateParams(const CreateParams& that) { operator=(that); } - CreateParams& operator=(const CreateParams& that) { - // Not all parameters can be copied. - client = that.client; - url = that.url; - settings = that.settings; - request_context = that.request_context; - extra_info = that.extra_info; - return *this; - } - - // Platform-specific window creation info. Will be nullptr when creating a - // views-hosted browser. Currently used with the alloy runtime only. - std::unique_ptr window_info; - -#if defined(USE_AURA) - // The BrowserView that will own a views-hosted browser. Will be nullptr for - // popup browsers (the BrowserView will be created later in that case). - // Currently used with the alloy runtime only. - CefRefPtr browser_view; -#endif - - // Client implementation. May be nullptr. - CefRefPtr client; - - // Initial URL to load. May be empty. If this is a valid extension URL then - // the browser will be created as an app view extension host. - GURL url; - - // Browser settings. - CefBrowserSettings settings; - - // Other browser that opened this DevTools browser. Will be nullptr for non- - // DevTools browsers. Currently used with the alloy runtime only. - CefRefPtr devtools_opener; - - // Request context to use when creating the browser. If nullptr the global - // request context will be used. - CefRefPtr request_context; - - // Extra information that will be passed to - // CefRenderProcessHandler::OnBrowserCreated. - CefRefPtr extra_info; - - // Used when explicitly creating the browser as an extension host via - // ProcessManager::CreateBackgroundHost. Currently used with the alloy - // runtime only. - const extensions::Extension* extension = nullptr; - extensions::ViewType extension_host_type = extensions::VIEW_TYPE_INVALID; - }; - // Interface to implement for observers that wish to be informed of changes // to the CefBrowserHostBase. All methods will be called on the UI thread. class Observer : public base::CheckedObserver { @@ -114,10 +117,12 @@ class CefBrowserHostBase : public CefBrowserHost, int render_process_id, int render_routing_id); - CefBrowserHostBase(const CefBrowserSettings& settings, - CefRefPtr client, - scoped_refptr browser_info, - CefRefPtr request_context); + CefBrowserHostBase( + const CefBrowserSettings& settings, + CefRefPtr client, + std::unique_ptr platform_delegate, + scoped_refptr browser_info, + CefRefPtr request_context); // Called on the UI thread after the associated WebContents is created. virtual void InitializeBrowser(); @@ -139,6 +144,15 @@ class CefBrowserHostBase : public CefBrowserHost, CefRefPtr callback) override; void ReplaceMisspelling(const CefString& word) override; void AddWordToDictionary(const CefString& word) override; + void SendKeyEvent(const CefKeyEvent& event) override; + void SendMouseClickEvent(const CefMouseEvent& event, + MouseButtonType type, + bool mouseUp, + int clickCount) override; + void SendMouseMoveEvent(const CefMouseEvent& event, bool mouseLeave) override; + void SendMouseWheelEvent(const CefMouseEvent& event, + int deltaX, + int deltaY) override; void GetNavigationEntries(CefRefPtr visitor, bool current_only) override; CefRefPtr GetVisibleNavigationEntry() override; @@ -146,8 +160,13 @@ class CefBrowserHostBase : public CefBrowserHost, // CefBrowser methods: CefRefPtr GetHost() override; bool CanGoBack() override; + void GoBack() override; bool CanGoForward() override; + void GoForward() override; bool IsLoading() override; + void Reload() override; + void ReloadIgnoreCache() override; + void StopLoad() override; int GetIdentifier() override; bool IsSame(CefRefPtr that) override; bool HasDocument() override; @@ -162,7 +181,7 @@ class CefBrowserHostBase : public CefBrowserHost, // CefBrowserContentsDelegate::Observer methods: void OnStateChanged(CefBrowserContentsState state_changed) override; - void OnWebContentsDestroyed() override; + void OnWebContentsDestroyed(content::WebContents* web_contents) override; // Returns the frame associated with the specified RenderFrameHost. CefRefPtr GetFrameForHost(const content::RenderFrameHost* host); @@ -177,15 +196,17 @@ class CefBrowserHostBase : public CefBrowserHost, bool HasObserver(Observer* observer) const; // Methods called from CefFrameHostImpl. - void LoadMainFrameURL(const std::string& url, - const content::Referrer& referrer, - ui::PageTransition transition, - const std::string& extra_headers); + void LoadMainFrameURL(const content::OpenURLParams& params); void OnDidFinishLoad(CefRefPtr frame, const GURL& validated_url, int http_status_code); virtual void OnSetFocus(cef_focus_source_t source) = 0; - virtual void ViewText(const std::string& text) = 0; + void ViewText(const std::string& text); + + // Called from CefBrowserInfoManager::MaybeAllowNavigation. + virtual bool MaybeAllowNavigation(content::RenderFrameHost* opener, + bool is_guest_view, + const content::OpenURLParams& params); // Helpers for executing client callbacks. Must be called on the UI thread. void OnAfterCreated(); @@ -204,14 +225,21 @@ class CefBrowserHostBase : public CefBrowserHost, // Accessors that must be called on the UI thread. content::WebContents* GetWebContents() const; content::BrowserContext* GetBrowserContext() const; + CefBrowserPlatformDelegate* platform_delegate() const { + return platform_delegate_.get(); + } CefBrowserContentsDelegate* contents_delegate() const { return contents_delegate_.get(); } protected: + // Called from LoadMainFrameURL to perform the actual navigation. + virtual bool Navigate(const content::OpenURLParams& params); + // Thread-safe members. CefBrowserSettings settings_; CefRefPtr client_; + std::unique_ptr platform_delegate_; scoped_refptr browser_info_; CefRefPtr request_context_; diff --git a/libcef/browser/browser_host_create.cc b/libcef/browser/browser_host_create.cc index aeb754926..28b11b476 100644 --- a/libcef/browser/browser_host_create.cc +++ b/libcef/browser/browser_host_create.cc @@ -121,7 +121,7 @@ CefRefPtr CefBrowserHost::CreateBrowserSync( return nullptr; } - CefBrowserHostBase::CreateParams create_params; + CefBrowserCreateParams create_params; create_params.window_info.reset(new CefWindowInfo(windowInfo)); create_params.client = client; create_params.url = GURL(url.ToString()); diff --git a/libcef/browser/browser_info_manager.cc b/libcef/browser/browser_info_manager.cc index 7d901bb31..04e9f80bf 100644 --- a/libcef/browser/browser_info_manager.cc +++ b/libcef/browser/browser_info_manager.cc @@ -6,7 +6,7 @@ #include -#include "libcef/browser/alloy/alloy_browser_host_impl.h" +#include "libcef/browser/browser_host_base.h" #include "libcef/browser/browser_platform_delegate.h" #include "libcef/browser/extensions/browser_extensions_util.h" #include "libcef/browser/thread_util.h" @@ -24,7 +24,6 @@ #include "content/public/browser/web_contents.h" #include "content/public/common/child_process_host.h" #include "content/public/common/url_constants.h" -#include "extensions/common/constants.h" namespace { @@ -117,14 +116,13 @@ bool CefBrowserInfoManager::CanCreateWindow( bool opener_suppressed, bool* no_javascript_access) { CEF_REQUIRE_UIT(); - REQUIRE_ALLOY_RUNTIME(); content::OpenURLParams params(target_url, referrer, disposition, ui::PAGE_TRANSITION_LINK, /*is_renderer_initiated=*/true); params.user_gesture = user_gesture; - CefRefPtr browser; + CefRefPtr browser; if (!MaybeAllowNavigation(opener, params, browser) || !browser) { // Cancel the popup. return false; @@ -182,9 +180,9 @@ bool CefBrowserInfoManager::CanCreateWindow( } if (allow) { - CefBrowserHostBase::CreateParams create_params; + CefBrowserCreateParams create_params; - if (!browser->IsViewsHosted()) + if (!browser->HasView()) create_params.window_info = std::move(window_info); create_params.settings = pending_popup->settings; @@ -243,12 +241,16 @@ void CefBrowserInfoManager::WebContentsCreated( std::unique_ptr& platform_delegate, CefRefPtr& extra_info) { CEF_REQUIRE_UIT(); - REQUIRE_ALLOY_RUNTIME(); + + // GET_CUSTOM_WEB_CONTENTS_VIEW is only used with the alloy runtime. + const auto previous_step = + cef::IsAlloyRuntimeEnabled() + ? CefBrowserInfoManager::PendingPopup::GET_CUSTOM_WEB_CONTENTS_VIEW + : CefBrowserInfoManager::PendingPopup::CAN_CREATE_WINDOW; std::unique_ptr pending_popup = - PopPendingPopup( - CefBrowserInfoManager::PendingPopup::GET_CUSTOM_WEB_CONTENTS_VIEW, - opener_render_process_id, opener_render_routing_id, target_url); + PopPendingPopup(previous_step, opener_render_process_id, + opener_render_routing_id, target_url); DCHECK(pending_popup.get()); DCHECK(pending_popup->platform_delegate.get()); @@ -365,29 +367,18 @@ CefBrowserInfoManager::GetBrowserInfoForFrameRoute(int render_process_id, bool CefBrowserInfoManager::MaybeAllowNavigation( content::RenderFrameHost* opener, const content::OpenURLParams& params, - CefRefPtr& browser_out) const { + CefRefPtr& browser_out) const { CEF_REQUIRE_UIT(); - REQUIRE_ALLOY_RUNTIME(); bool is_guest_view = false; - CefRefPtr browser = static_cast( - extensions::GetOwnerBrowserForHost(opener, &is_guest_view).get()); + auto browser = extensions::GetOwnerBrowserForHost(opener, &is_guest_view); if (!browser) { // Print preview uses a modal dialog where we don't own the WebContents. // Allow that navigation to proceed. return true; } - if (is_guest_view && !params.url.SchemeIs(extensions::kExtensionScheme) && - !params.url.SchemeIs(content::kChromeUIScheme)) { - // The PDF viewer will load the PDF extension in the guest view, and print - // preview will load chrome://print in the guest view. All other navigations - // are passed to the owner browser. - CEF_POST_TASK( - CEF_UIT, - base::Bind(base::IgnoreResult(&AlloyBrowserHostImpl::OpenURLFromTab), - browser.get(), nullptr, params)); - + if (!browser->MaybeAllowNavigation(opener, is_guest_view, params)) { return false; } diff --git a/libcef/browser/browser_info_manager.h b/libcef/browser/browser_info_manager.h index df56d4a72..010b11239 100644 --- a/libcef/browser/browser_info_manager.h +++ b/libcef/browser/browser_info_manager.h @@ -38,7 +38,6 @@ class Message; } class CefBrowserHostBase; -class AlloyBrowserHostImpl; class CefBrowserPlatformDelegate; // Singleton object for managing BrowserInfo instances. @@ -50,15 +49,14 @@ class CefBrowserInfoManager : public content::RenderProcessHostObserver { // Returns this singleton instance of this class. static CefBrowserInfoManager* GetInstance(); - // Called from AlloyBrowserHostImpl::Create or - // ChromeBrowserDelegate::SetAsDelegate when a new browser is being created + // Called immediately before a new CefBrowserHost implementation is created // directly. In this case |is_popup| will be true only for DevTools browsers. scoped_refptr CreateBrowserInfo( bool is_popup, bool is_windowless, CefRefPtr extra_info); - // Called from AlloyBrowserHostImpl::WebContentsCreated when a new browser is + // Called from WebContentsDelegate::WebContentsCreated when a new browser is // being created for a traditional popup (e.g. window.open() or targeted // link). If any OnGetNewBrowserInfo requests are pending for the popup the // response will be sent when this method is called. @@ -67,7 +65,7 @@ class CefBrowserInfoManager : public content::RenderProcessHostObserver { bool is_windowless, CefRefPtr extra_info); - // Called from AlloyContentBrowserClient::CanCreateWindow. See comments on + // Called from ContentBrowserClient::CanCreateWindow. See comments on // PendingPopup for more information. bool CanCreateWindow(content::RenderFrameHost* opener, const GURL& target_url, @@ -79,8 +77,8 @@ class CefBrowserInfoManager : public content::RenderProcessHostObserver { bool opener_suppressed, bool* no_javascript_access); - // Called from AlloyBrowserHostImpl::GetCustomWebContentsView. See comments on - // PendingPopup for more information. + // Called from WebContentsDelegate::GetCustomWebContentsView (alloy runtime + // only). See comments on PendingPopup for more information. void GetCustomWebContentsView( const GURL& target_url, int opener_render_process_id, @@ -88,7 +86,7 @@ class CefBrowserInfoManager : public content::RenderProcessHostObserver { content::WebContentsView** view, content::RenderViewHostDelegateView** delegate_view); - // Called from AlloyBrowserHostImpl::WebContentsCreated. See comments on + // Called from WebContentsDelegate::WebContentsCreated. See comments on // PendingPopup for more information. void WebContentsCreated( const GURL& target_url, @@ -147,23 +145,24 @@ class CefBrowserInfoManager : public content::RenderProcessHostObserver { // |browser| will be set to the target browser if any. bool MaybeAllowNavigation(content::RenderFrameHost* opener, const content::OpenURLParams& params, - CefRefPtr& browser) const; + CefRefPtr& browser) const; private: // RenderProcessHostObserver methods: void RenderProcessHostDestroyed(content::RenderProcessHost* host) override; // Store state information about pending popups. Call order is: - // - AlloyContentBrowserClient::CanCreateWindow (UIT) + // - CanCreateWindow (UIT): // Provides an opportunity to cancel the popup (calls OnBeforePopup) and // creates the new platform delegate for the popup. If the popup owner is // an extension guest view then the popup is canceled and - // AlloyBrowserHostImpl::OpenURLFromTab is called. + // WebContentsDelegate::OpenURLFromTab is called via the + // CefBrowserHostBase::MaybeAllowNavigation implementation. // And then the following calls may occur at the same time: - // - AlloyBrowserHostImpl::GetCustomWebContentsView (UIT) + // - GetCustomWebContentsView (UIT) (alloy runtime only): // Creates the OSR views for windowless popups. - // - AlloyBrowserHostImpl::WebContentsCreated (UIT) - // Creates the AlloyBrowserHostImpl representation for the popup. + // - WebContentsCreated (UIT): + // Creates the CefBrowserHost representation for the popup. // - CefBrowserMessageFilter::OnGetNewBrowserInfo (IOT) // Passes information about the popup to the renderer process. struct PendingPopup { diff --git a/libcef/browser/browser_platform_delegate.cc b/libcef/browser/browser_platform_delegate.cc index 477135e7c..2dc417e3a 100644 --- a/libcef/browser/browser_platform_delegate.cc +++ b/libcef/browser/browser_platform_delegate.cc @@ -14,6 +14,13 @@ CefBrowserPlatformDelegate::~CefBrowserPlatformDelegate() { DCHECK(!browser_); } +content::WebContents* CefBrowserPlatformDelegate::CreateWebContents( + CefBrowserCreateParams& create_params, + bool& own_web_contents) { + NOTREACHED(); + return nullptr; +} + void CefBrowserPlatformDelegate::CreateViewForWebContents( content::WebContentsView** view, content::RenderViewHostDelegateView** delegate_view) { @@ -57,7 +64,7 @@ void CefBrowserPlatformDelegate::RenderViewCreated( void CefBrowserPlatformDelegate::RenderViewReady() {} -void CefBrowserPlatformDelegate::BrowserCreated(AlloyBrowserHostImpl* browser) { +void CefBrowserPlatformDelegate::BrowserCreated(CefBrowserHostBase* browser) { // We should have an associated WebContents at this point. DCHECK(web_contents_); @@ -83,8 +90,7 @@ void CefBrowserPlatformDelegate::NotifyBrowserCreated() {} void CefBrowserPlatformDelegate::NotifyBrowserDestroyed() {} -void CefBrowserPlatformDelegate::BrowserDestroyed( - AlloyBrowserHostImpl* browser) { +void CefBrowserPlatformDelegate::BrowserDestroyed(CefBrowserHostBase* browser) { // WebContentsDestroyed should already be called. DCHECK(!web_contents_); @@ -101,6 +107,11 @@ void CefBrowserPlatformDelegate::CloseHostWindow() { NOTREACHED(); } +CefWindowHandle CefBrowserPlatformDelegate::GetHostWindowHandle() const { + NOTREACHED(); + return kNullWindowHandle; +} + #if defined(USE_AURA) views::Widget* CefBrowserPlatformDelegate::GetWindowWidget() const { NOTREACHED(); @@ -121,9 +132,49 @@ void CefBrowserPlatformDelegate::PopupWebContentsCreated( bool is_devtools) {} void CefBrowserPlatformDelegate::PopupBrowserCreated( - AlloyBrowserHostImpl* new_browser, + CefBrowserHostBase* new_browser, bool is_devtools) {} +SkColor CefBrowserPlatformDelegate::GetBackgroundColor() const { + NOTREACHED(); + return SkColor(); +} + +void CefBrowserPlatformDelegate::WasResized() { + NOTREACHED(); +} + +void CefBrowserPlatformDelegate::SendKeyEvent(const CefKeyEvent& event) { + NOTIMPLEMENTED(); +} + +void CefBrowserPlatformDelegate::SendMouseClickEvent( + const CefMouseEvent& event, + CefBrowserHost::MouseButtonType type, + bool mouseUp, + int clickCount) { + NOTIMPLEMENTED(); +} + +void CefBrowserPlatformDelegate::SendMouseMoveEvent(const CefMouseEvent& event, + bool mouseLeave) { + NOTIMPLEMENTED(); +} + +void CefBrowserPlatformDelegate::SendMouseWheelEvent(const CefMouseEvent& event, + int deltaX, + int deltaY) { + NOTIMPLEMENTED(); +} + +void CefBrowserPlatformDelegate::SendTouchEvent(const CefTouchEvent& event) { + NOTIMPLEMENTED(); +} + +void CefBrowserPlatformDelegate::SendFocusEvent(bool setFocus) { + NOTIMPLEMENTED(); +} + void CefBrowserPlatformDelegate::SendCaptureLostEvent() { NOTIMPLEMENTED(); } @@ -134,6 +185,22 @@ void CefBrowserPlatformDelegate::NotifyMoveOrResizeStarted() {} void CefBrowserPlatformDelegate::SizeTo(int width, int height) {} #endif +gfx::Point CefBrowserPlatformDelegate::GetScreenPoint( + const gfx::Point& view) const { + NOTREACHED(); + return gfx::Point(); +} + +void CefBrowserPlatformDelegate::ViewText(const std::string& text) { + NOTIMPLEMENTED(); +} + +bool CefBrowserPlatformDelegate::HandleKeyboardEvent( + const content::NativeWebKeyboardEvent& event) { + NOTREACHED(); + return false; +} + bool CefBrowserPlatformDelegate::PreHandleGestureEvent( content::WebContents* source, const blink::WebGestureEvent& event) { @@ -145,6 +212,12 @@ bool CefBrowserPlatformDelegate::IsNeverComposited( return false; } +CefEventHandle CefBrowserPlatformDelegate::GetEventHandle( + const content::NativeWebKeyboardEvent& event) const { + NOTREACHED(); + return kNullEventHandle; +} + std::unique_ptr CefBrowserPlatformDelegate::CreateFileDialogRunner() { NOTIMPLEMENTED(); @@ -157,6 +230,19 @@ CefBrowserPlatformDelegate::CreateJavaScriptDialogRunner() { return nullptr; } +std::unique_ptr CefBrowserPlatformDelegate::CreateMenuRunner() { + NOTIMPLEMENTED(); + return nullptr; +} + +bool CefBrowserPlatformDelegate::IsWindowless() const { + return false; +} + +bool CefBrowserPlatformDelegate::IsViewsHosted() const { + return false; +} + void CefBrowserPlatformDelegate::WasHidden(bool hidden) { NOTREACHED(); } diff --git a/libcef/browser/browser_platform_delegate.h b/libcef/browser/browser_platform_delegate.h index cfb579894..55f30d339 100644 --- a/libcef/browser/browser_platform_delegate.h +++ b/libcef/browser/browser_platform_delegate.h @@ -13,12 +13,17 @@ #include "include/cef_drag_data.h" #include "include/internal/cef_types.h" #include "include/views/cef_browser_view.h" -#include "libcef/browser/alloy/alloy_browser_host_impl.h" #include "base/callback_forward.h" -#include "content/public/browser/web_contents.h" +#include "extensions/common/view_type.h" +#include "third_party/blink/public/common/page/web_drag_operation.h" +#include "third_party/skia/include/core/SkColor.h" +#include "ui/base/window_open_disposition.h" + +class GURL; namespace blink { +class WebGestureEvent; class WebMouseEvent; class WebMouseWheelEvent; class WebInputEvent; @@ -26,15 +31,30 @@ class WebTouchEvent; } // namespace blink namespace content { +struct AXEventNotificationDetails; +struct AXLocationChangeNotificationDetails; +struct DragEventSourceInfo; +struct DropData; struct NativeWebKeyboardEvent; class RenderViewHost; class RenderViewHostDelegateView; +class RenderWidgetHostImpl; +class WebContents; class WebContentsView; } // namespace content namespace extensions { +class Extension; class ExtensionHost; -} +} // namespace extensions + +namespace gfx { +class ImageSkia; +class Point; +class Rect; +class Size; +class Vector2d; +} // namespace gfx #if defined(USE_AURA) namespace views { @@ -42,6 +62,8 @@ class Widget; } #endif +struct CefBrowserCreateParams; +class CefBrowserHostBase; class CefFileDialogRunner; class CefJavaScriptDialogRunner; class CefMenuRunner; @@ -54,14 +76,14 @@ class CefBrowserPlatformDelegate { // Create a new CefBrowserPlatformDelegate instance. May be called on multiple // threads. static std::unique_ptr Create( - CefBrowserHostBase::CreateParams& create_params); + const CefBrowserCreateParams& create_params); // Called from AlloyBrowserHostImpl::Create. // Wait for the call to WebContentsCreated(owned=true) before taking ownership // of the resulting WebContents object. virtual content::WebContents* CreateWebContents( - CefBrowserHostBase::CreateParams& create_params, - bool& own_web_contents) = 0; + CefBrowserCreateParams& create_params, + bool& own_web_contents); // Called to create the view objects for a new WebContents. Will only be // called a single time per instance. May be called on multiple threads. Only @@ -106,7 +128,7 @@ class CefBrowserPlatformDelegate { // Called after the owning AlloyBrowserHostImpl is created. Will only be // called a single time per instance. Do not send any client notifications // from this method. - virtual void BrowserCreated(AlloyBrowserHostImpl* browser); + virtual void BrowserCreated(CefBrowserHostBase* browser); // Called from AlloyBrowserHostImpl::Create. virtual void CreateExtensionHost(const extensions::Extension* extension, @@ -128,7 +150,7 @@ class CefBrowserPlatformDelegate { // called a single time per instance. All references to the // AlloyBrowserHostImpl and WebContents should be cleared when this method is // called. Do not send any client notifications from this method. - virtual void BrowserDestroyed(AlloyBrowserHostImpl* browser); + virtual void BrowserDestroyed(CefBrowserHostBase* browser); // Create the window that hosts the browser. Will only be called a single time // per instance. Only used with windowed rendering. @@ -143,7 +165,7 @@ class CefBrowserPlatformDelegate { // rendering this will return the most immediate parent window handle. For // windowless rendering this will return the parent window handle specified by // the client, which may be NULL. May be called on multiple threads. - virtual CefWindowHandle GetHostWindowHandle() const = 0; + virtual CefWindowHandle GetHostWindowHandle() const; #if defined(USE_AURA) // Returns the Widget owner for the browser window. Only used with windowed @@ -174,7 +196,7 @@ class CefBrowserPlatformDelegate { // CefLifeSpanHandler::OnAfterCreated() for the popup browser. It is safe to // make the new browser visible in this callback (for example, add the browser // to a window and show it). - virtual void PopupBrowserCreated(AlloyBrowserHostImpl* new_browser, + virtual void PopupBrowserCreated(CefBrowserHostBase* new_browser, bool is_devtools); // Returns the background color for the browser. The alpha component will be @@ -182,27 +204,26 @@ class CefBrowserPlatformDelegate { // fully opaque). SK_AlphaOPAQUE will always be returned for windowed // browsers. SK_ColorTRANSPARENT may be returned for windowless browsers to // enable transparency. - virtual SkColor GetBackgroundColor() const = 0; + virtual SkColor GetBackgroundColor() const; // Notify the window that it was resized. - virtual void WasResized() = 0; + virtual void WasResized(); // Send input events. - virtual void SendKeyEvent(const CefKeyEvent& event) = 0; + virtual void SendKeyEvent(const CefKeyEvent& event); virtual void SendMouseClickEvent(const CefMouseEvent& event, CefBrowserHost::MouseButtonType type, bool mouseUp, - int clickCount) = 0; - virtual void SendMouseMoveEvent(const CefMouseEvent& event, - bool mouseLeave) = 0; + int clickCount); + virtual void SendMouseMoveEvent(const CefMouseEvent& event, bool mouseLeave); virtual void SendMouseWheelEvent(const CefMouseEvent& event, int deltaX, - int deltaY) = 0; - virtual void SendTouchEvent(const CefTouchEvent& event) = 0; + int deltaY); + virtual void SendTouchEvent(const CefTouchEvent& event); // Send focus event. The browser's WebContents may be NULL when this method is // called. - virtual void SendFocusEvent(bool setFocus) = 0; + virtual void SendFocusEvent(bool setFocus); // Send capture lost event. virtual void SendCaptureLostEvent(); @@ -219,15 +240,15 @@ class CefBrowserPlatformDelegate { // Convert from view coordinates to screen coordinates. Potential display // scaling will be applied to the result. - virtual gfx::Point GetScreenPoint(const gfx::Point& view) const = 0; + virtual gfx::Point GetScreenPoint(const gfx::Point& view) const; // Open the specified text in the default text editor. - virtual void ViewText(const std::string& text) = 0; + virtual void ViewText(const std::string& text); // Forward the keyboard event to the application or frame window to allow // processing of shortcut keys. virtual bool HandleKeyboardEvent( - const content::NativeWebKeyboardEvent& event) = 0; + const content::NativeWebKeyboardEvent& event); // See WebContentsDelegate documentation. virtual bool PreHandleGestureEvent(content::WebContents* source, @@ -241,7 +262,7 @@ class CefBrowserPlatformDelegate { // Returns the OS event handle, if any, associated with |event|. virtual CefEventHandle GetEventHandle( - const content::NativeWebKeyboardEvent& event) const = 0; + const content::NativeWebKeyboardEvent& event) const; // Create the platform-specific file dialog runner. virtual std::unique_ptr CreateFileDialogRunner(); @@ -251,15 +272,15 @@ class CefBrowserPlatformDelegate { CreateJavaScriptDialogRunner(); // Create the platform-specific menu runner. - virtual std::unique_ptr CreateMenuRunner() = 0; + virtual std::unique_ptr CreateMenuRunner(); // Returns true if this delegate implements windowless rendering. May be // called on multiple threads. - virtual bool IsWindowless() const = 0; + virtual bool IsWindowless() const; // Returns true if this delegate implements views-hosted browser handling. May // be called on multiple threads. - virtual bool IsViewsHosted() const = 0; + virtual bool IsViewsHosted() const; // Notify the browser that it was hidden. Only used with windowless rendering. virtual void WasHidden(bool hidden); @@ -343,7 +364,7 @@ class CefBrowserPlatformDelegate { // Not owned by this object. content::WebContents* web_contents_ = nullptr; - AlloyBrowserHostImpl* browser_ = nullptr; + CefBrowserHostBase* browser_ = nullptr; DISALLOW_COPY_AND_ASSIGN(CefBrowserPlatformDelegate); }; diff --git a/libcef/browser/browser_platform_delegate_create.cc b/libcef/browser/browser_platform_delegate_create.cc index d6f6fc05d..14af1812e 100644 --- a/libcef/browser/browser_platform_delegate_create.cc +++ b/libcef/browser/browser_platform_delegate_create.cc @@ -11,6 +11,8 @@ #include "base/memory/ptr_util.h" #include "build/build_config.h" +#include "libcef/browser/browser_host_base.h" +#include "libcef/browser/chrome/browser_platform_delegate_chrome.h" #include "libcef/browser/extensions/browser_platform_delegate_background.h" #include "libcef/features/runtime_checks.h" @@ -68,7 +70,7 @@ std::unique_ptr CreateOSRDelegate( // static std::unique_ptr CefBrowserPlatformDelegate::Create( - CefBrowserHostBase::CreateParams& create_params) { + const CefBrowserCreateParams& create_params) { const bool is_windowless = create_params.window_info && create_params.window_info->windowless_rendering_enabled && @@ -76,6 +78,14 @@ std::unique_ptr CefBrowserPlatformDelegate::Create( const SkColor background_color = CefContext::Get()->GetBackgroundColor( &create_params.settings, is_windowless ? STATE_ENABLED : STATE_DISABLED); + if (cef::IsChromeRuntimeEnabled()) { + // CefWindowInfo is not used in this case. + std::unique_ptr native_delegate = + CreateNativeDelegate(CefWindowInfo(), background_color); + return std::make_unique( + std::move(native_delegate)); + } + if (create_params.window_info) { std::unique_ptr native_delegate = CreateNativeDelegate(*create_params.window_info.get(), diff --git a/libcef/browser/chrome/browser_delegate.h b/libcef/browser/chrome/browser_delegate.h index 9e01825df..c0b565ef7 100644 --- a/libcef/browser/chrome/browser_delegate.h +++ b/libcef/browser/chrome/browser_delegate.h @@ -35,6 +35,9 @@ class BrowserDelegate : public content::WebContentsDelegate { ~BrowserDelegate() override {} + // Called immediately after |new_contents| is created. + virtual void OnWebContentsCreated(content::WebContents* new_contents) = 0; + // Add or remove ownership of the WebContents. virtual void SetAsDelegate(content::WebContents* web_contents, bool set_delegate) = 0; diff --git a/libcef/browser/chrome/browser_platform_delegate_chrome.cc b/libcef/browser/chrome/browser_platform_delegate_chrome.cc new file mode 100644 index 000000000..4df6ed3c5 --- /dev/null +++ b/libcef/browser/chrome/browser_platform_delegate_chrome.cc @@ -0,0 +1,101 @@ +// Copyright 2020 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/chrome/browser_platform_delegate_chrome.h" + +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_window.h" +#include "ui/display/screen.h" +#include "ui/gfx/geometry/point.h" + +CefBrowserPlatformDelegateChrome::CefBrowserPlatformDelegateChrome( + std::unique_ptr native_delegate) + : native_delegate_(std::move(native_delegate)) { + native_delegate_->set_windowless_handler(this); +} + +void CefBrowserPlatformDelegateChrome::WebContentsCreated( + content::WebContents* web_contents, + bool owned) { + CefBrowserPlatformDelegate::WebContentsCreated(web_contents, owned); + native_delegate_->WebContentsCreated(web_contents, /*owned=*/false); +} + +void CefBrowserPlatformDelegateChrome::WebContentsDestroyed( + content::WebContents* web_contents) { + CefBrowserPlatformDelegate::WebContentsDestroyed(web_contents); + native_delegate_->WebContentsDestroyed(web_contents); +} + +void CefBrowserPlatformDelegateChrome::BrowserCreated( + CefBrowserHostBase* browser) { + CefBrowserPlatformDelegate::BrowserCreated(browser); + native_delegate_->BrowserCreated(browser); +} + +void CefBrowserPlatformDelegateChrome::BrowserDestroyed( + CefBrowserHostBase* browser) { + CefBrowserPlatformDelegate::BrowserDestroyed(browser); + native_delegate_->BrowserDestroyed(browser); +} + +SkColor CefBrowserPlatformDelegateChrome::GetBackgroundColor() const { + return native_delegate_->GetBackgroundColor(); +} + +void CefBrowserPlatformDelegateChrome::SendKeyEvent(const CefKeyEvent& event) { + native_delegate_->SendKeyEvent(event); +} + +void CefBrowserPlatformDelegateChrome::SendMouseClickEvent( + const CefMouseEvent& event, + CefBrowserHost::MouseButtonType type, + bool mouseUp, + int clickCount) { + native_delegate_->SendMouseClickEvent(event, type, mouseUp, clickCount); +} + +void CefBrowserPlatformDelegateChrome::SendMouseMoveEvent( + const CefMouseEvent& event, + bool mouseLeave) { + native_delegate_->SendMouseMoveEvent(event, mouseLeave); +} + +void CefBrowserPlatformDelegateChrome::SendMouseWheelEvent( + const CefMouseEvent& event, + int deltaX, + int deltaY) { + native_delegate_->SendMouseWheelEvent(event, deltaX, deltaY); +} + +gfx::Point CefBrowserPlatformDelegateChrome::GetScreenPoint( + const gfx::Point& view) const { + auto screen = display::Screen::GetScreen(); + + gfx::NativeWindow native_window = + chrome_browser_ ? chrome_browser_->window()->GetNativeWindow() : nullptr; + + // Returns screen pixel coordinates. + auto screen_rect = screen->DIPToScreenRectInWindow( + native_window, gfx::Rect(view, gfx::Size(0, 0))); + return screen_rect.origin(); +} + +void CefBrowserPlatformDelegateChrome::ViewText(const std::string& text) { + native_delegate_->ViewText(text); +} + +CefWindowHandle CefBrowserPlatformDelegateChrome::GetParentWindowHandle() + const { + return GetHostWindowHandle(); +} + +gfx::Point CefBrowserPlatformDelegateChrome::GetParentScreenPoint( + const gfx::Point& view) const { + return GetScreenPoint(view); +} + +void CefBrowserPlatformDelegateChrome::set_chrome_browser(Browser* browser) { + chrome_browser_ = browser; +} diff --git a/libcef/browser/chrome/browser_platform_delegate_chrome.h b/libcef/browser/chrome/browser_platform_delegate_chrome.h new file mode 100644 index 000000000..60275f234 --- /dev/null +++ b/libcef/browser/chrome/browser_platform_delegate_chrome.h @@ -0,0 +1,52 @@ +// Copyright 2020 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_CHROME_BROWSER_PLATFORM_DELEGATE_CHROME_H_ +#define CEF_LIBCEF_BROWSER_CHROME_BROWSER_PLATFORM_DELEGATE_CHROME_H_ + +#include "libcef/browser/browser_platform_delegate.h" +#include "libcef/browser/native/browser_platform_delegate_native.h" + +class Browser; + +// Implementation of Chrome-based browser functionality. +class CefBrowserPlatformDelegateChrome + : public CefBrowserPlatformDelegate, + public CefBrowserPlatformDelegateNative::WindowlessHandler { + public: + explicit CefBrowserPlatformDelegateChrome( + std::unique_ptr native_delegate); + + // CefBrowserPlatformDelegate overrides. + void WebContentsCreated(content::WebContents* web_contents, + bool owned) override; + void WebContentsDestroyed(content::WebContents* web_contents) override; + void BrowserCreated(CefBrowserHostBase* browser) override; + void BrowserDestroyed(CefBrowserHostBase* browser) override; + SkColor GetBackgroundColor() const override; + void SendKeyEvent(const CefKeyEvent& event) override; + void SendMouseClickEvent(const CefMouseEvent& event, + CefBrowserHost::MouseButtonType type, + bool mouseUp, + int clickCount) override; + void SendMouseMoveEvent(const CefMouseEvent& event, bool mouseLeave) override; + void SendMouseWheelEvent(const CefMouseEvent& event, + int deltaX, + int deltaY) override; + gfx::Point GetScreenPoint(const gfx::Point& view) const override; + void ViewText(const std::string& text) override; + + // CefBrowserPlatformDelegateNative::WindowlessHandler methods: + CefWindowHandle GetParentWindowHandle() const override; + gfx::Point GetParentScreenPoint(const gfx::Point& view) const override; + + void set_chrome_browser(Browser* browser); + + private: + std::unique_ptr native_delegate_; + + Browser* chrome_browser_ = nullptr; +}; + +#endif // CEF_LIBCEF_BROWSER_CHROME_BROWSER_PLATFORM_DELEGATE_CHROME_H_ diff --git a/libcef/browser/chrome/chrome_browser_context.cc b/libcef/browser/chrome/chrome_browser_context.cc index 5bea962a7..e8ae49d89 100644 --- a/libcef/browser/chrome/chrome_browser_context.cc +++ b/libcef/browser/chrome/chrome_browser_context.cc @@ -4,6 +4,8 @@ #include "libcef/browser/chrome/chrome_browser_context.h" +#include "libcef/browser/prefs/browser_prefs.h" + #include "chrome/browser/profiles/profile_manager.h" ChromeBrowserContext::ChromeBrowserContext( @@ -28,6 +30,8 @@ void ChromeBrowserContext::Initialize() { // The global ProfileManager instance can be retrieved via // |g_browser_process->profile_manager()|. profile_ = ProfileManager::GetLastUsedProfileAllowedByPolicy(); + + browser_prefs::SetLanguagePrefs(profile_); } void ChromeBrowserContext::Shutdown() { diff --git a/libcef/browser/chrome/chrome_browser_delegate.cc b/libcef/browser/chrome/chrome_browser_delegate.cc index 5d781c20b..c3f73e667 100644 --- a/libcef/browser/chrome/chrome_browser_delegate.cc +++ b/libcef/browser/chrome/chrome_browser_delegate.cc @@ -9,22 +9,36 @@ #include "libcef/browser/browser_contents_delegate.h" #include "libcef/browser/browser_host_base.h" #include "libcef/browser/browser_info_manager.h" +#include "libcef/browser/browser_platform_delegate.h" #include "libcef/browser/chrome/chrome_browser_host_impl.h" #include "libcef/browser/request_context_impl.h" #include "libcef/common/app_manager.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" +#include "content/public/browser/keyboard_event_processing_result.h" +#include "content/public/browser/native_web_keyboard_event.h" + +using content::KeyboardEventProcessingResult; ChromeBrowserDelegate::ChromeBrowserDelegate( Browser* browser, - const CefBrowserHostBase::CreateParams& create_params) + const CefBrowserCreateParams& create_params) : browser_(browser), create_params_(create_params) { DCHECK(browser_); } ChromeBrowserDelegate::~ChromeBrowserDelegate() = default; +void ChromeBrowserDelegate::OnWebContentsCreated( + content::WebContents* new_contents) { + // Necessary to receive LoadingStateChanged calls during initial navigation. + // This will be called again in Browser::SetAsDelegate, which should be fine. + new_contents->SetDelegate(browser_); + + SetAsDelegate(new_contents, /*set_delegate=*/true); +} + void ChromeBrowserDelegate::SetAsDelegate(content::WebContents* web_contents, bool set_delegate) { DCHECK(web_contents); @@ -40,37 +54,67 @@ void ChromeBrowserDelegate::SetAsDelegate(content::WebContents* web_contents, return; } - auto request_context_impl = - CefRequestContextImpl::GetOrCreateForRequestContext( - create_params_.request_context); - - // Check if chrome and CEF are using the same browser context. - // TODO(chrome-runtime): Verify if/when this might occur. - auto chrome_browser_context = - CefBrowserContext::FromBrowserContext(browser_->create_params().profile); - if (chrome_browser_context != request_context_impl->GetBrowserContext()) { - LOG(WARNING) << "Creating a chrome browser with mismatched context"; - } - - CefRefPtr client = create_params_.client; - if (!client) { - if (auto app = CefAppManager::Get()->GetApplication()) { - if (auto bph = app->GetBrowserProcessHandler()) { - client = bph->GetDefaultClient(); - } - } - } - - if (!client) { - LOG(WARNING) << "Creating a chrome browser without a client"; - } + auto platform_delegate = CefBrowserPlatformDelegate::Create(create_params_); + CHECK(platform_delegate); auto browser_info = CefBrowserInfoManager::GetInstance()->CreateBrowserInfo( /*is_popup=*/false, /*is_windowless=*/false, create_params_.extra_info); - browser_host = new ChromeBrowserHostImpl(create_params_.settings, client, - browser_info, request_context_impl); - browser_host->Attach(browser_, web_contents); + auto request_context_impl = + CefRequestContextImpl::GetOrCreateForRequestContext( + create_params_.request_context); + + CreateBrowser(web_contents, create_params_.settings, create_params_.client, + std::move(platform_delegate), browser_info, + request_context_impl); +} + +void ChromeBrowserDelegate::WebContentsCreated( + content::WebContents* source_contents, + int opener_render_process_id, + int opener_render_frame_id, + const std::string& frame_name, + const GURL& target_url, + content::WebContents* new_contents) { + CefBrowserSettings settings; + CefRefPtr client; + std::unique_ptr platform_delegate; + CefRefPtr extra_info; + + CefBrowserInfoManager::GetInstance()->WebContentsCreated( + target_url, opener_render_process_id, opener_render_frame_id, settings, + client, platform_delegate, extra_info); + + auto opener = ChromeBrowserHostImpl::GetBrowserForContents(source_contents); + if (!opener) { + LOG(ERROR) << "No opener found for chrome popup browser"; + return; + } + + auto browser_info = + CefBrowserInfoManager::GetInstance()->CreatePopupBrowserInfo( + new_contents, /*is_windowless=*/false, extra_info); + CHECK(browser_info->is_popup()); + + // Popups must share the same RequestContext as the parent. + auto request_context_impl = opener->request_context(); + CHECK(request_context_impl); + + // We don't officially own |new_contents| until AddNewContents() is called. + // However, we need to install observers/delegates here. + CreateBrowser(new_contents, settings, client, std::move(platform_delegate), + browser_info, request_context_impl); +} + +content::WebContents* ChromeBrowserDelegate::OpenURLFromTab( + content::WebContents* source, + const content::OpenURLParams& params) { + // Return nullptr to cancel the navigation. Otherwise, proceed with default + // chrome handling. + if (auto delegate = GetDelegateForWebContents(source)) { + return delegate->OpenURLFromTab(source, params); + } + return nullptr; } void ChromeBrowserDelegate::LoadingStateChanged(content::WebContents* source, @@ -127,6 +171,64 @@ void ChromeBrowserDelegate::ExitFullscreenModeForTab( } } +KeyboardEventProcessingResult ChromeBrowserDelegate::PreHandleKeyboardEvent( + content::WebContents* source, + const content::NativeWebKeyboardEvent& event) { + if (auto delegate = GetDelegateForWebContents(source)) { + return delegate->PreHandleKeyboardEvent(source, event); + } + return KeyboardEventProcessingResult::NOT_HANDLED; +} + +bool ChromeBrowserDelegate::HandleKeyboardEvent( + content::WebContents* source, + const content::NativeWebKeyboardEvent& event) { + if (auto delegate = GetDelegateForWebContents(source)) { + return delegate->HandleKeyboardEvent(source, event); + } + return false; +} + +void ChromeBrowserDelegate::CreateBrowser( + content::WebContents* web_contents, + CefBrowserSettings settings, + CefRefPtr client, + std::unique_ptr platform_delegate, + scoped_refptr browser_info, + CefRefPtr request_context_impl) { + CEF_REQUIRE_UIT(); + DCHECK(web_contents); + DCHECK(platform_delegate); + DCHECK(browser_info); + DCHECK(request_context_impl); + + if (!client) { + if (auto app = CefAppManager::Get()->GetApplication()) { + if (auto bph = app->GetBrowserProcessHandler()) { + client = bph->GetDefaultClient(); + } + } + } + + if (!client) { + LOG(WARNING) << "Creating a chrome browser without a client"; + } + + // Check if chrome and CEF are using the same browser context. + // TODO(chrome-runtime): Verify if/when this might occur. + auto chrome_browser_context = + CefBrowserContext::FromBrowserContext(browser_->create_params().profile); + if (chrome_browser_context != request_context_impl->GetBrowserContext()) { + LOG(WARNING) << "Creating a chrome browser with mismatched context"; + } + + // Remains alive until the associated WebContents is destroyed. + CefRefPtr browser_host = + new ChromeBrowserHostImpl(settings, client, std::move(platform_delegate), + browser_info, request_context_impl); + browser_host->Attach(browser_, web_contents); +} + CefBrowserContentsDelegate* ChromeBrowserDelegate::GetDelegateForWebContents( content::WebContents* web_contents) { auto browser_host = @@ -142,7 +244,7 @@ namespace cef { std::unique_ptr BrowserDelegate::Create( Browser* browser, scoped_refptr cef_params) { - CefBrowserHostBase::CreateParams create_params; + CefBrowserCreateParams create_params; // Parameters from ChromeBrowserHostImpl::Create, or nullptr if the Browser // was created from somewhere else. diff --git a/libcef/browser/chrome/chrome_browser_delegate.h b/libcef/browser/chrome/chrome_browser_delegate.h index 485e44a29..566ca278a 100644 --- a/libcef/browser/chrome/chrome_browser_delegate.h +++ b/libcef/browser/chrome/chrome_browser_delegate.h @@ -40,14 +40,24 @@ class ChromeBrowserHostImpl; class ChromeBrowserDelegate : public cef::BrowserDelegate { public: ChromeBrowserDelegate(Browser* browser, - const CefBrowserHostBase::CreateParams& create_params); + const CefBrowserCreateParams& create_params); ~ChromeBrowserDelegate() override; // cef::BrowserDelegate methods: + void OnWebContentsCreated(content::WebContents* new_contents) override; void SetAsDelegate(content::WebContents* web_contents, bool set_delegate) override; // WebContentsDelegate methods: + void WebContentsCreated(content::WebContents* source_contents, + int opener_render_process_id, + int opener_render_frame_id, + const std::string& frame_name, + const GURL& target_url, + content::WebContents* new_contents) override; + content::WebContents* OpenURLFromTab( + content::WebContents* source, + const content::OpenURLParams& params) override; void LoadingStateChanged(content::WebContents* source, bool to_different_document) override; void UpdateTargetURL(content::WebContents* source, const GURL& url) override; @@ -62,17 +72,31 @@ class ChromeBrowserDelegate : public cef::BrowserDelegate { content::RenderFrameHost* requesting_frame, const blink::mojom::FullscreenOptions& options) override; void ExitFullscreenModeForTab(content::WebContents* web_contents) override; + content::KeyboardEventProcessingResult PreHandleKeyboardEvent( + content::WebContents* source, + const content::NativeWebKeyboardEvent& event) override; + bool HandleKeyboardEvent( + content::WebContents* source, + const content::NativeWebKeyboardEvent& event) override; Browser* browser() const { return browser_; } private: + void CreateBrowser( + content::WebContents* web_contents, + CefBrowserSettings settings, + CefRefPtr client, + std::unique_ptr platform_delegate, + scoped_refptr browser_info, + CefRefPtr request_context_impl); + CefBrowserContentsDelegate* GetDelegateForWebContents( content::WebContents* web_contents); Browser* const browser_; // Used when creating a new browser host. - const CefBrowserHostBase::CreateParams create_params_; + const CefBrowserCreateParams create_params_; DISALLOW_COPY_AND_ASSIGN(ChromeBrowserDelegate); }; diff --git a/libcef/browser/chrome/chrome_browser_host_impl.cc b/libcef/browser/chrome/chrome_browser_host_impl.cc index 80cbabf3e..542ea14ab 100644 --- a/libcef/browser/chrome/chrome_browser_host_impl.cc +++ b/libcef/browser/chrome/chrome_browser_host_impl.cc @@ -4,26 +4,27 @@ #include "libcef/browser/chrome/chrome_browser_host_impl.h" +#include "libcef/browser/browser_platform_delegate.h" +#include "libcef/browser/chrome/browser_platform_delegate_chrome.h" #include "libcef/browser/thread_util.h" #include "libcef/features/runtime_checks.h" #include "base/logging.h" #include "base/notreached.h" +#include "chrome/browser/printing/print_view_manager_common.h" +#include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_commands.h" +#include "chrome/browser/ui/browser_navigator.h" #include "chrome/browser/ui/browser_tabstrip.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" - -namespace { - -const auto kDefaultWindowDisposition = WindowOpenDisposition::CURRENT_TAB; - -} // namespace +#include "chrome/common/pref_names.h" +#include "url/url_constants.h" // static CefRefPtr ChromeBrowserHostImpl::Create( - const CreateParams& params) { + const CefBrowserCreateParams& params) { // Get or create the request context and profile. CefRefPtr request_context_impl = CefRequestContextImpl::GetOrCreateForRequestContext( @@ -44,21 +45,30 @@ CefRefPtr ChromeBrowserHostImpl::Create( // out of the existing Browser. auto browser = new Browser(chrome_params); - // Add a new tab. This will indirectly create a new tab WebContents and - // call ChromeBrowserDelegate::SetAsDelegate to create the associated - // ChromeBrowserHostImpl. - chrome::AddTabAt(browser, params.url, /*idx=*/-1, /*foreground=*/true); + GURL url = params.url; + if (url.is_empty()) { + // Chrome will navigate to kChromeUINewTabURL by default. We want to keep + // the current CEF behavior of not navigating at all. Use a special URL that + // will be recognized in HandleNonNavigationAboutURL. + url = GURL("chrome://ignore/"); + } - browser->window()->Show(); + // Add a new tab. This will indirectly create a new tab WebContents and + // call ChromeBrowserDelegate::OnWebContentsCreated to create the associated + // ChromeBrowserHostImpl. + chrome::AddTabAt(browser, url, /*idx=*/-1, /*foreground=*/true); // The new tab WebContents. auto web_contents = browser->tab_strip_model()->GetActiveWebContents(); - DCHECK(web_contents); + CHECK(web_contents); // The associated ChromeBrowserHostImpl. auto browser_host = ChromeBrowserHostImpl::GetBrowserForContents(web_contents); - DCHECK(browser_host); + CHECK(browser_host); + + browser->window()->Show(); + return browser_host; } @@ -107,20 +117,34 @@ CefRefPtr ChromeBrowserHostImpl::GetBrowserForFrameRoute( ChromeBrowserHostImpl::~ChromeBrowserHostImpl() = default; -void ChromeBrowserHostImpl::OnWebContentsDestroyed() { +void ChromeBrowserHostImpl::OnWebContentsDestroyed( + content::WebContents* web_contents) { + platform_delegate_->WebContentsDestroyed(web_contents); DestroyBrowser(); } void ChromeBrowserHostImpl::OnSetFocus(cef_focus_source_t source) { - NOTIMPLEMENTED(); -} + if (!CEF_CURRENTLY_ON_UIT()) { + CEF_POST_TASK(CEF_UIT, base::BindOnce(&ChromeBrowserHostImpl::OnSetFocus, + this, source)); + return; + } -void ChromeBrowserHostImpl::ViewText(const std::string& text) { - NOTIMPLEMENTED(); + if (contents_delegate_->OnSetFocus(source)) + return; + + if (browser_) { + const int tab_index = GetCurrentTabIndex(); + if (tab_index != TabStripModel::kNoTab) { + chrome::SelectNumberedTab(browser_, tab_index); + } + } } void ChromeBrowserHostImpl::CloseBrowser(bool force_close) { - NOTIMPLEMENTED(); + // Always do this asynchronously because TabStripModel is not re-entrant. + CEF_POST_TASK(CEF_UIT, base::BindOnce(&ChromeBrowserHostImpl::DoCloseBrowser, + this, force_close)); } bool ChromeBrowserHostImpl::TryCloseBrowser() { @@ -129,7 +153,9 @@ bool ChromeBrowserHostImpl::TryCloseBrowser() { } void ChromeBrowserHostImpl::SetFocus(bool focus) { - NOTIMPLEMENTED(); + if (focus) { + OnSetFocus(FOCUS_SOURCE_SYSTEM); + } } CefWindowHandle ChromeBrowserHostImpl::GetWindowHandle() { @@ -143,7 +169,7 @@ CefWindowHandle ChromeBrowserHostImpl::GetOpenerWindowHandle() { } bool ChromeBrowserHostImpl::HasView() { - NOTIMPLEMENTED(); + // TODO(chrome-runtime): Support Views-hosted browsers. return false; } @@ -174,7 +200,12 @@ void ChromeBrowserHostImpl::Print() { } if (browser_) { - chrome::Print(browser_); + // Like chrome::Print() but specifying the WebContents. + printing::StartPrint(GetWebContents(), + /*print_renderer=*/mojo::NullAssociatedRemote(), + browser_->profile()->GetPrefs()->GetBoolean( + prefs::kPrintPreviewDisabled), + /*has_selection=*/false); } } @@ -267,28 +298,6 @@ void ChromeBrowserHostImpl::SendExternalBeginFrame() { NOTIMPLEMENTED(); } -void ChromeBrowserHostImpl::SendKeyEvent(const CefKeyEvent& event) { - NOTIMPLEMENTED(); -} - -void ChromeBrowserHostImpl::SendMouseClickEvent(const CefMouseEvent& event, - MouseButtonType type, - bool mouseUp, - int clickCount) { - NOTIMPLEMENTED(); -} - -void ChromeBrowserHostImpl::SendMouseMoveEvent(const CefMouseEvent& event, - bool mouseLeave) { - NOTIMPLEMENTED(); -} - -void ChromeBrowserHostImpl::SendMouseWheelEvent(const CefMouseEvent& event, - int deltaX, - int deltaY) { - NOTIMPLEMENTED(); -} - void ChromeBrowserHostImpl::SendTouchEvent(const CefTouchEvent& event) { NOTIMPLEMENTED(); } @@ -390,94 +399,56 @@ bool ChromeBrowserHostImpl::IsBackgroundHost() { return false; } -void ChromeBrowserHostImpl::GoBack() { - auto callback = base::BindOnce(&ChromeBrowserHostImpl::GoBack, this); - if (!CEF_CURRENTLY_ON_UIT()) { - CEF_POST_TASK(CEF_UIT, std::move(callback)); - } - - if (browser_info_->IsNavigationLocked(std::move(callback))) { - return; - } - - if (browser_ && chrome::CanGoBack(browser_)) { - chrome::GoBack(browser_, kDefaultWindowDisposition); - } -} - -void ChromeBrowserHostImpl::GoForward() { - auto callback = base::BindOnce(&ChromeBrowserHostImpl::GoForward, this); - if (!CEF_CURRENTLY_ON_UIT()) { - CEF_POST_TASK(CEF_UIT, std::move(callback)); - } - - if (browser_info_->IsNavigationLocked(std::move(callback))) { - return; - } - - if (browser_ && chrome::CanGoForward(browser_)) { - chrome::GoForward(browser_, kDefaultWindowDisposition); - } -} - -void ChromeBrowserHostImpl::Reload() { - auto callback = base::BindOnce(&ChromeBrowserHostImpl::Reload, this); - if (!CEF_CURRENTLY_ON_UIT()) { - CEF_POST_TASK(CEF_UIT, std::move(callback)); - } - - if (browser_info_->IsNavigationLocked(std::move(callback))) { - return; +bool ChromeBrowserHostImpl::Navigate(const content::OpenURLParams& params) { + CEF_REQUIRE_UIT(); + if (GetCurrentTabIndex() == TabStripModel::kNoTab) { + // We can't navigate via the Browser because we don't have a current tab. + return CefBrowserHostBase::Navigate(params); } if (browser_) { - chrome::Reload(browser_, kDefaultWindowDisposition); - } -} + // This is generally equivalent to calling Browser::OpenURL, except: + // 1. It doesn't trigger a call to CefRequestHandler::OnOpenURLFromTab, and + // 2. It navigates in this CefBrowserHost's WebContents instead of + // (a) creating a new WebContents, or (b) using the Browser's active + // WebContents (which may not be the same), and + // 3. There is no risk of triggering chrome's popup blocker. + NavigateParams nav_params(browser_, params.url, params.transition); + nav_params.FillNavigateParamsFromOpenURLParams(params); -void ChromeBrowserHostImpl::ReloadIgnoreCache() { - auto callback = - base::BindOnce(&ChromeBrowserHostImpl::ReloadIgnoreCache, this); - if (!CEF_CURRENTLY_ON_UIT()) { - CEF_POST_TASK(CEF_UIT, std::move(callback)); - } + // Always navigate in the current tab. + nav_params.disposition = WindowOpenDisposition::CURRENT_TAB; + nav_params.source_contents = GetWebContents(); - if (browser_info_->IsNavigationLocked(std::move(callback))) { - return; - } - - if (browser_) { - chrome::ReloadBypassingCache(browser_, kDefaultWindowDisposition); - } -} - -void ChromeBrowserHostImpl::StopLoad() { - auto callback = base::BindOnce(&ChromeBrowserHostImpl::StopLoad, this); - if (!CEF_CURRENTLY_ON_UIT()) { - CEF_POST_TASK(CEF_UIT, std::move(callback)); - } - - if (browser_info_->IsNavigationLocked(std::move(callback))) { - return; - } - - if (browser_) { - chrome::Stop(browser_); + nav_params.tabstrip_add_types = TabStripModel::ADD_NONE; + if (params.user_gesture) + nav_params.window_action = NavigateParams::SHOW_WINDOW; + ::Navigate(&nav_params); + return true; } + return false; } ChromeBrowserHostImpl::ChromeBrowserHostImpl( const CefBrowserSettings& settings, CefRefPtr client, + std::unique_ptr platform_delegate, scoped_refptr browser_info, CefRefPtr request_context) - : CefBrowserHostBase(settings, client, browser_info, request_context) {} + : CefBrowserHostBase(settings, + client, + std::move(platform_delegate), + browser_info, + request_context) {} void ChromeBrowserHostImpl::Attach(Browser* browser, content::WebContents* web_contents) { DCHECK(browser); DCHECK(web_contents); + platform_delegate_->WebContentsCreated(web_contents, + /*own_web_contents=*/false); + SetBrowser(browser); contents_delegate_->ObserveWebContents(web_contents); InitializeBrowser(); @@ -486,14 +457,22 @@ void ChromeBrowserHostImpl::Attach(Browser* browser, void ChromeBrowserHostImpl::SetBrowser(Browser* browser) { CEF_REQUIRE_UIT(); browser_ = browser; + static_cast(platform_delegate_.get()) + ->set_chrome_browser(browser); } void ChromeBrowserHostImpl::InitializeBrowser() { CEF_REQUIRE_UIT(); DCHECK(browser_); + // Associate the platform delegate with this browser. + platform_delegate_->BrowserCreated(this); + CefBrowserHostBase::InitializeBrowser(); + // The WebContents won't be added to the Browser's TabStripModel until later + // in the current call stack. Block navigation until that time. + auto navigation_lock = browser_info_->CreateNavigationLock(); OnAfterCreated(); } @@ -504,5 +483,29 @@ void ChromeBrowserHostImpl::DestroyBrowser() { OnBeforeClose(); OnBrowserDestroyed(); + // Disassociate the platform delegate from this browser. + platform_delegate_->BrowserDestroyed(this); + CefBrowserHostBase::DestroyBrowser(); } + +void ChromeBrowserHostImpl::DoCloseBrowser(bool force_close) { + CEF_REQUIRE_UIT(); + if (browser_) { + // Like chrome::CloseTab() but specifying the WebContents. + const int tab_index = GetCurrentTabIndex(); + if (tab_index != TabStripModel::kNoTab) { + browser_->tab_strip_model()->CloseWebContentsAt( + tab_index, TabStripModel::CLOSE_CREATE_HISTORICAL_TAB | + TabStripModel::CLOSE_USER_GESTURE); + } + } +} + +int ChromeBrowserHostImpl::GetCurrentTabIndex() const { + CEF_REQUIRE_UIT(); + if (browser_) { + return browser_->tab_strip_model()->GetIndexOfWebContents(GetWebContents()); + } + return TabStripModel::kNoTab; +} diff --git a/libcef/browser/chrome/chrome_browser_host_impl.h b/libcef/browser/chrome/chrome_browser_host_impl.h index 511151c8c..deeb86641 100644 --- a/libcef/browser/chrome/chrome_browser_host_impl.h +++ b/libcef/browser/chrome/chrome_browser_host_impl.h @@ -6,6 +6,8 @@ #define CEF_LIBCEF_BROWSER_CHROME_CHROME_BROWSER_HOST_IMPL_H_ #pragma once +#include + #include "libcef/browser/browser_host_base.h" #include "libcef/browser/chrome/browser_delegate.h" @@ -22,15 +24,16 @@ class ChromeBrowserHostImpl : public CefBrowserHostBase { // possibly shared by multiple Browser instances. class DelegateCreateParams : public cef::BrowserDelegate::CreateParams { public: - DelegateCreateParams(const CefBrowserHostBase::CreateParams& create_params) + DelegateCreateParams(const CefBrowserCreateParams& create_params) : create_params_(create_params) {} - CefBrowserHostBase::CreateParams create_params_; + CefBrowserCreateParams create_params_; }; // Create a new Browser with a single tab (WebContents) and associated // ChromeBrowserHostImpl instance. - static CefRefPtr Create(const CreateParams& params); + static CefRefPtr Create( + const CefBrowserCreateParams& params); // Returns the browser associated with the specified RenderViewHost. static CefRefPtr GetBrowserForHost( @@ -52,11 +55,10 @@ class ChromeBrowserHostImpl : public CefBrowserHostBase { ~ChromeBrowserHostImpl() override; // CefBrowserContentsDelegate::Observer methods: - void OnWebContentsDestroyed() override; + void OnWebContentsDestroyed(content::WebContents* web_contents) override; // CefBrowserHostBase methods called from CefFrameHostImpl: void OnSetFocus(cef_focus_source_t source) override; - void ViewText(const std::string& text) override; // CefBrowserHost methods: void CloseBrowser(bool force_close) override; @@ -103,15 +105,6 @@ class ChromeBrowserHostImpl : public CefBrowserHostBase { void NotifyScreenInfoChanged() override; void Invalidate(PaintElementType type) override; void SendExternalBeginFrame() override; - void SendKeyEvent(const CefKeyEvent& event) override; - void SendMouseClickEvent(const CefMouseEvent& event, - MouseButtonType type, - bool mouseUp, - int clickCount) override; - void SendMouseMoveEvent(const CefMouseEvent& event, bool mouseLeave) override; - void SendMouseWheelEvent(const CefMouseEvent& event, - int deltaX, - int deltaY) override; void SendTouchEvent(const CefTouchEvent& event) override; void SendFocusEvent(bool setFocus) override; void SendCaptureLostEvent() override; @@ -145,20 +138,18 @@ class ChromeBrowserHostImpl : public CefBrowserHostBase { CefRefPtr GetExtension() override; bool IsBackgroundHost() override; - // CefBrowser methods: - void GoBack() override; - void GoForward() override; - void Reload() override; - void ReloadIgnoreCache() override; - void StopLoad() override; + protected: + bool Navigate(const content::OpenURLParams& params) override; private: friend class ChromeBrowserDelegate; - ChromeBrowserHostImpl(const CefBrowserSettings& settings, - CefRefPtr client, - scoped_refptr browser_info, - CefRefPtr request_context); + ChromeBrowserHostImpl( + const CefBrowserSettings& settings, + CefRefPtr client, + std::unique_ptr platform_delegate, + scoped_refptr browser_info, + CefRefPtr request_context); // Called from ChromeBrowserDelegate::SetAsDelegate when this object is first // created. Must be called on the UI thread. @@ -173,6 +164,12 @@ class ChromeBrowserHostImpl : public CefBrowserHostBase { void InitializeBrowser() override; void DestroyBrowser() override; + void DoCloseBrowser(bool force_close); + + // Returns the current tab index for the associated WebContents, or + // TabStripModel::kNoTab if not found. + int GetCurrentTabIndex() const; + Browser* browser_ = nullptr; }; diff --git a/libcef/browser/chrome/chrome_browser_main_extra_parts_cef.cc b/libcef/browser/chrome/chrome_browser_main_extra_parts_cef.cc index 130600a89..2ad9760f6 100644 --- a/libcef/browser/chrome/chrome_browser_main_extra_parts_cef.cc +++ b/libcef/browser/chrome/chrome_browser_main_extra_parts_cef.cc @@ -21,7 +21,7 @@ void ChromeBrowserMainExtraPartsCef::PostProfileInit() { CefRequestContextImpl::CreateGlobalRequestContext(settings); } -void ChromeBrowserMainExtraPartsCef::PostMainMessageLoopRun() { +void ChromeBrowserMainExtraPartsCef::PreMainMessageLoopRun() { background_task_runner_ = base::CreateSingleThreadTaskRunner( {base::ThreadPool(), base::TaskPriority::BEST_EFFORT, base::TaskShutdownBehavior::BLOCK_SHUTDOWN, base::MayBlock()}); diff --git a/libcef/browser/chrome/chrome_browser_main_extra_parts_cef.h b/libcef/browser/chrome/chrome_browser_main_extra_parts_cef.h index 29ce5ba7c..acab49096 100644 --- a/libcef/browser/chrome/chrome_browser_main_extra_parts_cef.h +++ b/libcef/browser/chrome/chrome_browser_main_extra_parts_cef.h @@ -37,7 +37,7 @@ class ChromeBrowserMainExtraPartsCef : public ChromeBrowserMainExtraParts { private: // ChromeBrowserMainExtraParts overrides. void PostProfileInit() override; - void PostMainMessageLoopRun() override; + void PreMainMessageLoopRun() override; CefRefPtr global_request_context_; diff --git a/libcef/browser/chrome/chrome_content_browser_client_cef.cc b/libcef/browser/chrome/chrome_content_browser_client_cef.cc index 6ca2a33ff..1cfc3126b 100644 --- a/libcef/browser/chrome/chrome_content_browser_client_cef.cc +++ b/libcef/browser/chrome/chrome_content_browser_client_cef.cc @@ -5,14 +5,48 @@ #include "libcef/browser/chrome/chrome_content_browser_client_cef.h" +#include "libcef/browser/browser_info_manager.h" +#include "libcef/browser/browser_message_filter.h" #include "libcef/browser/chrome/chrome_browser_main_extra_parts_cef.h" +#include "libcef/browser/net/throttle_handler.h" +#include "libcef/browser/net_service/cookie_manager_impl.h" +#include "libcef/browser/net_service/login_delegate.h" +#include "libcef/browser/net_service/proxy_url_loader_factory.h" +#include "libcef/browser/net_service/resource_request_handler_wrapper.h" +#include "libcef/common/app_manager.h" #include "libcef/common/cef_switches.h" +#include "libcef/common/command_line_impl.h" #include "base/command_line.h" #include "base/path_service.h" #include "chrome/browser/chrome_browser_main.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_switches.h" +#include "content/public/browser/navigation_throttle.h" +#include "content/public/browser/render_process_host.h" +#include "content/public/common/content_switches.h" +#include "third_party/blink/public/mojom/loader/resource_load_info.mojom-shared.h" + +namespace { + +void HandleExternalProtocolHelper( + ChromeContentBrowserClientCef* self, + content::WebContents::OnceGetter web_contents_getter, + content::NavigationUIData* navigation_data, + const network::ResourceRequest& resource_request) { + // Match the logic of the original call in + // NavigationURLLoaderImpl::PrepareForNonInterceptedRequest. + self->HandleExternalProtocol( + resource_request.url, std::move(web_contents_getter), + content::ChildProcessHost::kInvalidUniqueID, navigation_data, + resource_request.resource_type == + static_cast(blink::mojom::ResourceType::kMainFrame), + static_cast(resource_request.transition_type), + resource_request.has_user_gesture, resource_request.request_initiator, + nullptr); +} + +} // namespace ChromeContentBrowserClientCef::ChromeContentBrowserClientCef( StartupData* startup_data) @@ -46,6 +80,199 @@ void ChromeContentBrowserClientCef::AppendExtraCommandLineSwitches( if (base::PathService::Get(chrome::DIR_USER_DATA, &user_data_dir)) { command_line->AppendSwitchPath(switches::kUserDataDir, user_data_dir); } + + const base::CommandLine* browser_cmd = base::CommandLine::ForCurrentProcess(); + + const std::string& process_type = + command_line->GetSwitchValueASCII(switches::kProcessType); + if (process_type == switches::kRendererProcess) { + // Propagate the following switches to the renderer command line (along with + // any associated values) if present in the browser command line. + static const char* const kSwitchNames[] = { + switches::kUncaughtExceptionStackSize, + }; + command_line->CopySwitchesFrom(*browser_cmd, kSwitchNames, + base::size(kSwitchNames)); + } + + CefRefPtr app = CefAppManager::Get()->GetApplication(); + if (app.get()) { + CefRefPtr handler = + app->GetBrowserProcessHandler(); + if (handler.get()) { + CefRefPtr commandLinePtr( + new CefCommandLineImpl(command_line, false, false)); + handler->OnBeforeChildProcessLaunch(commandLinePtr.get()); + commandLinePtr->Detach(nullptr); + } + } +} + +void ChromeContentBrowserClientCef::RenderProcessWillLaunch( + content::RenderProcessHost* 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. + host->RemoveObserver(CefBrowserInfoManager::GetInstance()); + host->AddObserver(CefBrowserInfoManager::GetInstance()); +} + +bool ChromeContentBrowserClientCef::CanCreateWindow( + content::RenderFrameHost* opener, + const GURL& opener_url, + const GURL& opener_top_level_frame_url, + const url::Origin& source_origin, + content::mojom::WindowContainerType container_type, + const GURL& target_url, + const content::Referrer& referrer, + const std::string& frame_name, + WindowOpenDisposition disposition, + const blink::mojom::WindowFeatures& features, + bool user_gesture, + bool opener_suppressed, + bool* no_javascript_access) { + // The chrome layer has popup blocker, extensions, etc. + if (!ChromeContentBrowserClient::CanCreateWindow( + opener, opener_url, opener_top_level_frame_url, source_origin, + container_type, target_url, referrer, frame_name, disposition, + features, user_gesture, opener_suppressed, no_javascript_access)) { + return false; + } + + return CefBrowserInfoManager::GetInstance()->CanCreateWindow( + opener, target_url, referrer, frame_name, disposition, features, + user_gesture, opener_suppressed, no_javascript_access); +} + +bool ChromeContentBrowserClientCef::WillCreateURLLoaderFactory( + content::BrowserContext* browser_context, + content::RenderFrameHost* frame, + int render_process_id, + URLLoaderFactoryType type, + const url::Origin& request_initiator, + base::Optional navigation_id, + mojo::PendingReceiver* factory_receiver, + mojo::PendingRemote* + header_client, + bool* bypass_redirect_checks, + bool* disable_secure_dns, + network::mojom::URLLoaderFactoryOverridePtr* factory_override) { + bool use_proxy = ChromeContentBrowserClient::WillCreateURLLoaderFactory( + browser_context, frame, render_process_id, type, request_initiator, + navigation_id, factory_receiver, header_client, bypass_redirect_checks, + disable_secure_dns, factory_override); + if (use_proxy) { + // The chrome layer will handle the request. + return use_proxy; + } + + auto request_handler = net_service::CreateInterceptedRequestHandler( + browser_context, frame, render_process_id, + type == URLLoaderFactoryType::kNavigation, + type == URLLoaderFactoryType::kDownload, request_initiator); + + net_service::ProxyURLLoaderFactory::CreateProxy( + browser_context, factory_receiver, header_client, + std::move(request_handler)); + return true; +} + +bool ChromeContentBrowserClientCef::HandleExternalProtocol( + const GURL& url, + content::WebContents::OnceGetter web_contents_getter, + int child_id, + content::NavigationUIData* navigation_data, + bool is_main_frame, + ui::PageTransition page_transition, + bool has_user_gesture, + const base::Optional& initiating_origin, + mojo::PendingRemote* out_factory) { + // |out_factory| will be non-nullptr when this method is initially called + // from NavigationURLLoaderImpl::PrepareForNonInterceptedRequest. + if (out_factory) { + // Let the other HandleExternalProtocol variant handle the request. + return false; + } + + // The request was unhandled and we've recieved a callback from + // HandleExternalProtocolHelper. Forward to the chrome layer for default + // handling. + return ChromeContentBrowserClient::HandleExternalProtocol( + url, std::move(web_contents_getter), child_id, navigation_data, + is_main_frame, page_transition, has_user_gesture, initiating_origin, + nullptr); +} + +bool ChromeContentBrowserClientCef::HandleExternalProtocol( + content::WebContents::Getter web_contents_getter, + int frame_tree_node_id, + content::NavigationUIData* navigation_data, + const network::ResourceRequest& resource_request, + mojo::PendingRemote* out_factory) { + mojo::PendingReceiver receiver = + out_factory->InitWithNewPipeAndPassReceiver(); + + // HandleExternalProtocolHelper may be called if nothing handles the request. + auto request_handler = net_service::CreateInterceptedRequestHandler( + web_contents_getter, frame_tree_node_id, resource_request, + base::Bind(HandleExternalProtocolHelper, base::Unretained(this), + web_contents_getter, navigation_data, resource_request)); + + net_service::ProxyURLLoaderFactory::CreateProxy( + web_contents_getter, std::move(receiver), std::move(request_handler)); + return true; +} + +std::vector> +ChromeContentBrowserClientCef::CreateThrottlesForNavigation( + content::NavigationHandle* navigation_handle) { + auto throttles = ChromeContentBrowserClient::CreateThrottlesForNavigation( + navigation_handle); + throttle::CreateThrottlesForNavigation(navigation_handle, throttles); + return throttles; +} + +void ChromeContentBrowserClientCef::ConfigureNetworkContextParams( + content::BrowserContext* context, + bool in_memory, + const base::FilePath& relative_partition_path, + network::mojom::NetworkContextParams* network_context_params, + network::mojom::CertVerifierCreationParams* cert_verifier_creation_params) { + ChromeContentBrowserClient::ConfigureNetworkContextParams( + context, in_memory, relative_partition_path, network_context_params, + cert_verifier_creation_params); + + auto cef_context = CefBrowserContext::FromBrowserContext(context); + network_context_params->cookieable_schemes = + cef_context ? cef_context->GetCookieableSchemes() + : CefCookieManagerImpl::GetGlobalCookieableSchemes(); +} + +std::unique_ptr +ChromeContentBrowserClientCef::CreateLoginDelegate( + const net::AuthChallengeInfo& auth_info, + content::WebContents* web_contents, + const content::GlobalRequestID& request_id, + bool is_request_for_main_frame, + const GURL& url, + scoped_refptr response_headers, + bool first_auth_attempt, + LoginAuthRequiredCallback auth_required_callback) { + // |web_contents| is nullptr for CefURLRequests without an associated frame. + if (!web_contents || base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kDisableChromeLoginPrompt)) { + // Delegate auth callbacks to GetAuthCredentials. + return std::make_unique( + auth_info, web_contents, request_id, url, + std::move(auth_required_callback)); + } + + return ChromeContentBrowserClient::CreateLoginDelegate( + auth_info, web_contents, request_id, is_request_for_main_frame, url, + response_headers, first_auth_attempt, std::move(auth_required_callback)); } CefRefPtr diff --git a/libcef/browser/chrome/chrome_content_browser_client_cef.h b/libcef/browser/chrome/chrome_content_browser_client_cef.h index f11178a01..1fd71b976 100644 --- a/libcef/browser/chrome/chrome_content_browser_client_cef.h +++ b/libcef/browser/chrome/chrome_content_browser_client_cef.h @@ -15,7 +15,7 @@ class ChromeBrowserMainExtraPartsCef; -// CEF override of ChromeContentBrowserClient +// CEF override of ChromeContentBrowserClient. class ChromeContentBrowserClientCef : public ChromeContentBrowserClient { public: explicit ChromeContentBrowserClientCef(StartupData* startup_data = nullptr); @@ -26,6 +26,70 @@ class ChromeContentBrowserClientCef : public ChromeContentBrowserClient { const content::MainFunctionParams& parameters) override; void AppendExtraCommandLineSwitches(base::CommandLine* command_line, int child_process_id) override; + void RenderProcessWillLaunch(content::RenderProcessHost* host) override; + bool CanCreateWindow(content::RenderFrameHost* opener, + const GURL& opener_url, + const GURL& opener_top_level_frame_url, + const url::Origin& source_origin, + content::mojom::WindowContainerType container_type, + const GURL& target_url, + const content::Referrer& referrer, + const std::string& frame_name, + WindowOpenDisposition disposition, + const blink::mojom::WindowFeatures& features, + bool user_gesture, + bool opener_suppressed, + bool* no_javascript_access) override; + bool WillCreateURLLoaderFactory( + content::BrowserContext* browser_context, + content::RenderFrameHost* frame, + int render_process_id, + URLLoaderFactoryType type, + const url::Origin& request_initiator, + base::Optional navigation_id, + mojo::PendingReceiver* factory_receiver, + mojo::PendingRemote* + header_client, + bool* bypass_redirect_checks, + bool* disable_secure_dns, + network::mojom::URLLoaderFactoryOverridePtr* factory_override) override; + bool HandleExternalProtocol( + const GURL& url, + content::WebContents::OnceGetter web_contents_getter, + int child_id, + content::NavigationUIData* navigation_data, + bool is_main_frame, + ui::PageTransition page_transition, + bool has_user_gesture, + const base::Optional& initiating_origin, + mojo::PendingRemote* out_factory) + override; + bool HandleExternalProtocol( + content::WebContents::Getter web_contents_getter, + int frame_tree_node_id, + content::NavigationUIData* navigation_data, + const network::ResourceRequest& request, + mojo::PendingRemote* out_factory) + override; + std::vector> + CreateThrottlesForNavigation( + content::NavigationHandle* navigation_handle) override; + void ConfigureNetworkContextParams( + content::BrowserContext* context, + bool in_memory, + const base::FilePath& relative_partition_path, + network::mojom::NetworkContextParams* network_context_params, + network::mojom::CertVerifierCreationParams* cert_verifier_creation_params) + override; + std::unique_ptr CreateLoginDelegate( + const net::AuthChallengeInfo& auth_info, + content::WebContents* web_contents, + const content::GlobalRequestID& request_id, + bool is_request_for_main_frame, + const GURL& url, + scoped_refptr response_headers, + bool first_auth_attempt, + LoginAuthRequiredCallback auth_required_callback) override; CefRefPtr request_context() const; diff --git a/libcef/browser/devtools/devtools_frontend.cc b/libcef/browser/devtools/devtools_frontend.cc index 2ed9f1976..93e6d2299 100644 --- a/libcef/browser/devtools/devtools_frontend.cc +++ b/libcef/browser/devtools/devtools_frontend.cc @@ -249,7 +249,7 @@ CefDevToolsFrontend* CefDevToolsFrontend::Show( new_settings.background_color = SK_ColorWHITE; } - CefBrowserHostBase::CreateParams create_params; + CefBrowserCreateParams create_params; if (!inspected_browser->IsViewsHosted()) create_params.window_info.reset(new CefWindowInfo(windowInfo)); create_params.client = client; diff --git a/libcef/browser/extensions/browser_platform_delegate_background.cc b/libcef/browser/extensions/browser_platform_delegate_background.cc index d3246d751..4b1252906 100644 --- a/libcef/browser/extensions/browser_platform_delegate_background.cc +++ b/libcef/browser/extensions/browser_platform_delegate_background.cc @@ -8,6 +8,7 @@ #include "libcef/browser/alloy/alloy_browser_host_impl.h" #include "libcef/browser/thread_util.h" +#include "libcef/features/runtime_checks.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/render_widget_host.h" @@ -15,6 +16,7 @@ CefBrowserPlatformDelegateBackground::CefBrowserPlatformDelegateBackground( std::unique_ptr native_delegate) : native_delegate_(std::move(native_delegate)) { + REQUIRE_ALLOY_RUNTIME(); native_delegate_->set_windowless_handler(this); } @@ -27,7 +29,8 @@ void CefBrowserPlatformDelegateBackground::CloseHostWindow() { // No host window, so continue browser destruction now. Do it asynchronously // so the call stack has a chance to unwind. CEF_POST_TASK(CEF_UIT, - base::Bind(&AlloyBrowserHostImpl::WindowDestroyed, browser_)); + base::Bind(&AlloyBrowserHostImpl::WindowDestroyed, + static_cast(browser_))); } CefWindowHandle CefBrowserPlatformDelegateBackground::GetHostWindowHandle() @@ -115,14 +118,6 @@ CefBrowserPlatformDelegateBackground::CreateMenuRunner() { return nullptr; } -bool CefBrowserPlatformDelegateBackground::IsWindowless() const { - return false; -} - -bool CefBrowserPlatformDelegateBackground::IsViewsHosted() const { - return false; -} - CefWindowHandle CefBrowserPlatformDelegateBackground::GetParentWindowHandle() const { return GetHostWindowHandle(); diff --git a/libcef/browser/extensions/browser_platform_delegate_background.h b/libcef/browser/extensions/browser_platform_delegate_background.h index 2aaf2a055..bd6226ea5 100644 --- a/libcef/browser/extensions/browser_platform_delegate_background.h +++ b/libcef/browser/extensions/browser_platform_delegate_background.h @@ -44,8 +44,6 @@ class CefBrowserPlatformDelegateBackground std::unique_ptr CreateJavaScriptDialogRunner() override; std::unique_ptr CreateMenuRunner() override; - bool IsWindowless() const override; - bool IsViewsHosted() const override; // CefBrowserPlatformDelegateNative::WindowlessHandler methods: CefWindowHandle GetParentWindowHandle() const override; diff --git a/libcef/browser/extensions/extension_function_details.cc b/libcef/browser/extensions/extension_function_details.cc index b72c89f20..001d2770b 100644 --- a/libcef/browser/extensions/extension_function_details.cc +++ b/libcef/browser/extensions/extension_function_details.cc @@ -365,7 +365,7 @@ base::DictionaryValue* CefExtensionFunctionDetails::OpenTab( if (!request_context) return nullptr; - CefBrowserHostBase::CreateParams create_params; + CefBrowserCreateParams create_params; create_params.url = url; create_params.request_context = request_context; create_params.window_info.reset(new CefWindowInfo); diff --git a/libcef/browser/extensions/extensions_browser_client.cc b/libcef/browser/extensions/extensions_browser_client.cc index 3d9c7109a..66cd67e19 100644 --- a/libcef/browser/extensions/extensions_browser_client.cc +++ b/libcef/browser/extensions/extensions_browser_client.cc @@ -250,7 +250,7 @@ bool CefExtensionsBrowserClient::CreateBackgroundExtensionHost( return true; } - CefBrowserHostBase::CreateParams create_params; + CefBrowserCreateParams create_params; create_params.url = url; create_params.request_context = request_context; diff --git a/libcef/browser/frame_host_impl.cc b/libcef/browser/frame_host_impl.cc index 589803d92..257096f0a 100644 --- a/libcef/browser/frame_host_impl.cc +++ b/libcef/browser/frame_host_impl.cc @@ -306,8 +306,7 @@ void CefFrameHostImpl::Navigate(const CefNavigateParams& params) { CefMsg_LoadRequest_Params request; request.url = params.url; if (!request.url.is_valid()) { - LOG(ERROR) << "Invalid URL passed to CefFrameHostImpl::Navigate: " - << params.url; + LOG(ERROR) << "Invalid URL: " << params.url; return; } @@ -337,14 +336,30 @@ void CefFrameHostImpl::LoadURLWithExtras(const std::string& url, if (frame_id < CefFrameHostImpl::kMainFrameId) return; + GURL gurl(url); + if (!gurl.is_valid() && !gurl.has_scheme()) { + // Try to add "http://" at the beginning. + std::string new_url = std::string("http://") + url; + gurl = GURL(new_url); + } + if (!gurl.is_valid()) { + LOG(ERROR) << "Invalid URL: " << url; + return; + } + if (frame_id == CefFrameHostImpl::kMainFrameId) { // Load via the browser using NavigationController. auto browser = GetBrowserHostBase(); if (browser) { - browser->LoadMainFrameURL(url, referrer, transition, extra_headers); + content::OpenURLParams params( + gurl, referrer, WindowOpenDisposition::CURRENT_TAB, transition, + /*is_renderer_initiated=*/false); + params.extra_headers = extra_headers; + + browser->LoadMainFrameURL(params); } } else { - CefNavigateParams params(GURL(url), transition); + CefNavigateParams params(gurl, transition); params.referrer = referrer; params.headers = extra_headers; Navigate(params); diff --git a/libcef/browser/native/browser_platform_delegate_native.cc b/libcef/browser/native/browser_platform_delegate_native.cc index 4fa440eba..6547a137b 100644 --- a/libcef/browser/native/browser_platform_delegate_native.cc +++ b/libcef/browser/native/browser_platform_delegate_native.cc @@ -22,15 +22,8 @@ SkColor CefBrowserPlatformDelegateNative::GetBackgroundColor() const { } void CefBrowserPlatformDelegateNative::WasResized() { - content::RenderViewHost* host = browser_->web_contents()->GetRenderViewHost(); - if (host) + content::RenderViewHost* host = web_contents_->GetRenderViewHost(); + if (host) { host->GetWidget()->SynchronizeVisualProperties(); -} - -bool CefBrowserPlatformDelegateNative::IsWindowless() const { - return false; -} - -bool CefBrowserPlatformDelegateNative::IsViewsHosted() const { - return false; + } } diff --git a/libcef/browser/native/browser_platform_delegate_native.h b/libcef/browser/native/browser_platform_delegate_native.h index 8f279a1a9..d3b47b1ec 100644 --- a/libcef/browser/native/browser_platform_delegate_native.h +++ b/libcef/browser/native/browser_platform_delegate_native.h @@ -28,8 +28,6 @@ class CefBrowserPlatformDelegateNative // CefBrowserPlatformDelegate methods: SkColor GetBackgroundColor() const override; void WasResized() override; - bool IsWindowless() const override; - bool IsViewsHosted() const override; // Translate CEF events to Chromium/Blink Web events. virtual content::NativeWebKeyboardEvent TranslateWebKeyEvent( @@ -52,6 +50,7 @@ class CefBrowserPlatformDelegateNative protected: // Delegates that can wrap a native delegate. friend class CefBrowserPlatformDelegateBackground; + friend class CefBrowserPlatformDelegateChrome; friend class CefBrowserPlatformDelegateOsr; friend class CefBrowserPlatformDelegateViews; @@ -61,6 +60,7 @@ class CefBrowserPlatformDelegateNative // Methods used by delegates that can wrap a native delegate. void set_windowless_handler(WindowlessHandler* handler) { windowless_handler_ = handler; + set_as_secondary(); } CefWindowInfo window_info_; diff --git a/libcef/browser/native/browser_platform_delegate_native_linux.cc b/libcef/browser/native/browser_platform_delegate_native_linux.cc index 843996fbc..29a9dd8d8 100644 --- a/libcef/browser/native/browser_platform_delegate_native_linux.cc +++ b/libcef/browser/native/browser_platform_delegate_native_linux.cc @@ -6,7 +6,7 @@ #include -#include "libcef/browser/alloy/alloy_browser_host_impl.h" +#include "libcef/browser/browser_host_base.h" #include "libcef/browser/context.h" #include "libcef/browser/native/menu_runner_linux.h" #include "libcef/browser/native/window_delegate_view.h" @@ -50,7 +50,7 @@ CefBrowserPlatformDelegateNativeLinux::CefBrowserPlatformDelegateNativeLinux( window_widget_(nullptr) {} void CefBrowserPlatformDelegateNativeLinux::BrowserDestroyed( - AlloyBrowserHostImpl* browser) { + CefBrowserHostBase* browser) { CefBrowserPlatformDelegateNative::BrowserDestroyed(browser); if (host_window_created_) { diff --git a/libcef/browser/native/browser_platform_delegate_native_linux.h b/libcef/browser/native/browser_platform_delegate_native_linux.h index b8a2ae5c6..ce724f682 100644 --- a/libcef/browser/native/browser_platform_delegate_native_linux.h +++ b/libcef/browser/native/browser_platform_delegate_native_linux.h @@ -19,7 +19,7 @@ class CefBrowserPlatformDelegateNativeLinux SkColor background_color); // CefBrowserPlatformDelegate methods: - void BrowserDestroyed(AlloyBrowserHostImpl* browser) override; + void BrowserDestroyed(CefBrowserHostBase* browser) override; bool CreateHostWindow() override; void CloseHostWindow() override; CefWindowHandle GetHostWindowHandle() const override; diff --git a/libcef/browser/native/browser_platform_delegate_native_mac.h b/libcef/browser/native/browser_platform_delegate_native_mac.h index f7a72e818..d0bfb68a6 100644 --- a/libcef/browser/native/browser_platform_delegate_native_mac.h +++ b/libcef/browser/native/browser_platform_delegate_native_mac.h @@ -19,7 +19,7 @@ class CefBrowserPlatformDelegateNativeMac SkColor background_color); // CefBrowserPlatformDelegate methods: - void BrowserDestroyed(AlloyBrowserHostImpl* browser) override; + void BrowserDestroyed(CefBrowserHostBase* browser) override; bool CreateHostWindow() override; void CloseHostWindow() override; CefWindowHandle GetHostWindowHandle() const override; diff --git a/libcef/browser/native/browser_platform_delegate_native_mac.mm b/libcef/browser/native/browser_platform_delegate_native_mac.mm index d35075524..814b5fd67 100644 --- a/libcef/browser/native/browser_platform_delegate_native_mac.mm +++ b/libcef/browser/native/browser_platform_delegate_native_mac.mm @@ -34,10 +34,10 @@ // the view is deleted. @interface CefBrowserHostView : NSView { @private - AlloyBrowserHostImpl* browser_; // weak + CefBrowserHostBase* browser_; // weak } -@property(nonatomic, assign) AlloyBrowserHostImpl* browser; +@property(nonatomic, assign) CefBrowserHostBase* browser; @end @@ -49,7 +49,7 @@ if (browser_) { // Force the browser to be destroyed and release the reference added in // PlatformCreateWindow(). - browser_->WindowDestroyed(); + static_cast(browser_)->WindowDestroyed(); } [super dealloc]; @@ -60,17 +60,15 @@ // Receives notifications from the browser window. Will delete itself when done. @interface CefWindowDelegate : NSObject { @private - AlloyBrowserHostImpl* browser_; // weak + CefBrowserHostBase* browser_; // weak NSWindow* window_; } -- (id)initWithWindow:(NSWindow*)window - andBrowser:(AlloyBrowserHostImpl*)browser; +- (id)initWithWindow:(NSWindow*)window andBrowser:(CefBrowserHostBase*)browser; @end @implementation CefWindowDelegate -- (id)initWithWindow:(NSWindow*)window - andBrowser:(AlloyBrowserHostImpl*)browser { +- (id)initWithWindow:(NSWindow*)window andBrowser:(CefBrowserHostBase*)browser { if (self = [super init]) { window_ = window; browser_ = browser; @@ -152,7 +150,7 @@ CefBrowserPlatformDelegateNativeMac::CefBrowserPlatformDelegateNativeMac( host_window_created_(false) {} void CefBrowserPlatformDelegateNativeMac::BrowserDestroyed( - AlloyBrowserHostImpl* browser) { + CefBrowserHostBase* browser) { CefBrowserPlatformDelegateNative::BrowserDestroyed(browser); if (host_window_created_) { diff --git a/libcef/browser/native/browser_platform_delegate_native_win.cc b/libcef/browser/native/browser_platform_delegate_native_win.cc index 04cba517a..a7653f481 100644 --- a/libcef/browser/native/browser_platform_delegate_native_win.cc +++ b/libcef/browser/native/browser_platform_delegate_native_win.cc @@ -127,12 +127,10 @@ float GetWindowScaleFactor(HWND hwnd) { CefBrowserPlatformDelegateNativeWin::CefBrowserPlatformDelegateNativeWin( const CefWindowInfo& window_info, SkColor background_color) - : CefBrowserPlatformDelegateNativeAura(window_info, background_color), - host_window_created_(false), - window_widget_(nullptr) {} + : CefBrowserPlatformDelegateNativeAura(window_info, background_color) {} void CefBrowserPlatformDelegateNativeWin::BrowserDestroyed( - AlloyBrowserHostImpl* browser) { + CefBrowserHostBase* browser) { CefBrowserPlatformDelegateNative::BrowserDestroyed(browser); if (host_window_created_) { @@ -530,13 +528,14 @@ LRESULT CALLBACK CefBrowserPlatformDelegateNativeWin::WndProc(HWND hwnd, WPARAM wParam, LPARAM lParam) { CefBrowserPlatformDelegateNativeWin* platform_delegate = nullptr; - AlloyBrowserHostImpl* browser = nullptr; + CefBrowserHostBase* browser = nullptr; if (message != WM_NCCREATE) { platform_delegate = static_cast( gfx::GetWindowUserData(hwnd)); - if (platform_delegate) + if (platform_delegate) { browser = platform_delegate->browser_; + } } switch (message) { @@ -582,7 +581,7 @@ LRESULT CALLBACK CefBrowserPlatformDelegateNativeWin::WndProc(HWND hwnd, // Force the browser to be destroyed. This will result in a call to // BrowserDestroyed() that will release the reference added in // CreateHostWindow(). - browser->WindowDestroyed(); + static_cast(browser)->WindowDestroyed(); } break; diff --git a/libcef/browser/native/browser_platform_delegate_native_win.h b/libcef/browser/native/browser_platform_delegate_native_win.h index 9c8e33ffa..a0cdcf3e8 100644 --- a/libcef/browser/native/browser_platform_delegate_native_win.h +++ b/libcef/browser/native/browser_platform_delegate_native_win.h @@ -17,7 +17,7 @@ class CefBrowserPlatformDelegateNativeWin SkColor background_color); // CefBrowserPlatformDelegate methods: - void BrowserDestroyed(AlloyBrowserHostImpl* browser) override; + void BrowserDestroyed(CefBrowserHostBase* browser) override; bool CreateHostWindow() override; void CloseHostWindow() override; CefWindowHandle GetHostWindowHandle() const override; @@ -52,11 +52,11 @@ class CefBrowserPlatformDelegateNativeWin LPARAM lParam); // True if the host window has been created. - bool host_window_created_; + bool host_window_created_ = false; // Widget hosting the web contents. It will be deleted automatically when the // associated root window is destroyed. - views::Widget* window_widget_; + views::Widget* window_widget_ = nullptr; bool has_frame_ = false; bool called_enable_non_client_dpi_scaling_ = false; diff --git a/libcef/browser/native/window_x11.cc b/libcef/browser/native/window_x11.cc index 20e4e176e..241728336 100644 --- a/libcef/browser/native/window_x11.cc +++ b/libcef/browser/native/window_x11.cc @@ -9,6 +9,8 @@ #include #include +#include "libcef/browser/alloy/alloy_browser_host_impl.h" +#include "libcef/browser/browser_host_base.h" #include "libcef/browser/thread_util.h" #include "ui/base/x/x11_util.h" @@ -92,7 +94,7 @@ CEF_EXPORT XDisplay* cef_get_xdisplay() { return gfx::GetXDisplay(); } -CefWindowX11::CefWindowX11(CefRefPtr browser, +CefWindowX11::CefWindowX11(CefRefPtr browser, ::Window parent_xwindow, const gfx::Rect& bounds, const std::string& title) @@ -412,10 +414,11 @@ void CefWindowX11::ProcessXEvent(x11::Event* event) { xwindow_ = x11::None; - if (browser_.get()) { + if (browser_) { // Force the browser to be destroyed and release the reference // added in PlatformCreateWindow(). - browser_->WindowDestroyed(); + static_cast(browser_.get()) + ->WindowDestroyed(); } delete this; diff --git a/libcef/browser/native/window_x11.h b/libcef/browser/native/window_x11.h index 668009496..559e27804 100644 --- a/libcef/browser/native/window_x11.h +++ b/libcef/browser/native/window_x11.h @@ -12,7 +12,7 @@ typedef unsigned long Window; struct _XDisplay; typedef struct _XDisplay Display; -#include "libcef/browser/alloy/alloy_browser_host_impl.h" +#include "include/internal/cef_ptr.h" #include "base/memory/weak_ptr.h" #include "ui/events/platform/platform_event_dispatcher.h" @@ -24,12 +24,14 @@ namespace views { class DesktopWindowTreeHostLinux; } +class CefBrowserHostBase; + // Object wrapper for an X11 Window. // Based on WindowTreeHostX11 and DesktopWindowTreeHostX11. class CefWindowX11 : public ui::PlatformEventDispatcher, public ui::XEventDispatcher { public: - CefWindowX11(CefRefPtr browser, + CefWindowX11(CefRefPtr browser, ::Window parent_xwindow, const gfx::Rect& bounds, const std::string& title); @@ -69,7 +71,7 @@ class CefWindowX11 : public ui::PlatformEventDispatcher, bool IsTargetedBy(const x11::Event& x11_event) const; void ProcessXEvent(x11::Event* xev); - CefRefPtr browser_; + CefRefPtr browser_; // The display and the native X window hosting the root window. ::Display* xdisplay_; diff --git a/libcef/browser/net/throttle_handler.cc b/libcef/browser/net/throttle_handler.cc new file mode 100644 index 000000000..c9f3091de --- /dev/null +++ b/libcef/browser/net/throttle_handler.cc @@ -0,0 +1,116 @@ +// Copyright 2020 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/net/throttle_handler.h" + +#include "libcef/browser/browser_host_base.h" +#include "libcef/browser/browser_info_manager.h" +#include "libcef/browser/frame_host_impl.h" +#include "libcef/common/request_impl.h" + +#include "components/navigation_interception/intercept_navigation_throttle.h" +#include "components/navigation_interception/navigation_params.h" +#include "content/public/browser/navigation_handle.h" +#include "content/public/browser/navigation_throttle.h" +#include "content/public/browser/page_navigator.h" + +namespace throttle { + +namespace { + +// TODO(cef): We can't currently trust NavigationParams::is_main_frame() because +// it's always set to true in +// InterceptNavigationThrottle::CheckIfShouldIgnoreNavigation. Remove the +// |is_main_frame| argument once this problem is fixed. +bool NavigationOnUIThread( + bool is_main_frame, + int64_t frame_id, + int64_t parent_frame_id, + int frame_tree_node_id, + content::WebContents* source, + const navigation_interception::NavigationParams& params) { + CEF_REQUIRE_UIT(); + + content::OpenURLParams open_params( + params.url(), params.referrer(), WindowOpenDisposition::CURRENT_TAB, + params.transition_type(), params.is_renderer_initiated()); + open_params.user_gesture = params.has_user_gesture(); + open_params.initiator_origin = params.initiator_origin(); + + CefRefPtr browser; + if (!CefBrowserInfoManager::GetInstance()->MaybeAllowNavigation( + source->GetMainFrame(), open_params, browser)) { + // Cancel the navigation. + return true; + } + + bool ignore_navigation = false; + + if (browser) { + if (auto client = browser->GetClient()) { + if (auto handler = client->GetRequestHandler()) { + CefRefPtr frame; + if (is_main_frame) { + frame = browser->GetMainFrame(); + } else if (frame_id >= 0) { + frame = browser->GetFrame(frame_id); + } + if (!frame && frame_tree_node_id >= 0) { + frame = browser->GetFrameForFrameTreeNode(frame_tree_node_id); + } + if (!frame) { + // Create a temporary frame object for navigation of sub-frames that + // don't yet exist. + frame = browser->browser_info()->CreateTempSubFrame(parent_frame_id); + } + + CefRefPtr request = new CefRequestImpl(); + request->Set(params, is_main_frame); + request->SetReadOnly(true); + + // Initiating a new navigation in OnBeforeBrowse will delete the + // InterceptNavigationThrottle that currently owns this callback, + // resulting in a crash. Use the lock to prevent that. + auto navigation_lock = browser->browser_info()->CreateNavigationLock(); + ignore_navigation = handler->OnBeforeBrowse( + browser.get(), frame, request.get(), params.has_user_gesture(), + params.is_redirect()); + } + } + } + + return ignore_navigation; +} + +} // namespace + +void CreateThrottlesForNavigation(content::NavigationHandle* navigation_handle, + NavigationThrottleList& throttles) { + CEF_REQUIRE_UIT(); + + const bool is_main_frame = navigation_handle->IsInMainFrame(); + + // Identify the RenderFrameHost that originated the navigation. + const int64_t parent_frame_id = + !is_main_frame + ? CefFrameHostImpl::MakeFrameId(navigation_handle->GetParentFrame()) + : CefFrameHostImpl::kInvalidFrameId; + + const int64_t frame_id = !is_main_frame && navigation_handle->HasCommitted() + ? CefFrameHostImpl::MakeFrameId( + navigation_handle->GetRenderFrameHost()) + : CefFrameHostImpl::kInvalidFrameId; + + // Must use SynchronyMode::kSync to ensure that OnBeforeBrowse is always + // called before OnBeforeResourceLoad. + std::unique_ptr throttle = + std::make_unique( + navigation_handle, + base::Bind(&NavigationOnUIThread, is_main_frame, frame_id, + parent_frame_id, navigation_handle->GetFrameTreeNodeId()), + navigation_interception::SynchronyMode::kSync); + throttles.push_back(std::move(throttle)); +} + +} // namespace throttle diff --git a/libcef/browser/net/throttle_handler.h b/libcef/browser/net/throttle_handler.h new file mode 100644 index 000000000..5810fb4ff --- /dev/null +++ b/libcef/browser/net/throttle_handler.h @@ -0,0 +1,27 @@ +// Copyright 2020 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_NET_THROTTLE_HANDLER_H_ +#define CEF_LIBCEF_BROWSER_NET_THROTTLE_HANDLER_H_ +#pragma once + +#include +#include + +namespace content { +class NavigationHandle; +class NavigationThrottle; +} // namespace content + +namespace throttle { + +using NavigationThrottleList = + std::vector>; + +void CreateThrottlesForNavigation(content::NavigationHandle* navigation_handle, + NavigationThrottleList& throttles); + +} // namespace throttle + +#endif // CEF_LIBCEF_BROWSER_NET_THROTTLE_HANDLER_H_ diff --git a/libcef/browser/net_service/cookie_manager_impl.cc b/libcef/browser/net_service/cookie_manager_impl.cc index 89dd40f77..ad5276671 100644 --- a/libcef/browser/net_service/cookie_manager_impl.cc +++ b/libcef/browser/net_service/cookie_manager_impl.cc @@ -4,11 +4,13 @@ #include "libcef/browser/net_service/cookie_manager_impl.h" +#include "libcef/common/app_manager.h" #include "libcef/common/net_service/net_service_util.h" #include "libcef/common/time_util.h" #include "base/bind.h" #include "base/logging.h" +#include "base/no_destructor.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/storage_partition.h" #include "services/network/public/mojom/cookie_manager.mojom.h" @@ -115,6 +117,25 @@ void GetCookiesCallbackImpl( GetAllCookiesCallbackImpl(visitor, browser_context_getter, cookies); } +CefCookieManagerImpl::CookieableSchemes MakeSupportedSchemes( + const std::vector& schemes, + bool include_defaults) { + std::vector all_schemes; + for (const auto& scheme : schemes) + all_schemes.push_back(scheme); + + if (include_defaults) { + // Add default schemes that should always support cookies. + // This list should match CookieMonster::kDefaultCookieableSchemes. + all_schemes.push_back("http"); + all_schemes.push_back("https"); + all_schemes.push_back("ws"); + all_schemes.push_back("wss"); + } + + return base::make_optional(all_schemes); +} + } // namespace CefCookieManagerImpl::CefCookieManagerImpl() {} @@ -140,19 +161,6 @@ void CefCookieManagerImpl::SetSupportedSchemes( return; } - std::vector all_schemes; - for (const auto& scheme : schemes) - all_schemes.push_back(scheme); - - if (include_defaults) { - // Add default schemes that should always support cookies. - // This list should match CookieMonster::kDefaultCookieableSchemes. - all_schemes.push_back("http"); - all_schemes.push_back("https"); - all_schemes.push_back("ws"); - all_schemes.push_back("wss"); - } - auto browser_context = GetBrowserContext(browser_context_getter_); if (!browser_context) return; @@ -160,7 +168,8 @@ void CefCookieManagerImpl::SetSupportedSchemes( // This will be forwarded to the CookieMonster that lives in the // NetworkService process when the NetworkContext is created via // AlloyContentBrowserClient::CreateNetworkContext. - browser_context->set_cookieable_schemes(base::make_optional(all_schemes)); + browser_context->set_cookieable_schemes( + MakeSupportedSchemes(schemes, include_defaults)); RunAsyncCompletionOnUIThread(callback); } @@ -343,6 +352,26 @@ bool CefCookieManagerImpl::FlushStore( return true; } +// static +CefCookieManagerImpl::CookieableSchemes +CefCookieManagerImpl::GetGlobalCookieableSchemes() { + CEF_REQUIRE_UIT(); + + static base::NoDestructor schemes( + []() -> CefCookieManagerImpl::CookieableSchemes { + if (auto application = CefAppManager::Get()->GetApplication()) { + if (auto handler = application->GetBrowserProcessHandler()) { + std::vector schemes; + bool include_defaults = true; + handler->GetCookieableSchemes(schemes, include_defaults); + return MakeSupportedSchemes(schemes, include_defaults); + } + } + return base::nullopt; + }()); + return *schemes; +} + // CefCookieManager methods ---------------------------------------------------- // static diff --git a/libcef/browser/net_service/cookie_manager_impl.h b/libcef/browser/net_service/cookie_manager_impl.h index 19eff86d8..c9a53b550 100644 --- a/libcef/browser/net_service/cookie_manager_impl.h +++ b/libcef/browser/net_service/cookie_manager_impl.h @@ -38,6 +38,9 @@ class CefCookieManagerImpl : public CefCookieManager { CefRefPtr callback) override; bool FlushStore(CefRefPtr callback) override; + using CookieableSchemes = base::Optional>; + static CookieableSchemes GetGlobalCookieableSchemes(); + private: // Only accessed on the UI thread. Will be non-null after Initialize(). CefBrowserContext::Getter browser_context_getter_; diff --git a/libcef/browser/net_service/login_delegate.cc b/libcef/browser/net_service/login_delegate.cc index 39e4fad07..3aeeb380f 100644 --- a/libcef/browser/net_service/login_delegate.cc +++ b/libcef/browser/net_service/login_delegate.cc @@ -4,7 +4,7 @@ #include "libcef/browser/net_service/login_delegate.h" -#include "libcef/browser/alloy/alloy_browser_host_impl.h" +#include "libcef/browser/browser_host_base.h" #include "libcef/browser/net_service/browser_urlrequest_impl.h" #include "libcef/browser/thread_util.h" @@ -67,7 +67,7 @@ class AuthCallbackImpl : public CefAuthCallback { }; void RunCallbackOnIOThread( - CefRefPtr browser, + CefRefPtr browser, base::Optional url_request_info, const net::AuthChallengeInfo& auth_info, const GURL& origin_url, @@ -119,9 +119,9 @@ LoginDelegate::LoginDelegate(const net::AuthChallengeInfo& auth_info, CEF_REQUIRE_UIT(); // May be nullptr for requests originating from CefURLRequest. - CefRefPtr browser; + CefRefPtr browser; if (web_contents) { - browser = AlloyBrowserHostImpl::GetBrowserForContents(web_contents); + browser = CefBrowserHostBase::GetBrowserForContents(web_contents); } // |callback| needs to be executed asynchronously. @@ -146,7 +146,7 @@ void LoginDelegate::Cancel() { } } -void LoginDelegate::Start(CefRefPtr browser, +void LoginDelegate::Start(CefRefPtr browser, const net::AuthChallengeInfo& auth_info, const content::GlobalRequestID& request_id, const GURL& origin_url) { diff --git a/libcef/browser/net_service/login_delegate.h b/libcef/browser/net_service/login_delegate.h index 7c6b70e36..8732ea7b1 100644 --- a/libcef/browser/net_service/login_delegate.h +++ b/libcef/browser/net_service/login_delegate.h @@ -17,7 +17,7 @@ struct GlobalRequestID; class WebContents; } // namespace content -class AlloyBrowserHostImpl; +class CefBrowserHostBase; class GURL; namespace net_service { @@ -36,7 +36,7 @@ class LoginDelegate : public content::LoginDelegate { void Cancel(); private: - void Start(CefRefPtr browser, + void Start(CefRefPtr browser, const net::AuthChallengeInfo& auth_info, const content::GlobalRequestID& request_id, const GURL& origin_url); diff --git a/libcef/browser/net_service/proxy_url_loader_factory.cc b/libcef/browser/net_service/proxy_url_loader_factory.cc index 506a03862..b6e33dc45 100644 --- a/libcef/browser/net_service/proxy_url_loader_factory.cc +++ b/libcef/browser/net_service/proxy_url_loader_factory.cc @@ -52,6 +52,15 @@ bool IsOutOfBlinkCorsEnabled() { return !!state; } +void CreateProxyHelper( + content::WebContents::Getter web_contents_getter, + mojo::PendingReceiver loader_receiver, + std::unique_ptr request_handler) { + ProxyURLLoaderFactory::CreateProxy(web_contents_getter, + std::move(loader_receiver), + std::move(request_handler)); +} + } // namespace // Owns all of the ProxyURLLoaderFactorys for a given BrowserContext. Since @@ -1270,13 +1279,20 @@ void ProxyURLLoaderFactory::CreateProxy( } // static -ProxyURLLoaderFactory* ProxyURLLoaderFactory::CreateProxy( +void ProxyURLLoaderFactory::CreateProxy( content::WebContents::Getter web_contents_getter, mojo::PendingReceiver loader_receiver, std::unique_ptr request_handler) { - CEF_REQUIRE_IOT(); DCHECK(request_handler); + if (!CEF_CURRENTLY_ON_IOT()) { + CEF_POST_TASK( + CEF_IOT, + base::BindOnce(CreateProxyHelper, web_contents_getter, + std::move(loader_receiver), std::move(request_handler))); + return; + } + auto proxy = new ProxyURLLoaderFactory( std::move(loader_receiver), nullptr, mojo::PendingReceiver(), @@ -1284,7 +1300,6 @@ ProxyURLLoaderFactory* ProxyURLLoaderFactory::CreateProxy( CEF_POST_TASK(CEF_UIT, base::BindOnce(ResourceContextData::AddProxyOnUIThread, base::Unretained(proxy), web_contents_getter)); - return proxy; } void ProxyURLLoaderFactory::CreateLoaderAndStart( diff --git a/libcef/browser/net_service/proxy_url_loader_factory.h b/libcef/browser/net_service/proxy_url_loader_factory.h index f556f12c1..5973e9999 100644 --- a/libcef/browser/net_service/proxy_url_loader_factory.h +++ b/libcef/browser/net_service/proxy_url_loader_factory.h @@ -144,7 +144,7 @@ class ProxyURLLoaderFactory std::unique_ptr request_handler); // Create a proxy object on the IO thread. - static ProxyURLLoaderFactory* CreateProxy( + static void CreateProxy( content::WebContents::Getter web_contents_getter, mojo::PendingReceiver loader_request, std::unique_ptr request_handler); diff --git a/libcef/browser/net_service/resource_request_handler_wrapper.cc b/libcef/browser/net_service/resource_request_handler_wrapper.cc index 2631b0850..99a57af58 100644 --- a/libcef/browser/net_service/resource_request_handler_wrapper.cc +++ b/libcef/browser/net_service/resource_request_handler_wrapper.cc @@ -5,7 +5,6 @@ #include "libcef/browser/net_service/resource_request_handler_wrapper.h" #include "libcef/browser/browser_host_base.h" -#include "libcef/browser/browser_platform_delegate.h" #include "libcef/browser/context.h" #include "libcef/browser/iothread_state.h" #include "libcef/browser/net_service/cookie_helper.h" @@ -256,7 +255,8 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler { int frame_tree_node_id, bool is_navigation, bool is_download, - const url::Origin& request_initiator) { + const url::Origin& request_initiator, + const base::Closure& unhandled_request_callback) { CEF_REQUIRE_UIT(); browser_context_ = browser_context; @@ -264,7 +264,7 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler { CefBrowserContext::FromBrowserContext(browser_context); iothread_state_ = cef_browser_context->iothread_state(); DCHECK(iothread_state_); - cookieable_schemes_ = cef_browser_context->cookieable_schemes(); + cookieable_schemes_ = cef_browser_context->GetCookieableSchemes(); // We register to be notified of CEF context or browser destruction so // that we can stop accepting new requests and cancel pending/in-progress @@ -284,6 +284,7 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler { is_navigation_ = is_navigation; is_download_ = is_download; request_initiator_ = request_initiator.Serialize(); + unhandled_request_callback_ = unhandled_request_callback; // Default values for standard headers. accept_language_ = ComputeAcceptLanguageFromPref( @@ -320,6 +321,7 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler { bool is_navigation_ = true; bool is_download_ = false; CefString request_initiator_; + base::Closure unhandled_request_callback_; // Default values for standard headers. std::string accept_language_; @@ -996,13 +998,14 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler { CallHandlerOnComplete(state, status); - if (status.error_code != 0 && is_external) { + if (status.error_code != 0 && status.error_code != ERR_ABORTED && + is_external) { bool allow_os_execution = false; state->handler_->OnProtocolExecution( init_state_->browser_, init_state_->frame_, state->pending_request_.get(), allow_os_execution); - if (allow_os_execution) { - CefBrowserPlatformDelegate::HandleExternalProtocol(request.url); + if (allow_os_execution && init_state_->unhandled_request_callback_) { + init_state_->unhandled_request_callback_.Run(); } } } @@ -1197,7 +1200,8 @@ void InitOnUIThread( scoped_refptr init_helper, content::WebContents::Getter web_contents_getter, int frame_tree_node_id, - const network::ResourceRequest& request) { + const network::ResourceRequest& request, + const base::Closure& unhandled_request_callback) { CEF_REQUIRE_UIT(); // May return nullptr if the WebContents was destroyed while this callback was @@ -1267,7 +1271,7 @@ void InitOnUIThread( init_state->Initialize(browser_context, browserPtr, framePtr, render_process_id, request.render_frame_id, frame_tree_node_id, is_navigation, is_download, - request_initiator); + request_initiator, unhandled_request_callback); init_helper->MaybeSetInitialized(std::move(init_state)); } @@ -1304,7 +1308,8 @@ std::unique_ptr CreateInterceptedRequestHandler( std::make_unique(); init_state->Initialize(browser_context, browserPtr, framePtr, render_process_id, render_frame_id, frame_tree_node_id, - is_navigation, is_download, request_initiator); + is_navigation, is_download, request_initiator, + base::Closure()); auto wrapper = std::make_unique(); wrapper->init_helper()->MaybeSetInitialized(std::move(init_state)); @@ -1315,11 +1320,12 @@ std::unique_ptr CreateInterceptedRequestHandler( std::unique_ptr CreateInterceptedRequestHandler( content::WebContents::Getter web_contents_getter, int frame_tree_node_id, - const network::ResourceRequest& request) { + const network::ResourceRequest& request, + const base::Closure& unhandled_request_callback) { auto wrapper = std::make_unique(); CEF_POST_TASK(CEF_UIT, base::BindOnce(InitOnUIThread, wrapper->init_helper(), web_contents_getter, frame_tree_node_id, - request)); + request, unhandled_request_callback)); return wrapper; } diff --git a/libcef/browser/net_service/resource_request_handler_wrapper.h b/libcef/browser/net_service/resource_request_handler_wrapper.h index 4ed933a20..52d2b2792 100644 --- a/libcef/browser/net_service/resource_request_handler_wrapper.h +++ b/libcef/browser/net_service/resource_request_handler_wrapper.h @@ -5,6 +5,7 @@ #ifndef CEF_LIBCEF_BROWSER_NET_SERVICE_RESOURCE_REQUEST_HANDLER_WRAPPER_H_ #define CEF_LIBCEF_BROWSER_NET_SERVICE_RESOURCE_REQUEST_HANDLER_WRAPPER_H_ +#include "base/callback_forward.h" #include "content/public/browser/web_contents.h" namespace content { @@ -41,7 +42,8 @@ std::unique_ptr CreateInterceptedRequestHandler( std::unique_ptr CreateInterceptedRequestHandler( content::WebContents::Getter web_contents_getter, int frame_tree_node_id, - const network::ResourceRequest& request); + const network::ResourceRequest& request, + const base::Closure& unhandled_request_callback); } // namespace net_service diff --git a/libcef/browser/osr/browser_platform_delegate_osr.cc b/libcef/browser/osr/browser_platform_delegate_osr.cc index ebe46ba0c..c7293666c 100644 --- a/libcef/browser/osr/browser_platform_delegate_osr.cc +++ b/libcef/browser/osr/browser_platform_delegate_osr.cc @@ -6,7 +6,6 @@ #include -#include "libcef/browser/alloy/alloy_browser_host_impl.h" #include "libcef/browser/image_impl.h" #include "libcef/browser/osr/osr_accessibility_util.h" #include "libcef/browser/osr/render_widget_host_view_osr.h" @@ -60,26 +59,25 @@ void CefBrowserPlatformDelegateOsr::RenderViewCreated( } void CefBrowserPlatformDelegateOsr::BrowserCreated( - AlloyBrowserHostImpl* browser) { + CefBrowserHostBase* browser) { CefBrowserPlatformDelegateAlloy::BrowserCreated(browser); if (browser->IsPopup()) { // Associate the RenderWidget host view with the browser now because the // browser wasn't known at the time that the host view was created. - content::RenderViewHost* host = - browser->web_contents()->GetRenderViewHost(); + content::RenderViewHost* host = web_contents_->GetRenderViewHost(); DCHECK(host); CefRenderWidgetHostViewOSR* view = static_cast(host->GetWidget()->GetView()); // |view| will be null if the popup is a DevTools window. - if (view) - view->set_browser_impl(browser); + if (view) { + view->set_browser_impl(static_cast(browser)); + } } } void CefBrowserPlatformDelegateOsr::NotifyBrowserDestroyed() { - content::WebContents* web_contents = browser_->web_contents(); - content::RenderViewHost* host = web_contents->GetRenderViewHost(); + content::RenderViewHost* host = web_contents_->GetRenderViewHost(); if (host) { CefRenderWidgetHostViewOSR* view = static_cast(host->GetWidget()->GetView()); @@ -92,7 +90,7 @@ void CefBrowserPlatformDelegateOsr::NotifyBrowserDestroyed() { } void CefBrowserPlatformDelegateOsr::BrowserDestroyed( - AlloyBrowserHostImpl* browser) { + CefBrowserHostBase* browser) { CefBrowserPlatformDelegateAlloy::BrowserDestroyed(browser); view_osr_ = nullptr; @@ -215,14 +213,10 @@ bool CefBrowserPlatformDelegateOsr::IsWindowless() const { return true; } -bool CefBrowserPlatformDelegateOsr::IsViewsHosted() const { - return false; -} - void CefBrowserPlatformDelegateOsr::WasHidden(bool hidden) { // The WebContentsImpl will notify the OSR view. content::WebContentsImpl* web_contents = - static_cast(browser_->web_contents()); + static_cast(web_contents_); if (web_contents) { if (hidden) web_contents->WasHidden(); @@ -294,7 +288,7 @@ void CefBrowserPlatformDelegateOsr::DragTargetDragEnter( const CefMouseEvent& event, cef_drag_operations_mask_t allowed_ops) { content::WebContentsImpl* web_contents = - static_cast(browser_->web_contents()); + static_cast(web_contents_); if (!web_contents) return; @@ -342,7 +336,7 @@ void CefBrowserPlatformDelegateOsr::DragTargetDragOver( return; content::WebContentsImpl* web_contents = - static_cast(browser_->web_contents()); + static_cast(web_contents_); if (!web_contents) return; @@ -391,7 +385,7 @@ void CefBrowserPlatformDelegateOsr::DragTargetDragOver( } void CefBrowserPlatformDelegateOsr::DragTargetDragLeave() { - if (current_rvh_for_drag_ != browser_->web_contents()->GetRenderViewHost() || + if (current_rvh_for_drag_ != web_contents_->GetRenderViewHost() || !drag_data_) { return; } @@ -409,7 +403,7 @@ void CefBrowserPlatformDelegateOsr::DragTargetDrop(const CefMouseEvent& event) { return; content::WebContentsImpl* web_contents = - static_cast(browser_->web_contents()); + static_cast(web_contents_); if (!web_contents) return; @@ -511,7 +505,7 @@ void CefBrowserPlatformDelegateOsr::DragSourceEndedAt( return; content::WebContentsImpl* web_contents = - static_cast(browser_->web_contents()); + static_cast(web_contents_); if (!web_contents) return; @@ -552,7 +546,7 @@ void CefBrowserPlatformDelegateOsr::DragSourceSystemDragEnded() { return; content::WebContentsImpl* web_contents = - static_cast(browser_->web_contents()); + static_cast(web_contents_); if (!web_contents) return; @@ -600,14 +594,13 @@ gfx::Point CefBrowserPlatformDelegateOsr::GetParentScreenPoint( CefRenderWidgetHostViewOSR* CefBrowserPlatformDelegateOsr::GetOSRHostView() const { - content::WebContents* web_contents = browser_->web_contents(); CefRenderWidgetHostViewOSR* fs_view = static_cast( - web_contents->GetFullscreenRenderWidgetHostView()); + web_contents_->GetFullscreenRenderWidgetHostView()); if (fs_view) return fs_view; - content::RenderViewHost* host = web_contents->GetRenderViewHost(); + content::RenderViewHost* host = web_contents_->GetRenderViewHost(); if (host) { return static_cast( host->GetWidget()->GetView()); diff --git a/libcef/browser/osr/browser_platform_delegate_osr.h b/libcef/browser/osr/browser_platform_delegate_osr.h index 2a4d2adae..c6ff9d79c 100644 --- a/libcef/browser/osr/browser_platform_delegate_osr.h +++ b/libcef/browser/osr/browser_platform_delegate_osr.h @@ -27,9 +27,9 @@ class CefBrowserPlatformDelegateOsr void WebContentsCreated(content::WebContents* web_contents, bool owned) override; void RenderViewCreated(content::RenderViewHost* render_view_host) override; - void BrowserCreated(AlloyBrowserHostImpl* browser) override; + void BrowserCreated(CefBrowserHostBase* browser) override; void NotifyBrowserDestroyed() override; - void BrowserDestroyed(AlloyBrowserHostImpl* browser) override; + void BrowserDestroyed(CefBrowserHostBase* browser) override; SkColor GetBackgroundColor() const override; void WasResized() override; void SendKeyEvent(const CefKeyEvent& event) override; @@ -54,7 +54,6 @@ class CefBrowserPlatformDelegateOsr override; std::unique_ptr CreateMenuRunner() override; bool IsWindowless() const override; - bool IsViewsHosted() const override; void WasHidden(bool hidden) override; void NotifyScreenInfoChanged() override; void Invalidate(cef_paint_element_type_t type) override; diff --git a/libcef/browser/prefs/browser_prefs.cc b/libcef/browser/prefs/browser_prefs.cc index 32f4395b5..3ec73d377 100644 --- a/libcef/browser/prefs/browser_prefs.cc +++ b/libcef/browser/prefs/browser_prefs.cc @@ -298,4 +298,12 @@ std::unique_ptr CreatePrefService(Profile* profile, return factory.CreateSyncable(registry.get()); } +void SetLanguagePrefs(Profile* profile) { + const std::string& accept_language_list = GetAcceptLanguageList(profile); + if (!accept_language_list.empty()) { + profile->GetPrefs()->SetString(language::prefs::kAcceptLanguages, + accept_language_list); + } +} + } // namespace browser_prefs diff --git a/libcef/browser/prefs/browser_prefs.h b/libcef/browser/prefs/browser_prefs.h index 94c6d130c..5e2f4abc1 100644 --- a/libcef/browser/prefs/browser_prefs.h +++ b/libcef/browser/prefs/browser_prefs.h @@ -25,6 +25,9 @@ std::unique_ptr CreatePrefService(Profile* profile, const base::FilePath& cache_path, bool persist_user_preferences); +// Set language preferences on |profile|. +void SetLanguagePrefs(Profile* profile); + } // namespace browser_prefs #endif // CEF_LIBCEF_BROWSER_PREFS_BROWSER_PREFS_H_ diff --git a/libcef/browser/request_context_impl.cc b/libcef/browser/request_context_impl.cc index f74b9edd8..50107aabc 100644 --- a/libcef/browser/request_context_impl.cc +++ b/libcef/browser/request_context_impl.cc @@ -602,7 +602,6 @@ void CefRequestContextImpl::OnRenderFrameDeleted(int render_process_id, // static CefRefPtr CefRequestContextImpl::GetOrCreateRequestContext(const Config& config) { - // TODO(chrome-runtime): Add support for this method. if (config.is_global || (config.other && config.other->IsGlobal() && !config.handler)) { // Return the singleton global context. diff --git a/libcef/browser/views/browser_platform_delegate_views.cc b/libcef/browser/views/browser_platform_delegate_views.cc index 9b7d6578c..323c6eb75 100644 --- a/libcef/browser/views/browser_platform_delegate_views.cc +++ b/libcef/browser/views/browser_platform_delegate_views.cc @@ -80,7 +80,7 @@ void CefBrowserPlatformDelegateViews::WebContentsDestroyed( } void CefBrowserPlatformDelegateViews::BrowserCreated( - AlloyBrowserHostImpl* browser) { + CefBrowserHostBase* browser) { CefBrowserPlatformDelegateAlloy::BrowserCreated(browser); native_delegate_->BrowserCreated(browser); @@ -102,7 +102,7 @@ void CefBrowserPlatformDelegateViews::NotifyBrowserDestroyed() { } void CefBrowserPlatformDelegateViews::BrowserDestroyed( - AlloyBrowserHostImpl* browser) { + CefBrowserHostBase* browser) { CefBrowserPlatformDelegateAlloy::BrowserDestroyed(browser); browser_view_->BrowserDestroyed(browser); @@ -161,7 +161,7 @@ void CefBrowserPlatformDelegateViews::PopupWebContentsCreated( } void CefBrowserPlatformDelegateViews::PopupBrowserCreated( - AlloyBrowserHostImpl* new_browser, + CefBrowserHostBase* new_browser, bool is_devtools) { CefRefPtr new_browser_view = CefBrowserView::GetForBrowser(new_browser); @@ -264,10 +264,6 @@ CefBrowserPlatformDelegateViews::CreateMenuRunner() { return base::WrapUnique(new CefMenuRunnerViews(browser_view_.get())); } -bool CefBrowserPlatformDelegateViews::IsWindowless() const { - return false; -} - bool CefBrowserPlatformDelegateViews::IsViewsHosted() const { return true; } diff --git a/libcef/browser/views/browser_platform_delegate_views.h b/libcef/browser/views/browser_platform_delegate_views.h index 49ad5e17c..41448c007 100644 --- a/libcef/browser/views/browser_platform_delegate_views.h +++ b/libcef/browser/views/browser_platform_delegate_views.h @@ -24,10 +24,10 @@ class CefBrowserPlatformDelegateViews void WebContentsCreated(content::WebContents* web_contents, bool owned) override; void WebContentsDestroyed(content::WebContents* web_contents) override; - void BrowserCreated(AlloyBrowserHostImpl* browser) override; + void BrowserCreated(CefBrowserHostBase* browser) override; void NotifyBrowserCreated() override; void NotifyBrowserDestroyed() override; - void BrowserDestroyed(AlloyBrowserHostImpl* browser) override; + void BrowserDestroyed(CefBrowserHostBase* browser) override; bool CreateHostWindow() override; void CloseHostWindow() override; CefWindowHandle GetHostWindowHandle() const override; @@ -39,7 +39,7 @@ class CefBrowserPlatformDelegateViews content::WebContents* new_web_contents, CefBrowserPlatformDelegate* new_platform_delegate, bool is_devtools) override; - void PopupBrowserCreated(AlloyBrowserHostImpl* new_browser, + void PopupBrowserCreated(CefBrowserHostBase* new_browser, bool is_devtools) override; SkColor GetBackgroundColor() const override; void WasResized() override; @@ -64,7 +64,6 @@ class CefBrowserPlatformDelegateViews std::unique_ptr CreateJavaScriptDialogRunner() override; std::unique_ptr CreateMenuRunner() override; - bool IsWindowless() const override; bool IsViewsHosted() const override; gfx::Point GetDialogPosition(const gfx::Size& size) override; gfx::Size GetMaximumDialogSize() override; diff --git a/libcef/browser/views/browser_view_impl.cc b/libcef/browser/views/browser_view_impl.cc index 03135d323..605723009 100644 --- a/libcef/browser/views/browser_view_impl.cc +++ b/libcef/browser/views/browser_view_impl.cc @@ -29,7 +29,9 @@ CefRefPtr CefBrowserView::CreateBrowserView( // static CefRefPtr CefBrowserView::GetForBrowser( CefRefPtr browser) { + REQUIRE_ALLOY_RUNTIME(); CEF_REQUIRE_UIT_RETURN(nullptr); + AlloyBrowserHostImpl* browser_impl = static_cast(browser.get()); if (browser_impl && browser_impl->IsViewsHosted()) @@ -45,10 +47,9 @@ CefRefPtr CefBrowserViewImpl::Create( CefRefPtr extra_info, CefRefPtr request_context, CefRefPtr delegate) { - // TODO(chrome-runtime): Add support for this method. REQUIRE_ALLOY_RUNTIME(); - CEF_REQUIRE_UIT_RETURN(nullptr); + CefRefPtr browser_view = new CefBrowserViewImpl(delegate); browser_view->SetPendingBrowserCreateParams(client, url, settings, extra_info, request_context); @@ -61,7 +62,9 @@ CefRefPtr CefBrowserViewImpl::Create( CefRefPtr CefBrowserViewImpl::CreateForPopup( const CefBrowserSettings& settings, CefRefPtr delegate) { + REQUIRE_ALLOY_RUNTIME(); CEF_REQUIRE_UIT_RETURN(nullptr); + CefRefPtr browser_view = new CefBrowserViewImpl(delegate); browser_view->Initialize(); browser_view->SetDefaults(settings); @@ -75,13 +78,13 @@ void CefBrowserViewImpl::WebContentsCreated( } void CefBrowserViewImpl::BrowserCreated( - AlloyBrowserHostImpl* browser, + CefBrowserHostBase* browser, base::RepeatingClosure on_bounds_changed) { browser_ = browser; on_bounds_changed_ = on_bounds_changed; } -void CefBrowserViewImpl::BrowserDestroyed(AlloyBrowserHostImpl* browser) { +void CefBrowserViewImpl::BrowserDestroyed(CefBrowserHostBase* browser) { DCHECK_EQ(browser, browser_); browser_ = nullptr; @@ -145,10 +148,10 @@ void CefBrowserViewImpl::Detach() { if (browser_) { // |browser_| will disappear when WindowDestroyed() indirectly calls // BrowserDestroyed() so keep a reference. - CefRefPtr browser = browser_; + CefRefPtr browser = browser_; // Force the browser to be destroyed. - browser->WindowDestroyed(); + static_cast(browser.get())->WindowDestroyed(); } } @@ -188,7 +191,7 @@ void CefBrowserViewImpl::SetPendingBrowserCreateParams( CefRefPtr extra_info, CefRefPtr request_context) { DCHECK(!pending_browser_create_params_); - pending_browser_create_params_.reset(new CefBrowserHostBase::CreateParams()); + pending_browser_create_params_.reset(new CefBrowserCreateParams()); pending_browser_create_params_->client = client; pending_browser_create_params_->url = GURL(url.ToString()); pending_browser_create_params_->settings = settings; diff --git a/libcef/browser/views/browser_view_impl.h b/libcef/browser/views/browser_view_impl.h index f379f91b6..f128a61ba 100644 --- a/libcef/browser/views/browser_view_impl.h +++ b/libcef/browser/views/browser_view_impl.h @@ -9,14 +9,15 @@ #include "include/cef_client.h" #include "include/views/cef_browser_view.h" #include "include/views/cef_browser_view_delegate.h" - -#include "libcef/browser/alloy/alloy_browser_host_impl.h" +#include "libcef/browser/browser_host_base.h" #include "libcef/browser/views/browser_view_view.h" #include "libcef/browser/views/view_impl.h" #include "base/callback_forward.h" #include "ui/views/controls/webview/unhandled_keyboard_event_handler.h" +class CefBrowserHostBase; + class CefBrowserViewImpl : public CefViewImpl, @@ -44,9 +45,9 @@ class CefBrowserViewImpl : public CefViewImpl - pending_browser_create_params_; + std::unique_ptr pending_browser_create_params_; - CefRefPtr browser_; + CefRefPtr browser_; views::UnhandledKeyboardEventHandler unhandled_keyboard_event_handler_; bool ignore_next_char_event_ = false; diff --git a/libcef/common/cef_switches.cc b/libcef/common/cef_switches.cc index 76849a01b..2b7507e5b 100644 --- a/libcef/common/cef_switches.cc +++ b/libcef/common/cef_switches.cc @@ -125,6 +125,10 @@ const char kDevToolsProtocolLogFile[] = "devtools-protocol-log-file"; // Enable use of the Chrome runtime in CEF. See issue #2969 for details. const char kEnableChromeRuntime[] = "enable-chrome-runtime"; +// Delegate all login requests to the client GetAuthCredentials callback when +// using the Chrome runtime. +const char kDisableChromeLoginPrompt[] = "disable-chrome-login-prompt"; + #if defined(OS_MAC) // Path to the framework directory. const char kFrameworkDirPath[] = "framework-dir-path"; diff --git a/libcef/common/cef_switches.h b/libcef/common/cef_switches.h index ebc5a1feb..b5f0e1bd0 100644 --- a/libcef/common/cef_switches.h +++ b/libcef/common/cef_switches.h @@ -55,6 +55,7 @@ extern const char kEnablePrintPreview[]; extern const char kDisableNewBrowserInfoTimeout[]; extern const char kDevToolsProtocolLogFile[]; extern const char kEnableChromeRuntime[]; +extern const char kDisableChromeLoginPrompt[]; #if defined(OS_MAC) extern const char kFrameworkDirPath[]; diff --git a/libcef/common/chrome/chrome_main_delegate_cef.cc b/libcef/common/chrome/chrome_main_delegate_cef.cc index 6682bc021..b12144d1c 100644 --- a/libcef/common/chrome/chrome_main_delegate_cef.cc +++ b/libcef/common/chrome/chrome_main_delegate_cef.cc @@ -7,16 +7,29 @@ #include "libcef/browser/chrome/chrome_browser_context.h" #include "libcef/browser/chrome/chrome_content_browser_client_cef.h" +#include "libcef/common/cef_switches.h" +#include "libcef/common/command_line_impl.h" #include "libcef/common/crash_reporting.h" #include "libcef/common/resource_util.h" +#include "libcef/renderer/chrome/chrome_content_renderer_client_cef.h" #include "base/command_line.h" +#include "base/lazy_instance.h" #include "content/public/common/content_switches.h" +#include "sandbox/policy/switches.h" +#include "services/service_manager/embedder/switches.h" #if defined(OS_MAC) #include "libcef/common/util_mac.h" #endif +namespace { + +base::LazyInstance::DestructorAtExit + g_chrome_content_renderer_client = LAZY_INSTANCE_INITIALIZER; + +} // namespace + ChromeMainDelegateCef::ChromeMainDelegateCef(CefMainRunnerHandler* runner, CefSettings* settings, CefRefPtr application) @@ -34,21 +47,71 @@ ChromeMainDelegateCef::~ChromeMainDelegateCef() = default; bool ChromeMainDelegateCef::BasicStartupComplete(int* exit_code) { // Returns false if startup should proceed. bool result = ChromeMainDelegate::BasicStartupComplete(exit_code); + if (result) + return true; + + base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); - if (!result) { #if defined(OS_POSIX) - // Read the crash configuration file. Platforms using Breakpad also add a - // command-line switch. On Windows this is done from chrome_elf. - crash_reporting::BasicStartupComplete( - base::CommandLine::ForCurrentProcess()); + // Read the crash configuration file. Platforms using Breakpad also add a + // command-line switch. On Windows this is done from chrome_elf. + crash_reporting::BasicStartupComplete(command_line); #endif -#if defined(OS_MAC) - util_mac::BasicStartupComplete(); -#endif + const std::string& process_type = + command_line->GetSwitchValueASCII(switches::kProcessType); + if (process_type.empty()) { + // In the browser process. Populate the global command-line object. + // TODO(chrome-runtime): Copy more settings from AlloyMainDelegate and test. + if (settings_->command_line_args_disabled) { + // Remove any existing command-line arguments. + base::CommandLine::StringVector argv; + argv.push_back(command_line->GetProgram().value()); + command_line->InitFromArgv(argv); + + const base::CommandLine::SwitchMap& map = command_line->GetSwitches(); + const_cast(&map)->clear(); + } + + bool no_sandbox = settings_->no_sandbox ? true : false; + + if (no_sandbox) { + command_line->AppendSwitch(sandbox::policy::switches::kNoSandbox); + } + + if (settings_->javascript_flags.length > 0) { + command_line->AppendSwitchASCII(switches::kJavaScriptFlags, + CefString(&settings_->javascript_flags)); + } + + if (settings_->remote_debugging_port >= 1024 && + settings_->remote_debugging_port <= 65535) { + command_line->AppendSwitchASCII( + switches::kRemoteDebuggingPort, + base::NumberToString(settings_->remote_debugging_port)); + } + + if (settings_->uncaught_exception_stack_size > 0) { + command_line->AppendSwitchASCII( + switches::kUncaughtExceptionStackSize, + base::NumberToString(settings_->uncaught_exception_stack_size)); + } } - return result; + if (application_) { + // Give the application a chance to view/modify the command line. + CefRefPtr commandLinePtr( + new CefCommandLineImpl(command_line, false, false)); + application_->OnBeforeCommandLineProcessing(process_type, + commandLinePtr.get()); + commandLinePtr->Detach(nullptr); + } + +#if defined(OS_MAC) + util_mac::BasicStartupComplete(); +#endif + + return false; } void ChromeMainDelegateCef::PreSandboxStartup() { @@ -124,6 +187,11 @@ ChromeMainDelegateCef::CreateContentBrowserClient() { return chrome_content_browser_client_.get(); } +content::ContentRendererClient* +ChromeMainDelegateCef::CreateContentRendererClient() { + return g_chrome_content_renderer_client.Pointer(); +} + CefRefPtr ChromeMainDelegateCef::GetGlobalRequestContext() { auto browser_client = content_browser_client(); if (browser_client) @@ -164,15 +232,17 @@ ChromeMainDelegateCef::GetUserBlockingTaskRunner() { scoped_refptr ChromeMainDelegateCef::GetRenderTaskRunner() { - // TODO: Implement. - NOTREACHED(); + auto renderer_client = content_renderer_client(); + if (renderer_client) + return renderer_client->render_task_runner(); return nullptr; } scoped_refptr ChromeMainDelegateCef::GetWebWorkerTaskRunner() { - // TODO: Implement. - NOTREACHED(); + auto renderer_client = content_renderer_client(); + if (renderer_client) + return renderer_client->GetCurrentTaskRunner(); return nullptr; } @@ -181,3 +251,10 @@ ChromeContentBrowserClientCef* ChromeMainDelegateCef::content_browser_client() return static_cast( chrome_content_browser_client_.get()); } + +ChromeContentRendererClientCef* ChromeMainDelegateCef::content_renderer_client() + const { + if (!g_chrome_content_renderer_client.IsCreated()) + return nullptr; + return g_chrome_content_renderer_client.Pointer(); +} \ No newline at end of file diff --git a/libcef/common/chrome/chrome_main_delegate_cef.h b/libcef/common/chrome/chrome_main_delegate_cef.h index c23058ae0..b8a9781e8 100644 --- a/libcef/common/chrome/chrome_main_delegate_cef.h +++ b/libcef/common/chrome/chrome_main_delegate_cef.h @@ -18,6 +18,7 @@ #include "chrome/app/chrome_main_delegate.h" class ChromeContentBrowserClientCef; +class ChromeContentRendererClientCef; // CEF override of ChromeMainDelegate class ChromeMainDelegateCef : public ChromeMainDelegate, @@ -43,6 +44,7 @@ class ChromeMainDelegateCef : public ChromeMainDelegate, #endif content::ContentClient* CreateContentClient() override; content::ContentBrowserClient* CreateContentBrowserClient() override; + content::ContentRendererClient* CreateContentRendererClient() override; protected: // CefAppManager overrides. @@ -66,6 +68,7 @@ class ChromeMainDelegateCef : public ChromeMainDelegate, private: ChromeContentBrowserClientCef* content_browser_client() const; + ChromeContentRendererClientCef* content_renderer_client() const; CefMainRunnerHandler* const runner_; CefSettings* const settings_; diff --git a/libcef/common/task_impl.cc b/libcef/common/task_impl.cc index e03744c4b..b74db2ecb 100644 --- a/libcef/common/task_impl.cc +++ b/libcef/common/task_impl.cc @@ -7,12 +7,16 @@ #include "base/bind.h" #include "base/location.h" +#include "base/logging.h" bool CefCurrentlyOn(CefThreadId threadId) { scoped_refptr task_runner = CefTaskRunnerImpl::GetTaskRunner(threadId); - if (task_runner.get()) + if (task_runner.get()) { return task_runner->RunsTasksInCurrentSequence(); + } + + LOG(WARNING) << "No task runner for threadId " << threadId; return false; } @@ -23,6 +27,8 @@ bool CefPostTask(CefThreadId threadId, CefRefPtr task) { return task_runner->PostTask(FROM_HERE, base::Bind(&CefTask::Execute, task.get())); } + + LOG(WARNING) << "No task runner for threadId " << threadId; return false; } @@ -36,5 +42,7 @@ bool CefPostDelayedTask(CefThreadId threadId, FROM_HERE, base::Bind(&CefTask::Execute, task.get()), base::TimeDelta::FromMilliseconds(delay_ms)); } + + LOG(WARNING) << "No task runner for threadId " << threadId; return false; } diff --git a/libcef/common/urlrequest_impl.cc b/libcef/common/urlrequest_impl.cc index 655f3bdba..463ea5ee4 100644 --- a/libcef/common/urlrequest_impl.cc +++ b/libcef/common/urlrequest_impl.cc @@ -17,9 +17,6 @@ CefRefPtr CefURLRequest::Create( CefRefPtr request, CefRefPtr client, CefRefPtr request_context) { - // TODO(chrome-runtime): Add support for this method. - REQUIRE_ALLOY_RUNTIME(); - if (!request.get() || !client.get()) { NOTREACHED() << "called with invalid parameters"; return nullptr; diff --git a/libcef/renderer/alloy/alloy_content_renderer_client.cc b/libcef/renderer/alloy/alloy_content_renderer_client.cc index b620bf23c..040296195 100644 --- a/libcef/renderer/alloy/alloy_content_renderer_client.cc +++ b/libcef/renderer/alloy/alloy_content_renderer_client.cc @@ -28,19 +28,16 @@ #include "libcef/common/cef_switches.h" #include "libcef/common/extensions/extensions_client.h" #include "libcef/common/extensions/extensions_util.h" -#include "libcef/common/net/scheme_info.h" #include "libcef/common/request_impl.h" -#include "libcef/common/values_impl.h" #include "libcef/features/runtime_checks.h" -#include "libcef/renderer/blink_glue.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_thread_observer.h" #include "libcef/renderer/thread_util.h" -#include "libcef/renderer/url_loader_throttle_provider_impl.h" -#include "libcef/renderer/v8_impl.h" #include "base/command_line.h" #include "base/macros.h" @@ -48,7 +45,6 @@ #include "base/metrics/user_metrics_action.h" #include "base/path_service.h" #include "base/stl_util.h" -#include "base/strings/string_number_conversions.h" #include "base/strings/utf_string_conversions.h" #include "base/task/post_task.h" #include "build/build_config.h" @@ -145,29 +141,9 @@ bool IsStandaloneExtensionProcess() { } // namespace -// Placeholder object for guest views. -class CefGuestView : public content::RenderViewObserver { - public: - CefGuestView(content::RenderView* render_view, bool is_windowless) - : content::RenderViewObserver(render_view), - is_windowless_(is_windowless) {} - - bool is_windowless() const { return is_windowless_; } - - private: - // RenderViewObserver methods. - void OnDestruct() override { - AlloyContentRendererClient::Get()->OnGuestViewDestroyed(this); - } - - const bool is_windowless_; -}; - AlloyContentRendererClient::AlloyContentRendererClient() : main_entry_time_(base::TimeTicks::Now()), - devtools_agent_count_(0), - uncaught_exception_stack_size_(0), - single_process_cleanup_complete_(false) { + browser_manager_(new CefBrowserManager) { if (extensions::ExtensionsEnabled()) { extensions_client_.reset(new extensions::CefExtensionsClient); extensions::ExtensionsClient::Set(extensions_client_.get()); @@ -187,139 +163,6 @@ AlloyContentRendererClient* AlloyContentRendererClient::Get() { CefAppManager::Get()->GetContentClient()->renderer()); } -CefRefPtr AlloyContentRendererClient::GetBrowserForView( - content::RenderView* view) { - CEF_REQUIRE_RT_RETURN(nullptr); - - BrowserMap::const_iterator it = browsers_.find(view); - if (it != browsers_.end()) - return it->second; - return nullptr; -} - -CefRefPtr AlloyContentRendererClient::GetBrowserForMainFrame( - blink::WebFrame* frame) { - CEF_REQUIRE_RT_RETURN(nullptr); - - BrowserMap::const_iterator it = browsers_.begin(); - for (; it != browsers_.end(); ++it) { - content::RenderView* render_view = it->second->render_view(); - if (render_view && render_view->GetWebView() && - render_view->GetWebView()->MainFrame() == frame) { - return it->second; - } - } - - return nullptr; -} - -void AlloyContentRendererClient::OnBrowserDestroyed(CefBrowserImpl* browser) { - BrowserMap::iterator it = browsers_.begin(); - for (; it != browsers_.end(); ++it) { - if (it->second.get() == browser) { - browsers_.erase(it); - return; - } - } - - // No browser was found in the map. - NOTREACHED(); -} - -CefGuestView* AlloyContentRendererClient::GetGuestViewForView( - content::RenderView* view) { - CEF_REQUIRE_RT_RETURN(nullptr); - - GuestViewMap::const_iterator it = guest_views_.find(view); - if (it != guest_views_.end()) - return it->second.get(); - return nullptr; -} - -void AlloyContentRendererClient::OnGuestViewDestroyed( - CefGuestView* guest_view) { - GuestViewMap::iterator it = guest_views_.begin(); - for (; it != guest_views_.end(); ++it) { - if (it->second.get() == guest_view) { - guest_views_.erase(it); - return; - } - } - - // No guest view was found in the map. - NOTREACHED(); -} - -void AlloyContentRendererClient::WebKitInitialized() { - const base::CommandLine* command_line = - base::CommandLine::ForCurrentProcess(); - - // Create global objects associated with the default Isolate. - CefV8IsolateCreated(); - - const CefAppManager::SchemeInfoList* schemes = - CefAppManager::Get()->GetCustomSchemes(); - if (!schemes->empty()) { - // Register the custom schemes. The |is_standard| value is excluded here - // because it's not explicitly registered with Blink. - CefAppManager::SchemeInfoList::const_iterator it = schemes->begin(); - for (; it != schemes->end(); ++it) { - const CefSchemeInfo& info = *it; - const blink::WebString& scheme = - blink::WebString::FromUTF8(info.scheme_name); - if (info.is_local) - blink_glue::RegisterURLSchemeAsLocal(scheme); - if (info.is_display_isolated) - blink::WebSecurityPolicy::RegisterURLSchemeAsDisplayIsolated(scheme); - if (info.is_secure) - blink_glue::RegisterURLSchemeAsSecure(scheme); - if (info.is_fetch_enabled) - blink_glue::RegisterURLSchemeAsSupportingFetchAPI(scheme); - } - } - - 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); - } - cross_origin_whitelist_entries_.clear(); - } - - // The number of stack trace frames to capture for uncaught exceptions. - if (command_line->HasSwitch(switches::kUncaughtExceptionStackSize)) { - int uncaught_exception_stack_size = 0; - base::StringToInt(command_line->GetSwitchValueASCII( - switches::kUncaughtExceptionStackSize), - &uncaught_exception_stack_size); - - if (uncaught_exception_stack_size > 0) { - uncaught_exception_stack_size_ = uncaught_exception_stack_size; - CefV8SetUncaughtExceptionStackSize(uncaught_exception_stack_size_); - } - } - - // Notify the render process handler. - CefRefPtr application = CefAppManager::Get()->GetApplication(); - if (application.get()) { - CefRefPtr handler = - application->GetRenderProcessHandler(); - if (handler.get()) - handler->OnWebKitInitialized(); - } -} - scoped_refptr AlloyContentRendererClient::GetCurrentTaskRunner() { // Check if currently on the render thread. @@ -372,7 +215,7 @@ void AlloyContentRendererClient::RenderThreadStarted() { base::CommandLine::ForCurrentProcess(); render_task_runner_ = base::ThreadTaskRunnerHandle::Get(); - observer_ = std::make_unique(); + observer_ = std::make_unique(); web_cache_impl_ = std::make_unique(); visited_link_slave_ = std::make_unique(); @@ -449,25 +292,17 @@ void AlloyContentRendererClient::ExposeInterfacesToBrowser( } void AlloyContentRendererClient::RenderThreadConnected() { - content::RenderThread* thread = content::RenderThread::Get(); - - // Retrieve the new render thread information synchronously. - CefProcessHostMsg_GetNewRenderThreadInfo_Params params; - thread->Send(new CefProcessHostMsg_GetNewRenderThreadInfo(¶ms)); - - // Cross-origin entries need to be added after WebKit is initialized. - cross_origin_whitelist_entries_ = params.cross_origin_whitelist_entries; - // Register extensions last because it will trigger WebKit initialization. + content::RenderThread* thread = content::RenderThread::Get(); thread->RegisterExtension(extensions_v8::LoadTimesExtension::Get()); - WebKitInitialized(); + browser_manager_->RenderThreadConnected(); } void AlloyContentRendererClient::RenderFrameCreated( content::RenderFrame* render_frame) { - CefRenderFrameObserver* render_frame_observer = - new CefRenderFrameObserver(render_frame); + AlloyRenderFrameObserver* render_frame_observer = + new AlloyRenderFrameObserver(render_frame); service_manager::BinderRegistry* registry = render_frame_observer->registry(); new PepperHelper(render_frame); @@ -488,14 +323,12 @@ void AlloyContentRendererClient::RenderFrameCreated( new SpellCheckProvider(render_frame, spellcheck_.get(), this); } + bool browser_created; base::Optional is_windowless; - - auto browser = MaybeCreateBrowser(render_frame->GetRenderView(), render_frame, - &is_windowless); - if (browser) { - // Attach the frame to the observer for message routing purposes. - render_frame_observer->AttachFrame( - browser->GetWebFrameImpl(render_frame->GetWebFrame()).get()); + browser_manager_->RenderFrameCreated(render_frame, render_frame_observer, + browser_created, is_windowless); + if (browser_created) { + OnBrowserCreated(render_frame->GetRenderView(), is_windowless); } if (is_windowless.has_value()) { @@ -510,7 +343,13 @@ void AlloyContentRendererClient::RenderViewCreated( content::RenderView* render_view) { new CefPrerendererClient(render_view); - MaybeCreateBrowser(render_view, render_view->GetMainRenderFrame(), nullptr); + bool browser_created; + base::Optional is_windowless; + browser_manager_->RenderViewCreated(render_view, browser_created, + is_windowless); + if (browser_created) { + OnBrowserCreated(render_view, is_windowless); + } } bool AlloyContentRendererClient::IsPluginHandledExternally( @@ -649,7 +488,7 @@ void AlloyContentRendererClient::DevToolsAgentAttached() { return; } - ++devtools_agent_count_; + browser_manager_->DevToolsAgentAttached(); } void AlloyContentRendererClient::DevToolsAgentDetached() { @@ -662,12 +501,7 @@ void AlloyContentRendererClient::DevToolsAgentDetached() { return; } - --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. - // Restore the user-specified stack size here. - CefV8SetUncaughtExceptionStackSize(uncaught_exception_stack_size_); - } + browser_manager_->DevToolsAgentDetached(); } std::unique_ptr @@ -700,84 +534,18 @@ void AlloyContentRendererClient::WillDestroyCurrentMessageLoop() { single_process_cleanup_complete_ = true; } -CefRefPtr AlloyContentRendererClient::MaybeCreateBrowser( +void AlloyContentRendererClient::OnBrowserCreated( content::RenderView* render_view, - content::RenderFrame* render_frame, - base::Optional* is_windowless) { - if (!render_view || !render_frame) - return nullptr; - - // Don't create another browser or guest view object if one already exists for - // the view. - auto browser = GetBrowserForView(render_view); - if (browser) { - if (is_windowless) { - *is_windowless = browser->is_windowless(); - } - return browser; - } - - auto guest_view = GetGuestViewForView(render_view); - if (guest_view) { - if (is_windowless) { - *is_windowless = guest_view->is_windowless(); - } - return nullptr; - } - - const int render_frame_routing_id = render_frame->GetRoutingID(); - - // Retrieve the browser information synchronously. This will also register - // the routing ids with the browser info object in the browser process. - CefProcessHostMsg_GetNewBrowserInfo_Params params; - content::RenderThread::Get()->Send(new CefProcessHostMsg_GetNewBrowserInfo( - render_frame_routing_id, ¶ms)); - - if (is_windowless) { - *is_windowless = params.is_windowless; - } - - if (params.browser_id == 0) { - // The popup may have been canceled during creation. - return nullptr; - } - - 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(render_view, params.is_windowless))); - return nullptr; - } - + base::Optional is_windowless) { #if defined(OS_MAC) + const bool windowless = is_windowless.has_value() && *is_windowless; + // FIXME: It would be better if this API would be a callback from the // WebKit layer, or if it would be exposed as an WebView instance method; the // current implementation uses a static variable, and WebKit needs to be // patched in order to make it work for each WebView instance - render_view->GetWebView()->SetUseExternalPopupMenusThisInstance( - !params.is_windowless); + render_view->GetWebView()->SetUseExternalPopupMenusThisInstance(!windowless); #endif - - 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. - CefRefPtr application = CefAppManager::Get()->GetApplication(); - if (application.get()) { - CefRefPtr handler = - application->GetRenderProcessHandler(); - if (handler.get()) { - CefRefPtr dictValuePtr( - new CefDictionaryValueImpl(¶ms.extra_info, false, true)); - handler->OnBrowserCreated(browser.get(), dictValuePtr.get()); - dictValuePtr->Detach(nullptr); - } - } - - return browser; } void AlloyContentRendererClient::RunSingleProcessCleanupOnUIThread() { diff --git a/libcef/renderer/alloy/alloy_content_renderer_client.h b/libcef/renderer/alloy/alloy_content_renderer_client.h index 28a2f6150..ae251f249 100644 --- a/libcef/renderer/alloy/alloy_content_renderer_client.h +++ b/libcef/renderer/alloy/alloy_content_renderer_client.h @@ -16,8 +16,7 @@ #include "libcef/renderer/browser_impl.h" #include "base/compiler_specific.h" -#include "base/optional.h" -#include "base/sequenced_task_runner.h" +#include "base/single_thread_task_runner.h" #include "base/task/current_thread.h" #include "chrome/common/plugin.mojom.h" #include "content/public/renderer/content_renderer_client.h" @@ -43,9 +42,8 @@ namespace web_cache { class WebCacheImpl; } -class CefGuestView; +class CefBrowserManager; class CefRenderThreadObserver; -struct Cef_CrossOriginWhiteListEntry_Params; class ChromePDFPrintClient; class SpellCheck; @@ -61,32 +59,11 @@ class AlloyContentRendererClient // This method is deprecated and should not be used in new callsites. static AlloyContentRendererClient* Get(); - // Returns the browser associated with the specified RenderView. - CefRefPtr GetBrowserForView(content::RenderView* view); - - // Returns the browser associated with the specified main WebFrame. - CefRefPtr GetBrowserForMainFrame(blink::WebFrame* frame); - - // Called from CefBrowserImpl::OnDestruct(). - void OnBrowserDestroyed(CefBrowserImpl* browser); - - // Returns the guest view associated with the specified RenderView if any. - CefGuestView* GetGuestViewForView(content::RenderView* view); - - // Called from CefGuestView::OnDestruct(). - void OnGuestViewDestroyed(CefGuestView* guest_view); - // Render thread task runner. base::SingleThreadTaskRunner* render_task_runner() const { return render_task_runner_.get(); } - int uncaught_exception_stack_size() const { - return uncaught_exception_stack_size_; - } - - void WebKitInitialized(); - // Returns the task runner for the current thread. Returns NULL if the current // thread is not the main render process thread. scoped_refptr GetCurrentTaskRunner(); @@ -146,12 +123,8 @@ class AlloyContentRendererClient void WillDestroyCurrentMessageLoop() override; private: - // Maybe create a new browser object, return the existing one, or return - // nullptr for guest views. - CefRefPtr MaybeCreateBrowser( - content::RenderView* render_view, - content::RenderFrame* render_frame, - base::Optional* is_windowless); + void OnBrowserCreated(content::RenderView* render_view, + base::Optional is_windowless); // Perform cleanup work for single-process mode. void RunSingleProcessCleanupOnUIThread(); @@ -160,37 +133,23 @@ class AlloyContentRendererClient // which the RendererMain function was entered. base::TimeTicks main_entry_time_; + std::unique_ptr browser_manager_; + scoped_refptr render_task_runner_; std::unique_ptr observer_; std::unique_ptr web_cache_impl_; std::unique_ptr spellcheck_; std::unique_ptr visited_link_slave_; - // Map of RenderView pointers to CefBrowserImpl references. - typedef std::map> BrowserMap; - BrowserMap browsers_; - - // Map of RenderView poiners to CefGuestView implementations. - typedef std::map> - GuestViewMap; - GuestViewMap guest_views_; - - // Cross-origin white list entries that need to be registered with WebKit. - typedef std::vector CrossOriginList; - CrossOriginList cross_origin_whitelist_entries_; - std::unique_ptr pdf_print_client_; std::unique_ptr extensions_client_; std::unique_ptr extensions_renderer_client_; - int devtools_agent_count_; - int uncaught_exception_stack_size_; - // Used in single-process mode to test when cleanup is complete. // Access must be protected by |single_process_cleanup_lock_|. - bool single_process_cleanup_complete_; + bool single_process_cleanup_complete_ = false; base::Lock single_process_cleanup_lock_; DISALLOW_COPY_AND_ASSIGN(AlloyContentRendererClient); diff --git a/libcef/renderer/alloy/alloy_render_frame_observer.cc b/libcef/renderer/alloy/alloy_render_frame_observer.cc new file mode 100644 index 000000000..68d56acba --- /dev/null +++ b/libcef/renderer/alloy/alloy_render_frame_observer.cc @@ -0,0 +1,23 @@ +// Copyright 2014 The Chromium Embedded Framework Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be found +// in the LICENSE file. + +#include "libcef/renderer/alloy/alloy_render_frame_observer.h" + +AlloyRenderFrameObserver::AlloyRenderFrameObserver( + content::RenderFrame* render_frame) + : CefRenderFrameObserver(render_frame) {} + +AlloyRenderFrameObserver::~AlloyRenderFrameObserver() = default; + +void AlloyRenderFrameObserver::OnInterfaceRequestForFrame( + const std::string& interface_name, + mojo::ScopedMessagePipeHandle* interface_pipe) { + registry_.TryBindInterface(interface_name, interface_pipe); +} + +bool AlloyRenderFrameObserver::OnAssociatedInterfaceRequestForFrame( + const std::string& interface_name, + mojo::ScopedInterfaceEndpointHandle* handle) { + return associated_interfaces_.TryBindInterface(interface_name, handle); +} diff --git a/libcef/renderer/alloy/alloy_render_frame_observer.h b/libcef/renderer/alloy/alloy_render_frame_observer.h new file mode 100644 index 000000000..e97a8514b --- /dev/null +++ b/libcef/renderer/alloy/alloy_render_frame_observer.h @@ -0,0 +1,38 @@ +// Copyright 2014 The Chromium Embedded Framework Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be found +// in the LICENSE file. + +#ifndef LIBCEF_RENDERER_ALLOY_ALLOY_RENDER_FRAME_OBSERVER_H_ +#define LIBCEF_RENDERER_ALLOY_ALLOY_RENDER_FRAME_OBSERVER_H_ + +#include "libcef/renderer/render_frame_observer.h" + +#include "services/service_manager/public/cpp/binder_registry.h" +#include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h" + +class AlloyRenderFrameObserver : public CefRenderFrameObserver { + public: + explicit AlloyRenderFrameObserver(content::RenderFrame* render_frame); + ~AlloyRenderFrameObserver() override; + + // RenderFrameObserver methods: + void OnInterfaceRequestForFrame( + const std::string& interface_name, + mojo::ScopedMessagePipeHandle* interface_pipe) override; + bool OnAssociatedInterfaceRequestForFrame( + const std::string& interface_name, + mojo::ScopedInterfaceEndpointHandle* handle) override; + + service_manager::BinderRegistry* registry() { return ®istry_; } + blink::AssociatedInterfaceRegistry* associated_interfaces() { + return &associated_interfaces_; + } + + private: + service_manager::BinderRegistry registry_; + blink::AssociatedInterfaceRegistry associated_interfaces_; + + DISALLOW_COPY_AND_ASSIGN(AlloyRenderFrameObserver); +}; + +#endif // LIBCEF_RENDERER_ALLOY_ALLOY_RENDER_FRAME_OBSERVER_H_ diff --git a/libcef/renderer/alloy/alloy_render_thread_observer.cc b/libcef/renderer/alloy/alloy_render_thread_observer.cc new file mode 100644 index 000000000..488eb444c --- /dev/null +++ b/libcef/renderer/alloy/alloy_render_thread_observer.cc @@ -0,0 +1,70 @@ +/// 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/alloy/alloy_render_thread_observer.h" + +#include "libcef/common/net/net_resource_provider.h" + +#include "base/no_destructor.h" +#include "mojo/public/cpp/bindings/strong_binding.h" +#include "net/base/net_module.h" +#include "services/service_manager/public/cpp/connector.h" +#include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h" + +namespace { + +chrome::mojom::DynamicParams* GetDynamicConfigParams() { + static base::NoDestructor dynamic_params; + return dynamic_params.get(); +} + +} // namespace + +bool AlloyRenderThreadObserver::is_incognito_process_ = false; + +AlloyRenderThreadObserver::AlloyRenderThreadObserver() { + net::NetModule::SetResourceProvider(NetResourceProvider); +} + +AlloyRenderThreadObserver::~AlloyRenderThreadObserver() {} + +// static +const chrome::mojom::DynamicParams& +AlloyRenderThreadObserver::GetDynamicParams() { + return *GetDynamicConfigParams(); +} + +void AlloyRenderThreadObserver::RegisterMojoInterfaces( + blink::AssociatedInterfaceRegistry* associated_interfaces) { + associated_interfaces->AddInterface(base::Bind( + &AlloyRenderThreadObserver::OnRendererConfigurationAssociatedRequest, + base::Unretained(this))); +} + +void AlloyRenderThreadObserver::UnregisterMojoInterfaces( + blink::AssociatedInterfaceRegistry* associated_interfaces) { + associated_interfaces->RemoveInterface( + chrome::mojom::RendererConfiguration::Name_); +} + +void AlloyRenderThreadObserver::SetInitialConfiguration( + bool is_incognito_process, + mojo::PendingReceiver chromeos_listener) { + is_incognito_process_ = is_incognito_process; +} + +void AlloyRenderThreadObserver::SetConfiguration( + chrome::mojom::DynamicParamsPtr params) { + *GetDynamicConfigParams() = std::move(*params); +} + +void AlloyRenderThreadObserver::SetContentSettingRules( + const RendererContentSettingRules& rules) {} + +void AlloyRenderThreadObserver::OnRendererConfigurationAssociatedRequest( + mojo::PendingAssociatedReceiver + receiver) { + renderer_configuration_receivers_.Add(this, std::move(receiver)); +} diff --git a/libcef/renderer/alloy/alloy_render_thread_observer.h b/libcef/renderer/alloy/alloy_render_thread_observer.h new file mode 100644 index 000000000..88f7abe40 --- /dev/null +++ b/libcef/renderer/alloy/alloy_render_thread_observer.h @@ -0,0 +1,61 @@ +// 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_ALLOY_ALLOY_RENDER_THREAD_OBSERVER_H_ +#define CEF_LIBCEF_RENDERER_ALLOY_ALLOY_RENDER_THREAD_OBSERVER_H_ + +#include + +#include "libcef/renderer/render_thread_observer.h" + +#include "base/compiler_specific.h" +#include "chrome/common/renderer_configuration.mojom.h" +#include "components/content_settings/core/common/content_settings.h" +#include "content/public/renderer/render_thread_observer.h" +#include "mojo/public/cpp/bindings/associated_binding_set.h" +#include "mojo/public/cpp/bindings/associated_receiver_set.h" + +// This class sends and receives control messages in the renderer process. +class AlloyRenderThreadObserver : public CefRenderThreadObserver, + public chrome::mojom::RendererConfiguration { + public: + AlloyRenderThreadObserver(); + ~AlloyRenderThreadObserver() override; + + static bool is_incognito_process() { return is_incognito_process_; } + + // Return the dynamic parameters - those that may change while the + // render process is running. + static const chrome::mojom::DynamicParams& GetDynamicParams(); + + private: + // content::RenderThreadObserver: + void RegisterMojoInterfaces( + blink::AssociatedInterfaceRegistry* associated_interfaces) override; + void UnregisterMojoInterfaces( + blink::AssociatedInterfaceRegistry* associated_interfaces) override; + + // chrome::mojom::RendererConfiguration: + void SetInitialConfiguration( + bool is_incognito_process, + mojo::PendingReceiver chromeos_listener) + override; + void SetConfiguration(chrome::mojom::DynamicParamsPtr params) override; + void SetContentSettingRules( + const RendererContentSettingRules& rules) override; + + void OnRendererConfigurationAssociatedRequest( + mojo::PendingAssociatedReceiver + receiver); + + static bool is_incognito_process_; + + mojo::AssociatedReceiverSet + renderer_configuration_receivers_; + + DISALLOW_COPY_AND_ASSIGN(AlloyRenderThreadObserver); +}; + +#endif // CEF_LIBCEF_RENDERER_ALLOY_ALLOY_RENDER_THREAD_OBSERVER_H_ diff --git a/libcef/renderer/url_loader_throttle_provider_impl.cc b/libcef/renderer/alloy/url_loader_throttle_provider_impl.cc similarity index 93% rename from libcef/renderer/url_loader_throttle_provider_impl.cc rename to libcef/renderer/alloy/url_loader_throttle_provider_impl.cc index 61f6f8d78..4efda94f9 100644 --- a/libcef/renderer/url_loader_throttle_provider_impl.cc +++ b/libcef/renderer/alloy/url_loader_throttle_provider_impl.cc @@ -2,10 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "libcef/renderer/url_loader_throttle_provider_impl.h" +#include "libcef/renderer/alloy/url_loader_throttle_provider_impl.h" #include "libcef/common/extensions/extensions_util.h" -#include "libcef/renderer/render_thread_observer.h" +#include "libcef/renderer/alloy/alloy_render_thread_observer.h" #include @@ -77,7 +77,7 @@ CefURLLoaderThrottleProviderImpl::CreateThrottles( } throttles.push_back(std::make_unique( - CefRenderThreadObserver::GetDynamicParams())); + AlloyRenderThreadObserver::GetDynamicParams())); return throttles; } diff --git a/libcef/renderer/url_loader_throttle_provider_impl.h b/libcef/renderer/alloy/url_loader_throttle_provider_impl.h similarity index 86% rename from libcef/renderer/url_loader_throttle_provider_impl.h rename to libcef/renderer/alloy/url_loader_throttle_provider_impl.h index 1fe2ca085..6724ca9c0 100644 --- a/libcef/renderer/url_loader_throttle_provider_impl.h +++ b/libcef/renderer/alloy/url_loader_throttle_provider_impl.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CEF_LIBCEF_RENDERER_URL_LOADER_THROTTLE_PROVIDER_IMPL_H_ -#define CEF_LIBCEF_RENDERER_URL_LOADER_THROTTLE_PROVIDER_IMPL_H_ +#ifndef CEF_LIBCEF_RENDERER_ALLOY_URL_LOADER_THROTTLE_PROVIDER_IMPL_H_ +#define CEF_LIBCEF_RENDERER_ALLOY_URL_LOADER_THROTTLE_PROVIDER_IMPL_H_ #include #include @@ -41,4 +41,4 @@ class CefURLLoaderThrottleProviderImpl DISALLOW_ASSIGN(CefURLLoaderThrottleProviderImpl); }; -#endif // CEF_LIBCEF_RENDERER_URL_LOADER_THROTTLE_PROVIDER_IMPL_H_ +#endif // CEF_LIBCEF_RENDERER_ALLOY_URL_LOADER_THROTTLE_PROVIDER_IMPL_H_ diff --git a/libcef/renderer/browser_impl.cc b/libcef/renderer/browser_impl.cc index e2d3ddd94..5983e3030 100644 --- a/libcef/renderer/browser_impl.cc +++ b/libcef/renderer/browser_impl.cc @@ -10,8 +10,8 @@ #include "libcef/common/app_manager.h" #include "libcef/common/cef_messages.h" -#include "libcef/renderer/alloy/alloy_content_renderer_client.h" #include "libcef/renderer/blink_glue.h" +#include "libcef/renderer/browser_manager.h" #include "libcef/renderer/render_frame_util.h" #include "libcef/renderer/thread_util.h" @@ -38,13 +38,13 @@ // static CefRefPtr CefBrowserImpl::GetBrowserForView( content::RenderView* view) { - return AlloyContentRendererClient::Get()->GetBrowserForView(view); + return CefBrowserManager::Get()->GetBrowserForView(view); } // static CefRefPtr CefBrowserImpl::GetBrowserForMainFrame( blink::WebFrame* frame) { - return AlloyContentRendererClient::Get()->GetBrowserForMainFrame(frame); + return CefBrowserManager::Get()->GetBrowserForMainFrame(frame); } // CefBrowser methods. @@ -352,7 +352,7 @@ void CefBrowserImpl::OnDestruct() { handler->OnBrowserDestroyed(this); } - AlloyContentRendererClient::Get()->OnBrowserDestroyed(this); + CefBrowserManager::Get()->OnBrowserDestroyed(this); } void CefBrowserImpl::FrameDetached(int64_t frame_id) { diff --git a/libcef/renderer/browser_manager.cc b/libcef/renderer/browser_manager.cc new file mode 100644 index 000000000..8e6326b2b --- /dev/null +++ b/libcef/renderer/browser_manager.cc @@ -0,0 +1,342 @@ +// Copyright 2015 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/browser_manager.h" + +#include "base/compiler_specific.h" + +// Enable deprecation warnings on Windows. See http://crbug.com/585142. +#if defined(OS_WIN) +#if defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic error "-Wdeprecated-declarations" +#else +#pragma warning(push) +#pragma warning(default : 4996) +#endif +#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" +#include "libcef/renderer/blink_glue.h" +#include "libcef/renderer/browser_impl.h" +#include "libcef/renderer/render_frame_observer.h" +#include "libcef/renderer/thread_util.h" +#include "libcef/renderer/v8_impl.h" + +#include "base/command_line.h" +#include "base/strings/string_number_conversions.h" +#include "content/public/renderer/render_frame.h" +#include "content/public/renderer/render_thread.h" +#include "content/public/renderer/render_view.h" +#include "content/public/renderer/render_view_observer.h" +#include "services/network/public/mojom/cors_origin_pattern.mojom.h" +#include "third_party/blink/public/web/web_security_policy.h" +#include "third_party/blink/public/web/web_view.h" + +namespace { + +CefBrowserManager* g_manager = nullptr; + +} // namespace + +// Placeholder object for guest views. +class CefGuestView : public content::RenderViewObserver { + public: + CefGuestView(CefBrowserManager* manager, + content::RenderView* render_view, + bool is_windowless) + : content::RenderViewObserver(render_view), + manager_(manager), + is_windowless_(is_windowless) {} + + bool is_windowless() const { return is_windowless_; } + + private: + // RenderViewObserver methods. + void OnDestruct() override { manager_->OnGuestViewDestroyed(this); } + + CefBrowserManager* const manager_; + const bool is_windowless_; +}; + +CefBrowserManager::CefBrowserManager() { + DCHECK(!g_manager); + g_manager = this; +} + +CefBrowserManager::~CefBrowserManager() { + g_manager = nullptr; +} + +// static +CefBrowserManager* CefBrowserManager::Get() { + CEF_REQUIRE_RT_RETURN(nullptr); + return g_manager; +} + +void CefBrowserManager::RenderThreadConnected() { + content::RenderThread* thread = content::RenderThread::Get(); + + // Retrieve the new render thread information synchronously. + CefProcessHostMsg_GetNewRenderThreadInfo_Params params; + thread->Send(new CefProcessHostMsg_GetNewRenderThreadInfo(¶ms)); + + // Cross-origin entries need to be added after WebKit is initialized. + cross_origin_whitelist_entries_ = params.cross_origin_whitelist_entries; + + WebKitInitialized(); +} + +void CefBrowserManager::RenderFrameCreated( + content::RenderFrame* render_frame, + CefRenderFrameObserver* render_frame_observer, + bool& browser_created, + base::Optional& is_windowless) { + auto browser = MaybeCreateBrowser(render_frame->GetRenderView(), render_frame, + &browser_created, &is_windowless); + if (browser) { + // Attach the frame to the observer for message routing purposes. + render_frame_observer->AttachFrame( + browser->GetWebFrameImpl(render_frame->GetWebFrame()).get()); + } +} + +void CefBrowserManager::RenderViewCreated(content::RenderView* render_view, + bool& browser_created, + base::Optional& is_windowless) { + MaybeCreateBrowser(render_view, render_view->GetMainRenderFrame(), + &browser_created, &is_windowless); +} + +void CefBrowserManager::DevToolsAgentAttached() { + ++devtools_agent_count_; +} + +void CefBrowserManager::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. + // Restore the user-specified stack size here. + CefV8SetUncaughtExceptionStackSize(uncaught_exception_stack_size_); + } +} + +CefRefPtr CefBrowserManager::GetBrowserForView( + content::RenderView* view) { + BrowserMap::const_iterator it = browsers_.find(view); + if (it != browsers_.end()) + return it->second; + return nullptr; +} + +CefRefPtr CefBrowserManager::GetBrowserForMainFrame( + blink::WebFrame* frame) { + BrowserMap::const_iterator it = browsers_.begin(); + for (; it != browsers_.end(); ++it) { + content::RenderView* render_view = it->second->render_view(); + if (render_view && render_view->GetWebView() && + render_view->GetWebView()->MainFrame() == frame) { + return it->second; + } + } + + return nullptr; +} + +void CefBrowserManager::WebKitInitialized() { + const base::CommandLine* command_line = + base::CommandLine::ForCurrentProcess(); + + // Create global objects associated with the default Isolate. + CefV8IsolateCreated(); + + const CefAppManager::SchemeInfoList* schemes = + CefAppManager::Get()->GetCustomSchemes(); + if (!schemes->empty()) { + // Register the custom schemes. The |is_standard| value is excluded here + // because it's not explicitly registered with Blink. + CefAppManager::SchemeInfoList::const_iterator it = schemes->begin(); + for (; it != schemes->end(); ++it) { + const CefSchemeInfo& info = *it; + const blink::WebString& scheme = + blink::WebString::FromUTF8(info.scheme_name); + if (info.is_local) + blink_glue::RegisterURLSchemeAsLocal(scheme); + if (info.is_display_isolated) + blink::WebSecurityPolicy::RegisterURLSchemeAsDisplayIsolated(scheme); + if (info.is_secure) + blink_glue::RegisterURLSchemeAsSecure(scheme); + if (info.is_fetch_enabled) + blink_glue::RegisterURLSchemeAsSupportingFetchAPI(scheme); + } + } + + 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); + } + cross_origin_whitelist_entries_.clear(); + } + + // The number of stack trace frames to capture for uncaught exceptions. + if (command_line->HasSwitch(switches::kUncaughtExceptionStackSize)) { + int uncaught_exception_stack_size = 0; + base::StringToInt(command_line->GetSwitchValueASCII( + switches::kUncaughtExceptionStackSize), + &uncaught_exception_stack_size); + + if (uncaught_exception_stack_size > 0) { + uncaught_exception_stack_size_ = uncaught_exception_stack_size; + CefV8SetUncaughtExceptionStackSize(uncaught_exception_stack_size_); + } + } + + // Notify the render process handler. + CefRefPtr application = CefAppManager::Get()->GetApplication(); + if (application.get()) { + CefRefPtr handler = + application->GetRenderProcessHandler(); + if (handler.get()) + handler->OnWebKitInitialized(); + } +} + +CefRefPtr CefBrowserManager::MaybeCreateBrowser( + content::RenderView* render_view, + content::RenderFrame* render_frame, + bool* browser_created, + base::Optional* is_windowless) { + if (browser_created) + *browser_created = false; + + if (!render_view || !render_frame) + return nullptr; + + // Don't create another browser or guest view object if one already exists for + // the view. + auto browser = GetBrowserForView(render_view); + if (browser) { + if (is_windowless) { + *is_windowless = browser->is_windowless(); + } + return browser; + } + + auto guest_view = GetGuestViewForView(render_view); + if (guest_view) { + if (is_windowless) { + *is_windowless = guest_view->is_windowless(); + } + return nullptr; + } + + const int render_frame_routing_id = render_frame->GetRoutingID(); + + // Retrieve the browser information synchronously. This will also register + // the routing ids with the browser info object in the browser process. + CefProcessHostMsg_GetNewBrowserInfo_Params params; + content::RenderThread::Get()->Send(new CefProcessHostMsg_GetNewBrowserInfo( + render_frame_routing_id, ¶ms)); + + if (is_windowless) { + *is_windowless = params.is_windowless; + } + + if (params.browser_id == 0) { + // The popup may have been canceled during creation. + return nullptr; + } + + if (params.is_guest_view || params.browser_id < 0) { + // Don't create a CefBrowser for guest views, or if the new browser info + // response has timed out. + guest_views_.insert(std::make_pair( + render_view, std::make_unique(this, render_view, + params.is_windowless))); + return nullptr; + } + + 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. + CefRefPtr application = CefAppManager::Get()->GetApplication(); + if (application.get()) { + CefRefPtr handler = + application->GetRenderProcessHandler(); + if (handler.get()) { + CefRefPtr dictValuePtr( + new CefDictionaryValueImpl(¶ms.extra_info, false, true)); + handler->OnBrowserCreated(browser.get(), dictValuePtr.get()); + dictValuePtr->Detach(nullptr); + } + } + + if (browser_created) + *browser_created = true; + + return browser; +} + +void CefBrowserManager::OnBrowserDestroyed(CefBrowserImpl* browser) { + BrowserMap::iterator it = browsers_.begin(); + for (; it != browsers_.end(); ++it) { + if (it->second.get() == browser) { + browsers_.erase(it); + return; + } + } + + // No browser was found in the map. + NOTREACHED(); +} + +CefGuestView* CefBrowserManager::GetGuestViewForView( + content::RenderView* view) { + CEF_REQUIRE_RT_RETURN(nullptr); + + GuestViewMap::const_iterator it = guest_views_.find(view); + if (it != guest_views_.end()) + return it->second.get(); + return nullptr; +} + +void CefBrowserManager::OnGuestViewDestroyed(CefGuestView* guest_view) { + GuestViewMap::iterator it = guest_views_.begin(); + for (; it != guest_views_.end(); ++it) { + if (it->second.get() == guest_view) { + guest_views_.erase(it); + return; + } + } + + // No guest view was found in the map. + NOTREACHED(); +} + +// Enable deprecation warnings on Windows. See http://crbug.com/585142. +#if defined(OS_WIN) +#if defined(__clang__) +#pragma GCC diagnostic pop +#else +#pragma warning(pop) +#endif +#endif diff --git a/libcef/renderer/browser_manager.h b/libcef/renderer/browser_manager.h new file mode 100644 index 000000000..1bd1aa93f --- /dev/null +++ b/libcef/renderer/browser_manager.h @@ -0,0 +1,100 @@ +// Copyright 2015 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_RENDERER_BROWSER_MANAGER_H_ +#define CEF_LIBCEF_RENDERER_BROWSER_MANAGER_H_ +#pragma once + +#include +#include + +#include "include/internal/cef_ptr.h" + +#include "base/optional.h" + +namespace blink { +class WebFrame; +} + +namespace content { +class RenderFrame; +class RenderView; +} // namespace content + +struct Cef_CrossOriginWhiteListEntry_Params; +class CefBrowserImpl; +class CefGuestView; +class CefRenderFrameObserver; + +// Singleton object for managing BrowserImpl instances. Only accessed on the +// main renderer thread. +class CefBrowserManager { + public: + CefBrowserManager(); + ~CefBrowserManager(); + + // Returns this singleton instance of this class. + static CefBrowserManager* Get(); + + // Called from ContentRendererClient methods of the same name. + void RenderThreadConnected(); + void RenderFrameCreated(content::RenderFrame* render_frame, + CefRenderFrameObserver* render_frame_observer, + bool& browser_created, + base::Optional& is_windowless); + void RenderViewCreated(content::RenderView* render_view, + bool& browser_created, + base::Optional& is_windowless); + void DevToolsAgentAttached(); + void DevToolsAgentDetached(); + + // Returns the browser associated with the specified RenderView. + CefRefPtr GetBrowserForView(content::RenderView* view); + + // Returns the browser associated with the specified main WebFrame. + CefRefPtr GetBrowserForMainFrame(blink::WebFrame* frame); + + private: + friend class CefBrowserImpl; + friend class CefGuestView; + + void WebKitInitialized(); + + // Maybe create a new browser object, return the existing one, or return + // nullptr for guest views. + CefRefPtr MaybeCreateBrowser( + content::RenderView* render_view, + content::RenderFrame* render_frame, + bool* browser_created, + base::Optional* is_windowless); + + // Called from CefBrowserImpl::OnDestruct(). + void OnBrowserDestroyed(CefBrowserImpl* browser); + + // Returns the guest view associated with the specified RenderView if any. + CefGuestView* GetGuestViewForView(content::RenderView* view); + + // Called from CefGuestView::OnDestruct(). + void OnGuestViewDestroyed(CefGuestView* guest_view); + + // Map of RenderView pointers to CefBrowserImpl references. + typedef std::map> BrowserMap; + BrowserMap browsers_; + + // Map of RenderView poiners to CefGuestView implementations. + typedef std::map> + GuestViewMap; + GuestViewMap guest_views_; + + // Cross-origin white list entries that need to be registered with WebKit. + typedef std::vector CrossOriginList; + CrossOriginList cross_origin_whitelist_entries_; + + int devtools_agent_count_ = 0; + int uncaught_exception_stack_size_ = 0; + + DISALLOW_COPY_AND_ASSIGN(CefBrowserManager); +}; + +#endif // CEF_LIBCEF_RENDERER_BROWSER_MANAGER_H_ diff --git a/libcef/renderer/chrome/chrome_content_renderer_client_cef.cc b/libcef/renderer/chrome/chrome_content_renderer_client_cef.cc new file mode 100644 index 000000000..d67569886 --- /dev/null +++ b/libcef/renderer/chrome/chrome_content_renderer_client_cef.cc @@ -0,0 +1,98 @@ +// Copyright 2020 The Chromium Embedded Framework Authors. +// Portions copyright 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/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/thread_util.h" + +#include "content/public/renderer/render_thread.h" + +ChromeContentRendererClientCef::ChromeContentRendererClientCef() + : browser_manager_(new CefBrowserManager) {} + +ChromeContentRendererClientCef::~ChromeContentRendererClientCef() = default; + +scoped_refptr +ChromeContentRendererClientCef::GetCurrentTaskRunner() { + // Check if currently on the render thread. + if (CEF_CURRENTLY_ON_RT()) + return render_task_runner_; + return nullptr; +} + +void ChromeContentRendererClientCef::RenderThreadStarted() { + ChromeContentRendererClient::RenderThreadStarted(); + + render_task_runner_ = base::ThreadTaskRunnerHandle::Get(); + observer_ = std::make_unique(); + + content::RenderThread* thread = content::RenderThread::Get(); + thread->AddObserver(observer_.get()); +} + +void ChromeContentRendererClientCef::RenderThreadConnected() { + ChromeContentRendererClient::RenderThreadConnected(); + + browser_manager_->RenderThreadConnected(); +} + +void ChromeContentRendererClientCef::RenderFrameCreated( + content::RenderFrame* render_frame) { + ChromeContentRendererClient::RenderFrameCreated(render_frame); + + // Will delete itself when no longer needed. + CefRenderFrameObserver* render_frame_observer = + new CefRenderFrameObserver(render_frame); + + bool browser_created; + base::Optional is_windowless; + browser_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"; + } +} + +void ChromeContentRendererClientCef::RenderViewCreated( + content::RenderView* render_view) { + ChromeContentRendererClient::RenderViewCreated(render_view); + + bool browser_created; + base::Optional is_windowless; + browser_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"; + } +} + +void ChromeContentRendererClientCef::DevToolsAgentAttached() { + // WebWorkers may be creating agents on a different thread. + if (!render_task_runner_->BelongsToCurrentThread()) { + render_task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&ChromeContentRendererClientCef::DevToolsAgentAttached, + base::Unretained(this))); + return; + } + + browser_manager_->DevToolsAgentAttached(); +} + +void ChromeContentRendererClientCef::DevToolsAgentDetached() { + // WebWorkers may be creating agents on a different thread. + if (!render_task_runner_->BelongsToCurrentThread()) { + render_task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&ChromeContentRendererClientCef::DevToolsAgentDetached, + base::Unretained(this))); + return; + } + + browser_manager_->DevToolsAgentDetached(); +} diff --git a/libcef/renderer/chrome/chrome_content_renderer_client_cef.h b/libcef/renderer/chrome/chrome_content_renderer_client_cef.h new file mode 100644 index 000000000..af616312d --- /dev/null +++ b/libcef/renderer/chrome/chrome_content_renderer_client_cef.h @@ -0,0 +1,51 @@ +// Copyright 2020 The Chromium Embedded Framework Authors. +// Portions copyright 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_RENDERER_CHROME_CHROME_CONTENT_RENDERER_CLIENT_CEF_ +#define CEF_LIBCEF_RENDERER_CHROME_CHROME_CONTENT_RENDERER_CLIENT_CEF_ + +#include + +#include "base/macros.h" +#include "base/memory/scoped_refptr.h" +#include "base/single_thread_task_runner.h" +#include "chrome/renderer/chrome_content_renderer_client.h" + +class CefBrowserManager; +class CefRenderThreadObserver; + +// CEF override of ChromeContentRendererClient. +class ChromeContentRendererClientCef : public ChromeContentRendererClient { + public: + ChromeContentRendererClientCef(); + ~ChromeContentRendererClientCef() override; + + // Render thread task runner. + base::SingleThreadTaskRunner* render_task_runner() const { + return render_task_runner_.get(); + } + + // Returns the task runner for the current thread. Returns NULL if the current + // thread is not the main render process thread. + scoped_refptr GetCurrentTaskRunner(); + + // ChromeContentRendererClient overrides. + void RenderThreadStarted() override; + void RenderThreadConnected() override; + void RenderFrameCreated(content::RenderFrame* render_frame) override; + void RenderViewCreated(content::RenderView* render_view) override; + void DevToolsAgentAttached() override; + void DevToolsAgentDetached() override; + + private: + std::unique_ptr browser_manager_; + + scoped_refptr render_task_runner_; + std::unique_ptr observer_; + + DISALLOW_COPY_AND_ASSIGN(ChromeContentRendererClientCef); +}; + +#endif // CEF_LIBCEF_RENDERER_CHROME_CHROME_CONTENT_RENDERER_CLIENT_CEF_ diff --git a/libcef/renderer/extensions/extensions_renderer_client.cc b/libcef/renderer/extensions/extensions_renderer_client.cc index a0c16f247..90a99b196 100644 --- a/libcef/renderer/extensions/extensions_renderer_client.cc +++ b/libcef/renderer/extensions/extensions_renderer_client.cc @@ -4,9 +4,8 @@ #include "libcef/renderer/extensions/extensions_renderer_client.h" -#include "libcef/common/cef_messages.h" +#include "libcef/renderer/alloy/alloy_render_thread_observer.h" #include "libcef/renderer/extensions/extensions_dispatcher_delegate.h" -#include "libcef/renderer/render_thread_observer.h" #include "base/command_line.h" #include "chrome/common/url_constants.h" @@ -50,7 +49,7 @@ CefExtensionsRendererClient::CefExtensionsRendererClient() {} CefExtensionsRendererClient::~CefExtensionsRendererClient() {} bool CefExtensionsRendererClient::IsIncognitoProcess() const { - return CefRenderThreadObserver::is_incognito_process(); + return AlloyRenderThreadObserver::is_incognito_process(); } int CefExtensionsRendererClient::GetLowestIsolatedWorldId() const { diff --git a/libcef/renderer/render_frame_observer.cc b/libcef/renderer/render_frame_observer.cc index 80e30f820..ebda9c4ed 100644 --- a/libcef/renderer/render_frame_observer.cc +++ b/libcef/renderer/render_frame_observer.cc @@ -25,8 +25,6 @@ #include "content/public/renderer/render_frame.h" #include "content/public/renderer/render_view.h" -#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h" -#include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h" #include "third_party/blink/public/web/blink.h" #include "third_party/blink/public/web/web_document.h" #include "third_party/blink/public/web/web_local_frame.h" @@ -36,19 +34,7 @@ CefRenderFrameObserver::CefRenderFrameObserver( content::RenderFrame* render_frame) : content::RenderFrameObserver(render_frame) {} -CefRenderFrameObserver::~CefRenderFrameObserver() {} - -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); -} +CefRenderFrameObserver::~CefRenderFrameObserver() = default; void CefRenderFrameObserver::DidCommitProvisionalLoad( ui::PageTransition transition) { diff --git a/libcef/renderer/render_frame_observer.h b/libcef/renderer/render_frame_observer.h index e1fbfca88..efd93bc65 100644 --- a/libcef/renderer/render_frame_observer.h +++ b/libcef/renderer/render_frame_observer.h @@ -6,8 +6,6 @@ #define LIBCEF_RENDERER_RENDER_FRAME_OBSERVER_H_ #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; @@ -22,12 +20,6 @@ class CefRenderFrameObserver : public content::RenderFrameObserver { ~CefRenderFrameObserver() 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; void DidCommitProvisionalLoad(ui::PageTransition transition) override; void DidFailProvisionalLoad() override; void DidFinishLoad() override; @@ -41,19 +33,12 @@ class CefRenderFrameObserver : public content::RenderFrameObserver { void OnDestruct() override; bool OnMessageReceived(const IPC::Message& message) override; - service_manager::BinderRegistry* registry() { return ®istry_; } - blink::AssociatedInterfaceRegistry* associated_interfaces() { - return &associated_interfaces_; - } - void AttachFrame(CefFrameImpl* frame); private: void OnLoadStart(); void OnLoadError(); - service_manager::BinderRegistry registry_; - blink::AssociatedInterfaceRegistry associated_interfaces_; CefFrameImpl* frame_ = nullptr; DISALLOW_COPY_AND_ASSIGN(CefRenderFrameObserver); diff --git a/libcef/renderer/render_thread_observer.cc b/libcef/renderer/render_thread_observer.cc index 5bd79f67a..1f92fcf4f 100644 --- a/libcef/renderer/render_thread_observer.cc +++ b/libcef/renderer/render_thread_observer.cc @@ -6,42 +6,14 @@ #include "libcef/renderer/render_thread_observer.h" #include "libcef/common/cef_messages.h" -#include "libcef/common/net/net_resource_provider.h" #include "libcef/renderer/blink_glue.h" -#include "components/visitedlink/renderer/visitedlink_reader.h" -#include "content/public/child/child_thread.h" -#include "content/public/renderer/render_thread.h" -#include "mojo/public/cpp/bindings/strong_binding.h" -#include "net/base/net_module.h" -#include "services/service_manager/public/cpp/connector.h" -#include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.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" -namespace { - -chrome::mojom::DynamicParams* GetDynamicConfigParams() { - static base::NoDestructor dynamic_params; - return dynamic_params.get(); -} - -} // namespace - -bool CefRenderThreadObserver::is_incognito_process_ = false; - -CefRenderThreadObserver::CefRenderThreadObserver() { - net::NetModule::SetResourceProvider(NetResourceProvider); -} - -CefRenderThreadObserver::~CefRenderThreadObserver() {} - -// static -const chrome::mojom::DynamicParams& -CefRenderThreadObserver::GetDynamicParams() { - return *GetDynamicConfigParams(); -} +CefRenderThreadObserver::CefRenderThreadObserver() = default; +CefRenderThreadObserver::~CefRenderThreadObserver() = default; bool CefRenderThreadObserver::OnControlMessageReceived( const IPC::Message& message) { @@ -56,39 +28,6 @@ bool CefRenderThreadObserver::OnControlMessageReceived( return handled; } -void CefRenderThreadObserver::RegisterMojoInterfaces( - blink::AssociatedInterfaceRegistry* associated_interfaces) { - associated_interfaces->AddInterface(base::Bind( - &CefRenderThreadObserver::OnRendererConfigurationAssociatedRequest, - base::Unretained(this))); -} - -void CefRenderThreadObserver::UnregisterMojoInterfaces( - blink::AssociatedInterfaceRegistry* associated_interfaces) { - associated_interfaces->RemoveInterface( - chrome::mojom::RendererConfiguration::Name_); -} - -void CefRenderThreadObserver::SetInitialConfiguration( - bool is_incognito_process, - mojo::PendingReceiver chromeos_listener) { - is_incognito_process_ = is_incognito_process; -} - -void CefRenderThreadObserver::SetConfiguration( - chrome::mojom::DynamicParamsPtr params) { - *GetDynamicConfigParams() = std::move(*params); -} - -void CefRenderThreadObserver::SetContentSettingRules( - const RendererContentSettingRules& rules) {} - -void CefRenderThreadObserver::OnRendererConfigurationAssociatedRequest( - mojo::PendingAssociatedReceiver - receiver) { - renderer_configuration_receivers_.Add(this, std::move(receiver)); -} - void CefRenderThreadObserver::OnModifyCrossOriginWhitelistEntry( bool add, const Cef_CrossOriginWhiteListEntry_Params& params) { diff --git a/libcef/renderer/render_thread_observer.h b/libcef/renderer/render_thread_observer.h index 2044fc87c..cae0e6a50 100644 --- a/libcef/renderer/render_thread_observer.h +++ b/libcef/renderer/render_thread_observer.h @@ -9,47 +9,19 @@ #include #include "base/compiler_specific.h" -#include "chrome/common/renderer_configuration.mojom.h" -#include "components/content_settings/core/common/content_settings.h" #include "content/public/renderer/render_thread_observer.h" -#include "mojo/public/cpp/bindings/associated_binding_set.h" -#include "mojo/public/cpp/bindings/associated_receiver_set.h" struct Cef_CrossOriginWhiteListEntry_Params; // This class sends and receives control messages in the renderer process. -class CefRenderThreadObserver : public content::RenderThreadObserver, - public chrome::mojom::RendererConfiguration { +class CefRenderThreadObserver : public content::RenderThreadObserver { public: CefRenderThreadObserver(); ~CefRenderThreadObserver() override; - static bool is_incognito_process() { return is_incognito_process_; } - - // Return the dynamic parameters - those that may change while the - // render process is running. - static const chrome::mojom::DynamicParams& GetDynamicParams(); - private: // content::RenderThreadObserver: bool OnControlMessageReceived(const IPC::Message& message) override; - void RegisterMojoInterfaces( - blink::AssociatedInterfaceRegistry* associated_interfaces) override; - void UnregisterMojoInterfaces( - blink::AssociatedInterfaceRegistry* associated_interfaces) override; - - // chrome::mojom::RendererConfiguration: - void SetInitialConfiguration( - bool is_incognito_process, - mojo::PendingReceiver chromeos_listener) - override; - void SetConfiguration(chrome::mojom::DynamicParamsPtr params) override; - void SetContentSettingRules( - const RendererContentSettingRules& rules) override; - - void OnRendererConfigurationAssociatedRequest( - mojo::PendingAssociatedReceiver - receiver); // Message handlers called on the render thread. void OnModifyCrossOriginWhitelistEntry( @@ -57,11 +29,6 @@ class CefRenderThreadObserver : public content::RenderThreadObserver, const Cef_CrossOriginWhiteListEntry_Params& params); void OnClearCrossOriginWhitelist(); - static bool is_incognito_process_; - - mojo::AssociatedReceiverSet - renderer_configuration_receivers_; - DISALLOW_COPY_AND_ASSIGN(CefRenderThreadObserver); }; diff --git a/libcef_dll/cpptoc/browser_process_handler_cpptoc.cc b/libcef_dll/cpptoc/browser_process_handler_cpptoc.cc index ceb5b402a..a826418f6 100644 --- a/libcef_dll/cpptoc/browser_process_handler_cpptoc.cc +++ b/libcef_dll/cpptoc/browser_process_handler_cpptoc.cc @@ -9,18 +9,56 @@ // implementations. See the translator.README.txt file in the tools directory // for more information. // -// $hash=94217ee1df26d037136df93adda612261606c569$ +// $hash=51e9102befaf6a5e88a1a409932316a7571d84f8$ // #include "libcef_dll/cpptoc/browser_process_handler_cpptoc.h" #include "libcef_dll/cpptoc/client_cpptoc.h" #include "libcef_dll/cpptoc/print_handler_cpptoc.h" #include "libcef_dll/ctocpp/command_line_ctocpp.h" +#include "libcef_dll/transfer_util.h" namespace { // MEMBER FUNCTIONS - Body may be edited by hand. +void CEF_CALLBACK browser_process_handler_get_cookieable_schemes( + struct _cef_browser_process_handler_t* self, + cef_string_list_t schemes, + int* include_defaults) { + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + DCHECK(self); + if (!self) + return; + // Verify param: schemes; type: string_vec_byref + DCHECK(schemes); + if (!schemes) + return; + // Verify param: include_defaults; type: bool_byref + DCHECK(include_defaults); + if (!include_defaults) + return; + + // Translate param: schemes; type: string_vec_byref + std::vector schemesList; + transfer_string_list_contents(schemes, schemesList); + // Translate param: include_defaults; type: bool_byref + bool include_defaultsBool = + (include_defaults && *include_defaults) ? true : false; + + // Execute + CefBrowserProcessHandlerCppToC::Get(self)->GetCookieableSchemes( + schemesList, include_defaultsBool); + + // Restore param: schemes; type: string_vec_byref + cef_string_list_clear(schemes); + transfer_string_list_contents(schemesList, schemes); + // Restore param: include_defaults; type: bool_byref + if (include_defaults) + *include_defaults = include_defaultsBool ? true : false; +} + void CEF_CALLBACK browser_process_handler_on_context_initialized( struct _cef_browser_process_handler_t* self) { // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING @@ -103,6 +141,8 @@ struct _cef_client_t* CEF_CALLBACK browser_process_handler_get_default_client( // CONSTRUCTOR - Do not edit by hand. CefBrowserProcessHandlerCppToC::CefBrowserProcessHandlerCppToC() { + GetStruct()->get_cookieable_schemes = + browser_process_handler_get_cookieable_schemes; GetStruct()->on_context_initialized = browser_process_handler_on_context_initialized; GetStruct()->on_before_child_process_launch = diff --git a/libcef_dll/ctocpp/browser_process_handler_ctocpp.cc b/libcef_dll/ctocpp/browser_process_handler_ctocpp.cc index d3e015502..5f04670ab 100644 --- a/libcef_dll/ctocpp/browser_process_handler_ctocpp.cc +++ b/libcef_dll/ctocpp/browser_process_handler_ctocpp.cc @@ -9,16 +9,48 @@ // implementations. See the translator.README.txt file in the tools directory // for more information. // -// $hash=9e8f283905d68b7b97c13a568040dc12c2859ad3$ +// $hash=d591d5b715b75ccb712f18d29774836580bec514$ // #include "libcef_dll/ctocpp/browser_process_handler_ctocpp.h" #include "libcef_dll/cpptoc/command_line_cpptoc.h" #include "libcef_dll/ctocpp/client_ctocpp.h" #include "libcef_dll/ctocpp/print_handler_ctocpp.h" +#include "libcef_dll/transfer_util.h" // VIRTUAL METHODS - Body may be edited by hand. +NO_SANITIZE("cfi-icall") +void CefBrowserProcessHandlerCToCpp::GetCookieableSchemes( + std::vector& schemes, + bool& include_defaults) { + cef_browser_process_handler_t* _struct = GetStruct(); + if (CEF_MEMBER_MISSING(_struct, get_cookieable_schemes)) + return; + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Translate param: schemes; type: string_vec_byref + cef_string_list_t schemesList = cef_string_list_alloc(); + DCHECK(schemesList); + if (schemesList) + transfer_string_list_contents(schemes, schemesList); + // Translate param: include_defaults; type: bool_byref + int include_defaultsInt = include_defaults; + + // Execute + _struct->get_cookieable_schemes(_struct, schemesList, &include_defaultsInt); + + // Restore param:schemes; type: string_vec_byref + if (schemesList) { + schemes.clear(); + transfer_string_list_contents(schemesList, schemes); + cef_string_list_free(schemesList); + } + // Restore param:include_defaults; type: bool_byref + include_defaults = include_defaultsInt ? true : false; +} + NO_SANITIZE("cfi-icall") void CefBrowserProcessHandlerCToCpp::OnContextInitialized() { cef_browser_process_handler_t* _struct = GetStruct(); diff --git a/libcef_dll/ctocpp/browser_process_handler_ctocpp.h b/libcef_dll/ctocpp/browser_process_handler_ctocpp.h index cc6c1b456..0b09108fb 100644 --- a/libcef_dll/ctocpp/browser_process_handler_ctocpp.h +++ b/libcef_dll/ctocpp/browser_process_handler_ctocpp.h @@ -9,7 +9,7 @@ // implementations. See the translator.README.txt file in the tools directory // for more information. // -// $hash=857a8ad51f8b7ca9e62b9ce35d0cf510d84fb8b1$ +// $hash=be0f9481659ed425a96ebfb004f6e5590953cf49$ // #ifndef CEF_LIBCEF_DLL_CTOCPP_BROWSER_PROCESS_HANDLER_CTOCPP_H_ @@ -20,6 +20,7 @@ #error This file can be included DLL-side only #endif +#include #include "include/capi/cef_browser_process_handler_capi.h" #include "include/cef_browser_process_handler.h" #include "libcef_dll/ctocpp/ctocpp_ref_counted.h" @@ -35,6 +36,8 @@ class CefBrowserProcessHandlerCToCpp virtual ~CefBrowserProcessHandlerCToCpp(); // CefBrowserProcessHandler methods. + void GetCookieableSchemes(std::vector& schemes, + bool& include_defaults) override; void OnContextInitialized() override; void OnBeforeChildProcessLaunch( CefRefPtr command_line) override; diff --git a/patch/patch.cfg b/patch/patch.cfg index 61b876bd9..155e03eb3 100644 --- a/patch/patch.cfg +++ b/patch/patch.cfg @@ -225,6 +225,9 @@ patches = [ { # Don't initialize ExtensionSystemFactory when extensions are disabled. # https://bitbucket.org/chromiumembedded/cef/issues/2359 + # + # Remove NOTREACHED() in GetContentSettingFromRulesImpl triggered by + # NavigationTest.LoadCrossOriginLoadURL with the chrome runtime. 'name': 'chrome_browser_content_settings', }, { diff --git a/patch/patches/chrome_browser_browser.patch b/patch/patches/chrome_browser_browser.patch index 8a514f1a9..eca6ed741 100644 --- a/patch/patches/chrome_browser_browser.patch +++ b/patch/patches/chrome_browser_browser.patch @@ -1,5 +1,19 @@ +diff --git chrome/browser/browser_about_handler.cc chrome/browser/browser_about_handler.cc +index af2282034336..c49d920f73b5 100644 +--- chrome/browser/browser_about_handler.cc ++++ chrome/browser/browser_about_handler.cc +@@ -95,6 +95,9 @@ bool HandleNonNavigationAboutURL(const GURL& url) { + FROM_HERE, base::BindOnce(&chrome::AttemptExit)); + return true; + } ++ if (base::LowerCaseEqualsASCII(spec, "chrome://ignore/")) { ++ return true; ++ } + + return false; + } diff --git chrome/browser/ui/browser.cc chrome/browser/ui/browser.cc -index 71ec3bbbf1b6..8b99a3ac7de2 100644 +index 71ec3bbbf1b6..10d47a4f021e 100644 --- chrome/browser/ui/browser.cc +++ chrome/browser/ui/browser.cc @@ -257,6 +257,20 @@ @@ -37,7 +51,58 @@ index 71ec3bbbf1b6..8b99a3ac7de2 100644 tab_strip_model_->AddObserver(this); location_bar_model_ = std::make_unique( -@@ -1713,6 +1734,8 @@ void Browser::LoadingStateChanged(WebContents* source, +@@ -1318,6 +1339,14 @@ content::KeyboardEventProcessingResult Browser::PreHandleKeyboardEvent( + if (exclusive_access_manager_->HandleUserKeyEvent(event)) + return content::KeyboardEventProcessingResult::HANDLED; + ++#if BUILDFLAG(ENABLE_CEF) ++ if (cef_browser_delegate_) { ++ auto result = cef_browser_delegate_->PreHandleKeyboardEvent(source, event); ++ if (result != content::KeyboardEventProcessingResult::NOT_HANDLED) ++ return result; ++ } ++#endif ++ + return window()->PreHandleKeyboardEvent(event); + } + +@@ -1325,8 +1354,18 @@ bool Browser::HandleKeyboardEvent(content::WebContents* source, + const NativeWebKeyboardEvent& event) { + DevToolsWindow* devtools_window = + DevToolsWindow::GetInstanceForInspectedWebContents(source); +- return (devtools_window && devtools_window->ForwardKeyboardEvent(event)) || +- window()->HandleKeyboardEvent(event); ++ if (devtools_window && devtools_window->ForwardKeyboardEvent(event)) { ++ return true; ++ } ++ ++#if BUILDFLAG(ENABLE_CEF) ++ if (cef_browser_delegate_ && ++ cef_browser_delegate_->HandleKeyboardEvent(source, event)) { ++ return true; ++ } ++#endif ++ ++ return window()->HandleKeyboardEvent(event); + } + + bool Browser::TabsNeedBeforeUnloadFired() { +@@ -1601,6 +1640,14 @@ WebContents* Browser::OpenURLFromTab(WebContents* source, + return window->OpenURLFromTab(source, params); + } + ++#if BUILDFLAG(ENABLE_CEF) ++ if (cef_browser_delegate_) { ++ auto web_contents = cef_browser_delegate_->OpenURLFromTab(source, params); ++ if (!web_contents) ++ return nullptr; ++ } ++#endif ++ + NavigateParams nav_params(this, params.url, params.transition); + nav_params.FillNavigateParamsFromOpenURLParams(params); + nav_params.source_contents = source; +@@ -1713,6 +1760,8 @@ void Browser::LoadingStateChanged(WebContents* source, bool to_different_document) { ScheduleUIUpdate(source, content::INVALIDATE_TYPE_LOAD); UpdateWindowForLoadingStateChanged(source, to_different_document); @@ -46,7 +111,7 @@ index 71ec3bbbf1b6..8b99a3ac7de2 100644 } void Browser::CloseContents(WebContents* source) { -@@ -1740,6 +1763,8 @@ void Browser::SetContentsBounds(WebContents* source, const gfx::Rect& bounds) { +@@ -1740,6 +1789,8 @@ void Browser::SetContentsBounds(WebContents* source, const gfx::Rect& bounds) { } void Browser::UpdateTargetURL(WebContents* source, const GURL& url) { @@ -55,7 +120,7 @@ index 71ec3bbbf1b6..8b99a3ac7de2 100644 if (!GetStatusBubble()) return; -@@ -1747,6 +1772,17 @@ void Browser::UpdateTargetURL(WebContents* source, const GURL& url) { +@@ -1747,6 +1798,17 @@ void Browser::UpdateTargetURL(WebContents* source, const GURL& url) { GetStatusBubble()->SetURL(url); } @@ -73,7 +138,18 @@ index 71ec3bbbf1b6..8b99a3ac7de2 100644 void Browser::ContentsMouseEvent(WebContents* source, bool motion, bool exited) { -@@ -1899,6 +1935,8 @@ void Browser::RendererResponsive( +@@ -1863,6 +1925,10 @@ void Browser::WebContentsCreated(WebContents* source_contents, + + // Make the tab show up in the task manager. + task_manager::WebContentsTags::CreateForTabContents(new_contents); ++ ++ CALL_CEF_DELEGATE(WebContentsCreated, source_contents, ++ opener_render_process_id, opener_render_frame_id, ++ frame_name, target_url, new_contents); + } + + void Browser::PortalWebContentsCreated(WebContents* portal_web_contents) { +@@ -1899,6 +1965,8 @@ void Browser::RendererResponsive( void Browser::DidNavigateMainFramePostCommit(WebContents* web_contents) { if (web_contents == tab_strip_model_->GetActiveWebContents()) UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_TAB_STATE); @@ -82,7 +158,7 @@ index 71ec3bbbf1b6..8b99a3ac7de2 100644 } content::JavaScriptDialogManager* Browser::GetJavaScriptDialogManager( -@@ -1949,11 +1987,15 @@ void Browser::EnterFullscreenModeForTab( +@@ -1949,11 +2017,15 @@ void Browser::EnterFullscreenModeForTab( const blink::mojom::FullscreenOptions& options) { exclusive_access_manager_->fullscreen_controller()->EnterFullscreenModeForTab( requesting_frame, options.display_id); @@ -98,7 +174,7 @@ index 71ec3bbbf1b6..8b99a3ac7de2 100644 } bool Browser::IsFullscreenForTabOrPending(const WebContents* web_contents) { -@@ -2814,6 +2856,8 @@ void Browser::SetAsDelegate(WebContents* web_contents, bool set_delegate) { +@@ -2814,6 +2886,8 @@ void Browser::SetAsDelegate(WebContents* web_contents, bool set_delegate) { content_translate_driver->RemoveObserver(this); BookmarkTabHelper::FromWebContents(web_contents)->RemoveObserver(this); } @@ -178,3 +254,40 @@ index ab2a03e6e878..aef94abf4fd8 100644 const base::ElapsedTimer creation_timer_; // Stores the list of browser windows showing via a menu. +diff --git chrome/browser/ui/browser_navigator.cc chrome/browser/ui/browser_navigator.cc +index 6d6a3b90dcad..fbfe4a0c959c 100644 +--- chrome/browser/ui/browser_navigator.cc ++++ chrome/browser/ui/browser_navigator.cc +@@ -435,6 +435,13 @@ std::unique_ptr CreateTargetContents( + std::unique_ptr target_contents = + WebContents::Create(create_params); + ++#if BUILDFLAG(ENABLE_CEF) ++ auto cef_delegate = params.browser->cef_delegate(); ++ if (cef_delegate) { ++ cef_delegate->OnWebContentsCreated(target_contents.get()); ++ } ++#endif ++ + // New tabs can have WebUI URLs that will make calls back to arbitrary + // tab helpers, so the entire set of tab helpers needs to be set up + // immediately. +diff --git chrome/browser/ui/browser_tabstrip.cc chrome/browser/ui/browser_tabstrip.cc +index c8df2ade2443..0e350adda289 100644 +--- chrome/browser/ui/browser_tabstrip.cc ++++ chrome/browser/ui/browser_tabstrip.cc +@@ -28,9 +28,13 @@ void AddTabAt(Browser* browser, + // Time new tab page creation time. We keep track of the timing data in + // WebContents, but we want to include the time it takes to create the + // WebContents object too. ++ // For CEF use a PageTransition that matches ++ // CefFrameHostImpl::kPageTransitionExplicit. + base::TimeTicks new_tab_start_time = base::TimeTicks::Now(); + NavigateParams params(browser, url.is_empty() ? browser->GetNewTabURL() : url, +- ui::PAGE_TRANSITION_TYPED); ++ static_cast( ++ ui::PAGE_TRANSITION_TYPED | ++ ui::PAGE_TRANSITION_FROM_ADDRESS_BAR)); + params.disposition = foreground ? WindowOpenDisposition::NEW_FOREGROUND_TAB + : WindowOpenDisposition::NEW_BACKGROUND_TAB; + params.tabstrip_index = idx; diff --git a/patch/patches/chrome_browser_content_settings.patch b/patch/patches/chrome_browser_content_settings.patch index 829998d28..83b6025e1 100644 --- a/patch/patches/chrome_browser_content_settings.patch +++ b/patch/patches/chrome_browser_content_settings.patch @@ -1,12 +1,12 @@ diff --git chrome/browser/content_settings/host_content_settings_map_factory.cc chrome/browser/content_settings/host_content_settings_map_factory.cc -index 3e2d1221d91e..b0572e99c613 100644 +index 3e2d1221d91e..4fbf30796bdb 100644 --- chrome/browser/content_settings/host_content_settings_map_factory.cc +++ chrome/browser/content_settings/host_content_settings_map_factory.cc @@ -8,6 +8,7 @@ #include "base/feature_list.h" #include "build/buildflag.h" -+#include "cef/libcef/features/features.h" ++#include "cef/libcef/features/runtime.h" #include "chrome/browser/profiles/off_the_record_profile_impl.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/search_engines/template_url_service_factory.h" @@ -26,7 +26,7 @@ index 3e2d1221d91e..b0572e99c613 100644 #endif #if BUILDFLAG(ENABLE_EXTENSIONS) +#if BUILDFLAG(ENABLE_CEF) -+ if (extensions::ExtensionsEnabled()) { ++ if (!cef::IsAlloyRuntimeEnabled() || extensions::ExtensionsEnabled()) { +#endif DependsOn( extensions::ExtensionsBrowserClient::Get()->GetExtensionSystemFactory()); @@ -41,7 +41,7 @@ index 3e2d1221d91e..b0572e99c613 100644 #if BUILDFLAG(ENABLE_EXTENSIONS) +#if BUILDFLAG(ENABLE_CEF) -+ if (extensions::ExtensionsEnabled()) { ++ if (!cef::IsAlloyRuntimeEnabled() || extensions::ExtensionsEnabled()) { +#endif // These must be registered before before the HostSettings are passed over to // the IOThread. Simplest to do this on construction. @@ -53,3 +53,16 @@ index 3e2d1221d91e..b0572e99c613 100644 #endif // BUILDFLAG(ENABLE_EXTENSIONS) #if BUILDFLAG(ENABLE_SUPERVISED_USERS) SupervisedUserSettingsService* supervised_service = +diff --git components/content_settings/renderer/content_settings_agent_impl.cc components/content_settings/renderer/content_settings_agent_impl.cc +index 450005f9fc0b..13fca8b3e2d2 100644 +--- components/content_settings/renderer/content_settings_agent_impl.cc ++++ components/content_settings/renderer/content_settings_agent_impl.cc +@@ -183,7 +183,7 @@ ContentSetting GetContentSettingFromRulesImpl( + return rule.GetContentSetting(); + } + } +- NOTREACHED(); ++ // NOTREACHED(); + return CONTENT_SETTING_DEFAULT; + } + diff --git a/patch/patches/chrome_plugins.patch b/patch/patches/chrome_plugins.patch index 1d2b93670..94ed2cd41 100644 --- a/patch/patches/chrome_plugins.patch +++ b/patch/patches/chrome_plugins.patch @@ -1,12 +1,12 @@ diff --git chrome/browser/plugins/plugin_info_host_impl.cc chrome/browser/plugins/plugin_info_host_impl.cc -index d789ee040ac5..58b45d5a56f2 100644 +index d789ee040ac5..19e5a5daa343 100644 --- chrome/browser/plugins/plugin_info_host_impl.cc +++ chrome/browser/plugins/plugin_info_host_impl.cc @@ -18,6 +18,7 @@ #include "base/task_runner_util.h" #include "build/branding_buildflags.h" #include "build/build_config.h" -+#include "cef/libcef/features/features.h" ++#include "cef/libcef/features/runtime.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/content_settings/host_content_settings_map_factory.h" #include "chrome/browser/plugins/chrome_plugin_service_filter.h" @@ -49,40 +49,32 @@ index d789ee040ac5..58b45d5a56f2 100644 + +#if BUILDFLAG(ENABLE_EXTENSIONS) +#if BUILDFLAG(ENABLE_CEF) -+ if (extensions::ExtensionsEnabled()) ++ if (!cef::IsAlloyRuntimeEnabled() || extensions::ExtensionsEnabled()) +#endif + extension_registry_ = extensions::ExtensionRegistry::Get(profile); +#endif } PluginInfoHostImpl::Context::~Context() {} -@@ -208,6 +221,7 @@ void PluginInfoHostImpl::PluginsLoaded( +@@ -208,7 +221,8 @@ void PluginInfoHostImpl::PluginsLoaded( plugin_metadata->identifier(), &output->status); } -+#if !BUILDFLAG(ENABLE_CEF) - if (output->status == chrome::mojom::PluginStatus::kNotFound) { +- if (output->status == chrome::mojom::PluginStatus::kNotFound) { ++ if (!cef::IsAlloyRuntimeEnabled() && ++ output->status == chrome::mojom::PluginStatus::kNotFound) { // Check to see if the component updater can fetch an implementation. std::unique_ptr cus_plugin_info = -@@ -216,7 +230,9 @@ void PluginInfoHostImpl::PluginsLoaded( - ComponentPluginLookupDone(params, std::move(output), std::move(callback), - std::move(plugin_metadata), - std::move(cus_plugin_info)); -- } else { -+ } else -+#endif // !BUILDFLAG(ENABLE_CEF) -+ { - GetPluginInfoFinish(params, std::move(output), std::move(callback), - std::move(plugin_metadata)); - } -@@ -229,6 +245,14 @@ void PluginInfoHostImpl::Context::DecidePluginStatus( + g_browser_process->component_updater()->GetComponentForMimeType( +@@ -229,6 +243,15 @@ void PluginInfoHostImpl::Context::DecidePluginStatus( PluginMetadata::SecurityStatus security_status, const std::string& plugin_identifier, chrome::mojom::PluginStatus* status) const { +#if BUILDFLAG(ENABLE_CEF) + // Don't override the user decision. -+ if (*status == chrome::mojom::PluginStatus::kBlocked || -+ *status == chrome::mojom::PluginStatus::kDisabled) { ++ if (cef::IsAlloyRuntimeEnabled() && ++ (*status == chrome::mojom::PluginStatus::kBlocked || ++ *status == chrome::mojom::PluginStatus::kDisabled)) { + return; + } +#endif @@ -90,30 +82,33 @@ index d789ee040ac5..58b45d5a56f2 100644 if (security_status == PluginMetadata::SECURITY_STATUS_FULLY_TRUSTED) { *status = chrome::mojom::PluginStatus::kAllowed; return; -@@ -337,16 +361,35 @@ bool PluginInfoHostImpl::Context::FindEnabledPlugin( +@@ -337,17 +360,41 @@ bool PluginInfoHostImpl::Context::FindEnabledPlugin( return false; } + const bool is_main_frame = + main_frame_origin.IsSameOriginWith(url::Origin::Create(url)); ++ size_t i = 0; + +#if BUILDFLAG(ENABLE_CEF) -+ CefPluginServiceFilter* filter = static_cast( -+ PluginService::GetInstance()->GetFilter()); -+ DCHECK(filter); ++ if (cef::IsAlloyRuntimeEnabled()) { ++ CefPluginServiceFilter* filter = static_cast( ++ PluginService::GetInstance()->GetFilter()); ++ DCHECK(filter); + -+ size_t i = 0; -+ for (; i < matching_plugins.size(); ++i) { -+ if (filter->IsPluginAvailable(render_process_id_, render_frame_id, -+ url, is_main_frame, main_frame_origin, -+ &matching_plugins[i], status)) { -+ break; ++ for (; i < matching_plugins.size(); ++i) { ++ if (filter->IsPluginAvailable(render_process_id_, render_frame_id, ++ url, is_main_frame, main_frame_origin, ++ &matching_plugins[i], status)) { ++ break; ++ } + } -+ } -+#else // !BUILDFLAG(ENABLE_CEF) ++ } else { ++#endif // BUILDFLAG(ENABLE_CEF) ++ content::PluginServiceFilter* filter = PluginService::GetInstance()->GetFilter(); - size_t i = 0; +- size_t i = 0; for (; i < matching_plugins.size(); ++i) { if (!filter || filter->IsPluginAvailable(render_process_id_, render_frame_id, url, @@ -123,10 +118,14 @@ index d789ee040ac5..58b45d5a56f2 100644 break; } } -+#endif // !BUILDFLAG(ENABLE_CEF) ++#if BUILDFLAG(ENABLE_CEF) ++ } ++#endif ++ // If we broke out of the loop, we have found an enabled plugin. bool enabled = i < matching_plugins.size(); + if (!enabled) { diff --git chrome/browser/plugins/plugin_utils.cc chrome/browser/plugins/plugin_utils.cc index 1471b8f2a414..a856ce635719 100644 --- chrome/browser/plugins/plugin_utils.cc diff --git a/patch/patches/services_network_2622.patch b/patch/patches/services_network_2622.patch index 92584b2ef..de040c4ac 100644 --- a/patch/patches/services_network_2622.patch +++ b/patch/patches/services_network_2622.patch @@ -1,5 +1,5 @@ diff --git chrome/browser/net/profile_network_context_service.cc chrome/browser/net/profile_network_context_service.cc -index e5160aa3ff1a..87b037e517c2 100644 +index e5160aa3ff1a..f0ca556ed9e4 100644 --- chrome/browser/net/profile_network_context_service.cc +++ chrome/browser/net/profile_network_context_service.cc @@ -19,6 +19,7 @@ @@ -10,12 +10,8 @@ index e5160aa3ff1a..87b037e517c2 100644 #include "chrome/browser/browser_process.h" #include "chrome/browser/content_settings/cookie_settings_factory.h" #include "chrome/browser/content_settings/host_content_settings_map_factory.h" -@@ -668,9 +669,23 @@ void ProfileNetworkContextService::ConfigureNetworkContextParamsInternal( - network_context_params->cookie_manager_params = - CreateCookieManagerParams(profile_, *cookie_settings_); +@@ -670,7 +671,19 @@ void ProfileNetworkContextService::ConfigureNetworkContextParamsInternal( -+ network_context_params->cookieable_schemes = profile_->GetCookieableSchemes(); -+ // Configure on-disk storage for non-OTR profiles. OTR profiles just use // default behavior (in memory storage, default sizes). - if (!in_memory) { @@ -35,7 +31,7 @@ index e5160aa3ff1a..87b037e517c2 100644 PrefService* local_state = g_browser_process->local_state(); // Configure the HTTP cache path and size. base::FilePath base_cache_path; -@@ -683,7 +698,9 @@ void ProfileNetworkContextService::ConfigureNetworkContextParamsInternal( +@@ -683,7 +696,9 @@ void ProfileNetworkContextService::ConfigureNetworkContextParamsInternal( base_cache_path.Append(chrome::kCacheDirname); network_context_params->http_cache_max_size = local_state->GetInteger(prefs::kDiskCacheSize); @@ -45,22 +41,6 @@ index e5160aa3ff1a..87b037e517c2 100644 // Currently this just contains HttpServerProperties, but that will likely // change. network_context_params->http_server_properties_path = -diff --git chrome/browser/profiles/profile.h chrome/browser/profiles/profile.h -index a9dc5ed20a9f..3ce894531a21 100644 ---- chrome/browser/profiles/profile.h -+++ chrome/browser/profiles/profile.h -@@ -449,6 +449,11 @@ class Profile : public content::BrowserContext { - virtual bool ShouldRestoreOldSessionCookies() const; - virtual bool ShouldPersistSessionCookies() const; - -+ // Returns schemes that should be cookieable, if other than the defaults. -+ virtual base::Optional> GetCookieableSchemes() { -+ return base::nullopt; -+ } -+ - // Configures NetworkContextParams and CertVerifierCreationParams for the - // specified isolated app (or for the profile itself, if |relative_path| is - // empty). diff --git net/cookies/cookie_monster.cc net/cookies/cookie_monster.cc index 265deed0e52e..89d37ae6218a 100644 --- net/cookies/cookie_monster.cc diff --git a/patch/patches/webui_2037.patch b/patch/patches/webui_2037.patch index 95ee6f933..46e29e446 100644 --- a/patch/patches/webui_2037.patch +++ b/patch/patches/webui_2037.patch @@ -1,5 +1,5 @@ diff --git chrome/browser/feedback/system_logs/log_sources/chrome_internal_log_source.cc chrome/browser/feedback/system_logs/log_sources/chrome_internal_log_source.cc -index 0a144a99349f..7d835ce02b7f 100644 +index 0a144a99349f..c673f09e5652 100644 --- chrome/browser/feedback/system_logs/log_sources/chrome_internal_log_source.cc +++ chrome/browser/feedback/system_logs/log_sources/chrome_internal_log_source.cc @@ -10,6 +10,7 @@ @@ -14,7 +14,7 @@ index 0a144a99349f..7d835ce02b7f 100644 #include "base/task/thread_pool.h" #include "build/branding_buildflags.h" #include "build/build_config.h" -+#include "cef/libcef/features/features.h" ++#include "cef/libcef/features/runtime.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/data_reduction_proxy/data_reduction_proxy_chrome_settings.h" #include "chrome/browser/data_reduction_proxy/data_reduction_proxy_chrome_settings_factory.h" @@ -30,11 +30,12 @@ index 0a144a99349f..7d835ce02b7f 100644 response->emplace(kOsVersionTag, os_version); #endif -+#if !BUILDFLAG(ENABLE_CEF) -+ // CEF should avoid loading ProfileSyncServiceFactory which depends on a lot -+ // of unnecessary Chrome-specific factories. - PopulateSyncLogs(response.get()); -+#endif +- PopulateSyncLogs(response.get()); ++ if (!cef::IsAlloyRuntimeEnabled()) { ++ // Avoid loading ProfileSyncServiceFactory which depends on a lot of ++ // unnecessary Chrome-specific factories. ++ PopulateSyncLogs(response.get()); ++ } PopulateExtensionInfoLogs(response.get()); PopulatePowerApiLogs(response.get()); PopulateDataReductionProxyLogs(response.get()); diff --git a/tests/ceftests/client_app_delegates.cc b/tests/ceftests/client_app_delegates.cc index e86f60b68..653d362df 100644 --- a/tests/ceftests/client_app_delegates.cc +++ b/tests/ceftests/client_app_delegates.cc @@ -13,6 +13,11 @@ void CreateBrowserDelegates(ClientAppBrowser::DelegateSet& delegates) { extern void CreateAudioOutputTests(ClientAppBrowser::DelegateSet & delegates); CreateAudioOutputTests(delegates); + // Bring in navigation tests. + extern void CreateNavigationBrowserTests(ClientAppBrowser::DelegateSet & + delegates); + CreateNavigationBrowserTests(delegates); + // Bring in the plugin tests. extern void CreatePluginBrowserTests(ClientAppBrowser::DelegateSet & delegates); @@ -22,6 +27,11 @@ void CreateBrowserDelegates(ClientAppBrowser::DelegateSet& delegates) { extern void CreatePreferenceBrowserTests(ClientAppBrowser::DelegateSet & delegates); CreatePreferenceBrowserTests(delegates); + + // Bring in URLRequest tests. + extern void CreateURLRequestBrowserTests(ClientAppBrowser::DelegateSet & + delegates); + CreateURLRequestBrowserTests(delegates); } void CreateRenderDelegates(ClientAppRenderer::DelegateSet& delegates) { diff --git a/tests/ceftests/download_unittest.cc b/tests/ceftests/download_unittest.cc index 6408f6fe3..60273982f 100644 --- a/tests/ceftests/download_unittest.cc +++ b/tests/ceftests/download_unittest.cc @@ -402,7 +402,7 @@ class DownloadTestHandler : public TestHandler { } void VerifyResultsOnFileThread() { - EXPECT_TRUE(CefCurrentlyOn(TID_FILE)); + EXPECT_TRUE(CefCurrentlyOn(TID_FILE_USER_VISIBLE)); if (test_mode_ != PENDING) { // Verify the file contents. @@ -423,7 +423,7 @@ class DownloadTestHandler : public TestHandler { verified_results_ = true; // Clean up temp_dir_ on the FILE thread before destroying the test. CefPostTask( - TID_FILE, + TID_FILE_USER_VISIBLE, base::Bind(&DownloadTestHandler::VerifyResultsOnFileThread, this)); return; } diff --git a/tests/ceftests/navigation_unittest.cc b/tests/ceftests/navigation_unittest.cc index 9318205c4..0b31b124a 100644 --- a/tests/ceftests/navigation_unittest.cc +++ b/tests/ceftests/navigation_unittest.cc @@ -20,6 +20,22 @@ using client::ClientAppRenderer; namespace { +// Browser-side app delegate. +class NavigationBrowserTest : public client::ClientAppBrowser::Delegate { + public: + NavigationBrowserTest() {} + + void OnBeforeCommandLineProcessing( + CefRefPtr app, + CefRefPtr command_line) override { + // Disable popup blocking for the chrome runtime. + command_line->AppendSwitch("disable-popup-blocking"); + } + + private: + IMPLEMENT_REFCOUNTING(NavigationBrowserTest); +}; + const char kHNav1[] = "http://tests-hnav.com/nav1.html"; const char kHNav2[] = "http://tests-hnav.com/nav2.html"; const char kHNav3[] = "http://tests-hnav.com/nav3.html"; @@ -389,20 +405,28 @@ class HistoryNavTestHandler : public TestHandler { CefRefPtr frame, CefRefPtr request, CefRefPtr callback) override { - const NavListItem& item = kHNavList[nav_]; + if (IsChromeRuntimeEnabled() && request->GetResourceType() == RT_FAVICON) { + // Ignore favicon requests. + return RV_CANCEL; + } - EXPECT_EQ(RT_MAIN_FRAME, request->GetResourceType()); + const NavListItem& item = kHNavList[nav_]; + const std::string& url = request->GetURL(); + + EXPECT_EQ(RT_MAIN_FRAME, request->GetResourceType()) + << "nav=" << nav_ << " url=" << url; const auto transition_type = request->GetTransitionType(); if (item.action == NA_LOAD) { - EXPECT_EQ(kTransitionExplicitLoad, transition_type); + EXPECT_EQ(kTransitionExplicitLoad, transition_type) + << "nav=" << nav_ << " url=" << url; } else if (item.action == NA_BACK || item.action == NA_FORWARD) { - EXPECT_EQ(kTransitionExplicitForwardBack, transition_type); + EXPECT_EQ(kTransitionExplicitForwardBack, transition_type) + << "nav=" << nav_ << " url=" << url; } got_before_resource_load_[nav_].yes(); - std::string url = request->GetURL(); if (url == item.target) got_correct_target_[nav_].yes(); @@ -834,6 +858,11 @@ class RedirectTestHandler : public TestHandler { CefRefPtr frame, CefRefPtr request, CefRefPtr callback) override { + if (IsChromeRuntimeEnabled() && request->GetResourceType() == RT_FAVICON) { + // Ignore favicon requests. + return RV_CANCEL; + } + // Should be called for all but the second URL. std::string url = request->GetURL(); @@ -1441,6 +1470,11 @@ class OrderNavTestHandler : public TestHandler { CefRefPtr frame, CefRefPtr request, CefRefPtr callback) override { + if (IsChromeRuntimeEnabled() && request->GetResourceType() == RT_FAVICON) { + // Ignore favicon requests. + return RV_CANCEL; + } + EXPECT_EQ(RT_MAIN_FRAME, request->GetResourceType()); if (browser->IsPopup()) { @@ -1790,6 +1824,14 @@ class LoadNavTestHandler : public TestHandler { EXPECT_GT(browser_id_current_, 0); } + cef_transition_type_t ExpectedOpenURLTransitionType() const { + if (mode_ != LEFT_CLICK && IsChromeRuntimeEnabled()) { + // Because we triggered the navigation with LoadURL in OnOpenURLFromTab. + return kTransitionExplicitLoad; + } + return TT_LINK; + } + bool OnBeforeBrowse(CefRefPtr browser, CefRefPtr frame, CefRefPtr request, @@ -1800,7 +1842,7 @@ class LoadNavTestHandler : public TestHandler { EXPECT_EQ(kTransitionExplicitLoad, request->GetTransitionType()); EXPECT_FALSE(user_gesture); } else { - EXPECT_EQ(TT_LINK, request->GetTransitionType()); + EXPECT_EQ(ExpectedOpenURLTransitionType(), request->GetTransitionType()); if (mode_ == LEFT_CLICK) { EXPECT_TRUE(user_gesture); @@ -1849,6 +1891,14 @@ class LoadNavTestHandler : public TestHandler { got_open_url_from_tab_.yes(); + if (!cancel_in_open_url_ && IsChromeRuntimeEnabled()) { + // The chrome runtime may create a new popup window, which is not the + // behavior that this test expects. Instead, match the alloy runtime + // behavior by navigating in the current window. + browser->GetMainFrame()->LoadURL(target_url); + return true; + } + return cancel_in_open_url_; } @@ -1857,13 +1907,19 @@ class LoadNavTestHandler : public TestHandler { CefRefPtr frame, CefRefPtr request, CefRefPtr callback) override { + if (IsChromeRuntimeEnabled() && request->GetResourceType() == RT_FAVICON) { + // Ignore favicon requests. + return RV_CANCEL; + } + EXPECT_EQ(RT_MAIN_FRAME, request->GetResourceType()); const auto transition_type = request->GetTransitionType(); - if (mode_ == LOAD || request->GetURL() == kLoadNav1) + if (mode_ == LOAD || request->GetURL() == kLoadNav1) { EXPECT_EQ(kTransitionExplicitLoad, transition_type); - else - EXPECT_EQ(TT_LINK, transition_type); + } else { + EXPECT_EQ(ExpectedOpenURLTransitionType(), transition_type); + } EXPECT_GT(browser_id_current_, 0); EXPECT_EQ(browser_id_current_, browser->GetIdentifier()); @@ -1879,10 +1935,11 @@ class LoadNavTestHandler : public TestHandler { EXPECT_GT(browser_id_current_, 0); EXPECT_EQ(browser_id_current_, browser->GetIdentifier()); - if (mode_ == LOAD || frame->GetURL() == kLoadNav1) + if (mode_ == LOAD || frame->GetURL() == kLoadNav1) { EXPECT_EQ(kTransitionExplicitLoad, transition_type); - else - EXPECT_EQ(TT_LINK, transition_type); + } else { + EXPECT_EQ(ExpectedOpenURLTransitionType(), transition_type); + } got_load_start_.yes(); } @@ -2181,6 +2238,7 @@ class PopupSimultaneousTestHandler : public TestHandler { const std::string& url = browser->GetMainFrame()->GetURL(); for (size_t i = 0; i < kSimultPopupCount; ++i) { if (browser->GetIdentifier() == browser_id_[i]) { + EXPECT_TRUE(got_loading_state_change_[i]); EXPECT_STREQ(popup_url_[i].c_str(), url.c_str()) << i; got_before_close_[i].yes(); @@ -3473,6 +3531,7 @@ class ExtraInfoNavTestHandler : public TestHandler { IMPLEMENT_REFCOUNTING(ExtraInfoNavTestHandler); }; + } // namespace TEST(NavigationTest, ExtraInfo) { @@ -3489,3 +3548,10 @@ void CreateNavigationRendererTests(ClientAppRenderer::DelegateSet& delegates) { delegates.insert(new LoadNavRendererTest); delegates.insert(new ExtraInfoNavRendererTest); } + +// Entry point for creating plugin browser test objects. +// Called from client_app_delegates.cc. +void CreateNavigationBrowserTests( + client::ClientAppBrowser::DelegateSet& delegates) { + delegates.insert(new NavigationBrowserTest); +} diff --git a/tests/ceftests/request_unittest.cc b/tests/ceftests/request_unittest.cc index 653c0329a..cf7869754 100644 --- a/tests/ceftests/request_unittest.cc +++ b/tests/ceftests/request_unittest.cc @@ -313,6 +313,11 @@ class RequestSendRecvTestHandler : public TestHandler { int64 received_content_length) override { EXPECT_IO_THREAD(); + if (IsChromeRuntimeEnabled() && request->GetResourceType() == RT_FAVICON) { + // Ignore favicon requests. + return; + } + TestRequest(request); EXPECT_TRUE(request->IsReadOnly()); TestResponse(response); diff --git a/tests/ceftests/resource_manager_unittest.cc b/tests/ceftests/resource_manager_unittest.cc index fff45e7fe..88e1a418a 100644 --- a/tests/ceftests/resource_manager_unittest.cc +++ b/tests/ceftests/resource_manager_unittest.cc @@ -12,6 +12,7 @@ #include "include/wrapper/cef_scoped_temp_dir.h" #include "include/wrapper/cef_stream_resource_handler.h" #include "tests/ceftests/routing_test_handler.h" +#include "tests/ceftests/test_util.h" #include "tests/gtest/include/gtest/gtest.h" #include "tests/shared/browser/file_util.h" @@ -89,6 +90,11 @@ class ResourceManagerTestHandler : public RoutingTestHandler { CefRefPtr frame, CefRefPtr request, CefRefPtr callback) override { + if (IsChromeRuntimeEnabled() && request->GetResourceType() == RT_FAVICON) { + // Ignore favicon requests. + return RV_CANCEL; + } + return state_->manager_->OnBeforeResourceLoad(browser, frame, request, callback); } diff --git a/tests/ceftests/resource_request_handler_unittest.cc b/tests/ceftests/resource_request_handler_unittest.cc index 300692fd8..cec388389 100644 --- a/tests/ceftests/resource_request_handler_unittest.cc +++ b/tests/ceftests/resource_request_handler_unittest.cc @@ -608,6 +608,11 @@ class BasicResponseTest : public TestHandler { CefRefPtr request, CefRefPtr callback) override { EXPECT_IO_THREAD(); + if (IsChromeRuntimeEnabled() && request->GetResourceType() == RT_FAVICON) { + // Ignore favicon requests. + return RV_CANCEL; + } + EXPECT_EQ(browser_id_, browser->GetIdentifier()); EXPECT_TRUE(frame->IsMain()); @@ -779,6 +784,12 @@ class BasicResponseTest : public TestHandler { URLRequestStatus status, int64 received_content_length) override { EXPECT_IO_THREAD(); + + if (IsChromeRuntimeEnabled() && request->GetResourceType() == RT_FAVICON) { + // Ignore favicon requests. + return; + } + EXPECT_EQ(browser_id_, browser->GetIdentifier()); EXPECT_TRUE(frame->IsMain()); @@ -1619,6 +1630,12 @@ class SubresourceResponseTest : public RoutingTestHandler { CefRefPtr request, CefRefPtr callback) override { EXPECT_IO_THREAD(); + + if (IsChromeRuntimeEnabled() && request->GetResourceType() == RT_FAVICON) { + // Ignore favicon requests. + return RV_CANCEL; + } + EXPECT_EQ(browser_id_, browser->GetIdentifier()); if (IsMainURL(request->GetURL())) { @@ -1836,6 +1853,12 @@ class SubresourceResponseTest : public RoutingTestHandler { URLRequestStatus status, int64 received_content_length) override { EXPECT_IO_THREAD(); + + if (IsChromeRuntimeEnabled() && request->GetResourceType() == RT_FAVICON) { + // Ignore favicon requests. + return; + } + EXPECT_EQ(browser_id_, browser->GetIdentifier()); if (IsMainURL(request->GetURL())) { @@ -2987,6 +3010,13 @@ class RedirectResponseTest : public TestHandler { CefRefPtr request, CefRefPtr callback) override { EXPECT_IO_THREAD(); + + if (IsChromeRuntimeEnabled() && + request->GetResourceType() == RT_FAVICON) { + // Ignore favicon requests. + return RV_CANCEL; + } + EXPECT_EQ(test_->browser_id_, browser->GetIdentifier()); if (request->GetURL() == kResourceTestHtml) { @@ -3089,6 +3119,13 @@ class RedirectResponseTest : public TestHandler { URLRequestStatus status, int64 received_content_length) override { EXPECT_IO_THREAD(); + + if (IsChromeRuntimeEnabled() && + request->GetResourceType() == RT_FAVICON) { + // Ignore favicon requests. + return; + } + EXPECT_TRUE(browser.get()); EXPECT_EQ(test_->browser_id_, browser->GetIdentifier()); @@ -3206,6 +3243,11 @@ class BeforeResourceLoadTest : public TestHandler { CefRefPtr callback) override { EXPECT_IO_THREAD(); + if (IsChromeRuntimeEnabled() && request->GetResourceType() == RT_FAVICON) { + // Ignore favicon requests. + return RV_CANCEL; + } + // Allow the 2nd navigation to continue. const std::string& url = request->GetURL(); if (url == kResourceTestHtml2) { @@ -3765,6 +3807,11 @@ class ResponseFilterTestHandler : public TestHandler { int64 received_content_length) override { EXPECT_IO_THREAD(); + if (IsChromeRuntimeEnabled() && request->GetResourceType() == RT_FAVICON) { + // Ignore favicon requests. + return; + } + DCHECK(!got_resource_load_complete_); got_resource_load_complete_.yes(); diff --git a/tests/ceftests/scheme_handler_unittest.cc b/tests/ceftests/scheme_handler_unittest.cc index b49919e49..d31a9387d 100644 --- a/tests/ceftests/scheme_handler_unittest.cc +++ b/tests/ceftests/scheme_handler_unittest.cc @@ -145,6 +145,11 @@ class TestSchemeHandler : public TestHandler { CefRefPtr frame, CefRefPtr request, CefRefPtr callback) override { + if (IsChromeRuntimeEnabled() && request->GetResourceType() == RT_FAVICON) { + // Ignore favicon requests. + return RV_CANCEL; + } + const std::string& newUrl = request->GetURL(); if (IsExitURL(newUrl)) { test_results_->got_exit_request.yes(); @@ -429,6 +434,11 @@ class ClientSchemeHandler : public CefResourceHandler { CefRefPtr callback) override { EXPECT_FALSE(CefCurrentlyOn(TID_UI) || CefCurrentlyOn(TID_IO)); + if (IsChromeRuntimeEnabled() && request->GetResourceType() == RT_FAVICON) { + // Ignore favicon requests. + return false; + } + bool handled = false; std::string url = request->GetURL(); @@ -495,6 +505,11 @@ class ClientSchemeHandler : public CefResourceHandler { bool ProcessRequest(CefRefPtr request, CefRefPtr callback) override { + if (IsChromeRuntimeEnabled() && request->GetResourceType() == RT_FAVICON) { + // Ignore favicon requests. + return false; + } + EXPECT_TRUE(false); // Not reached. return false; } diff --git a/tests/ceftests/task_unittest.cc b/tests/ceftests/task_unittest.cc index 24a39cb73..20525902f 100644 --- a/tests/ceftests/task_unittest.cc +++ b/tests/ceftests/task_unittest.cc @@ -25,7 +25,7 @@ void GetForCurrentThread(bool* ran_test, CefRefPtr event) { CefRefPtr runner = CefTaskRunner::GetForCurrentThread(); EXPECT_TRUE(runner.get()); EXPECT_TRUE(runner->BelongsToCurrentThread()); - EXPECT_TRUE(runner->BelongsToThread(TID_FILE)); + EXPECT_TRUE(runner->BelongsToThread(TID_FILE_USER_VISIBLE)); EXPECT_FALSE(runner->BelongsToThread(TID_IO)); EXPECT_TRUE(runner->IsSame(runner)); @@ -50,7 +50,7 @@ void GetForThread(bool* ran_test, CefRefPtr event) { EXPECT_TRUE(runner.get()); EXPECT_FALSE(runner->BelongsToCurrentThread()); EXPECT_TRUE(runner->BelongsToThread(TID_IO)); - EXPECT_FALSE(runner->BelongsToThread(TID_FILE)); + EXPECT_FALSE(runner->BelongsToThread(TID_FILE_USER_VISIBLE)); EXPECT_TRUE(runner->IsSame(runner)); CefRefPtr runner2 = CefTaskRunner::GetForThread(TID_IO); @@ -58,7 +58,8 @@ void GetForThread(bool* ran_test, CefRefPtr event) { EXPECT_TRUE(runner->IsSame(runner2)); EXPECT_TRUE(runner2->IsSame(runner)); - CefRefPtr runner3 = CefTaskRunner::GetForThread(TID_FILE); + CefRefPtr runner3 = + CefTaskRunner::GetForThread(TID_FILE_USER_VISIBLE); EXPECT_TRUE(runner3.get()); EXPECT_FALSE(runner->IsSame(runner3)); EXPECT_FALSE(runner3->IsSame(runner)); @@ -73,14 +74,14 @@ void PostTaskEvent1(bool* ran_test, // Currently on the IO thread. EXPECT_TRUE(runner->BelongsToCurrentThread()); EXPECT_TRUE(runner->BelongsToThread(TID_IO)); - EXPECT_FALSE(runner->BelongsToThread(TID_FILE)); + EXPECT_FALSE(runner->BelongsToThread(TID_FILE_USER_VISIBLE)); // Current thread should be the IO thread. CefRefPtr runner2 = CefTaskRunner::GetForCurrentThread(); EXPECT_TRUE(runner2.get()); EXPECT_TRUE(runner2->BelongsToCurrentThread()); EXPECT_TRUE(runner2->BelongsToThread(TID_IO)); - EXPECT_FALSE(runner2->BelongsToThread(TID_FILE)); + EXPECT_FALSE(runner2->BelongsToThread(TID_FILE_USER_VISIBLE)); EXPECT_TRUE(runner->IsSame(runner2)); EXPECT_TRUE(runner2->IsSame(runner)); @@ -89,16 +90,17 @@ void PostTaskEvent1(bool* ran_test, EXPECT_TRUE(runner3.get()); EXPECT_TRUE(runner3->BelongsToCurrentThread()); EXPECT_TRUE(runner3->BelongsToThread(TID_IO)); - EXPECT_FALSE(runner3->BelongsToThread(TID_FILE)); + EXPECT_FALSE(runner3->BelongsToThread(TID_FILE_USER_VISIBLE)); EXPECT_TRUE(runner->IsSame(runner3)); EXPECT_TRUE(runner3->IsSame(runner)); // Current thread should not be the FILE thread. - CefRefPtr runner4 = CefTaskRunner::GetForThread(TID_FILE); + CefRefPtr runner4 = + CefTaskRunner::GetForThread(TID_FILE_USER_VISIBLE); EXPECT_TRUE(runner4.get()); EXPECT_FALSE(runner4->BelongsToCurrentThread()); EXPECT_FALSE(runner4->BelongsToThread(TID_IO)); - EXPECT_TRUE(runner4->BelongsToThread(TID_FILE)); + EXPECT_TRUE(runner4->BelongsToThread(TID_FILE_USER_VISIBLE)); EXPECT_FALSE(runner->IsSame(runner4)); EXPECT_FALSE(runner4->IsSame(runner)); @@ -131,7 +133,7 @@ void PostDelayedTask1(bool* ran_test, CefRefPtr event) { void PostTaskEvent2(bool* ran_test, CefRefPtr event) { EXPECT_TRUE(CefCurrentlyOn(TID_IO)); - EXPECT_FALSE(CefCurrentlyOn(TID_FILE)); + EXPECT_FALSE(CefCurrentlyOn(TID_FILE_USER_VISIBLE)); *ran_test = true; event->Signal(); @@ -160,8 +162,9 @@ TEST(TaskTest, GetForCurrentThread) { bool ran_test = false; CefRefPtr event = CefWaitableEvent::CreateWaitableEvent(true, false); - CefPostTask(TID_FILE, CefCreateClosureTask(base::Bind(&GetForCurrentThread, - &ran_test, event))); + CefPostTask( + TID_FILE_USER_VISIBLE, + CefCreateClosureTask(base::Bind(&GetForCurrentThread, &ran_test, event))); WaitForEvent(event); EXPECT_TRUE(ran_test); } @@ -170,8 +173,8 @@ TEST(TaskTest, GetForThread) { bool ran_test = false; CefRefPtr event = CefWaitableEvent::CreateWaitableEvent(true, false); - CefPostTask(TID_FILE, CefCreateClosureTask( - base::Bind(&GetForThread, &ran_test, event))); + CefPostTask(TID_FILE_USER_VISIBLE, CefCreateClosureTask(base::Bind( + &GetForThread, &ran_test, event))); WaitForEvent(event); EXPECT_TRUE(ran_test); } @@ -180,7 +183,7 @@ TEST(TaskTest, PostTask1) { bool ran_test = false; CefRefPtr event = CefWaitableEvent::CreateWaitableEvent(true, false); - CefPostTask(TID_FILE, + CefPostTask(TID_FILE_USER_VISIBLE, CefCreateClosureTask(base::Bind(&PostTask1, &ran_test, event))); WaitForEvent(event); EXPECT_TRUE(ran_test); @@ -190,8 +193,8 @@ TEST(TaskTest, PostDelayedTask1) { bool ran_test = false; CefRefPtr event = CefWaitableEvent::CreateWaitableEvent(true, false); - CefPostTask(TID_FILE, CefCreateClosureTask( - base::Bind(&PostDelayedTask1, &ran_test, event))); + CefPostTask(TID_FILE_USER_VISIBLE, CefCreateClosureTask(base::Bind( + &PostDelayedTask1, &ran_test, event))); WaitForEvent(event); EXPECT_TRUE(ran_test); } @@ -200,7 +203,7 @@ TEST(TaskTest, PostTask2) { bool ran_test = false; CefRefPtr event = CefWaitableEvent::CreateWaitableEvent(true, false); - CefPostTask(TID_FILE, + CefPostTask(TID_FILE_USER_VISIBLE, CefCreateClosureTask(base::Bind(&PostTask2, &ran_test, event))); WaitForEvent(event); EXPECT_TRUE(ran_test); @@ -210,8 +213,8 @@ TEST(TaskTest, PostDelayedTask2) { bool ran_test = false; CefRefPtr event = CefWaitableEvent::CreateWaitableEvent(true, false); - CefPostTask(TID_FILE, CefCreateClosureTask( - base::Bind(&PostDelayedTask2, &ran_test, event))); + CefPostTask(TID_FILE_USER_VISIBLE, CefCreateClosureTask(base::Bind( + &PostDelayedTask2, &ran_test, event))); WaitForEvent(event); EXPECT_TRUE(ran_test); } diff --git a/tests/ceftests/test_server.cc b/tests/ceftests/test_server.cc index 821a0a4c6..f49053a31 100644 --- a/tests/ceftests/test_server.cc +++ b/tests/ceftests/test_server.cc @@ -206,7 +206,8 @@ class ServerManager { void NotifyClientConnected(CefRefPtr server, int connection_id) { CEF_REQUIRE_UI_THREAD(); - DCHECK(!observer_list_.empty()); + if (observer_list_.empty()) + return; // Use a copy in case |observer_list_| is modified during iteration. ObserverList list = observer_list_; @@ -223,7 +224,8 @@ class ServerManager { int connection_id) { CEF_REQUIRE_UI_THREAD(); - DCHECK(!observer_list_.empty()); + if (observer_list_.empty()) + return; // Use a copy in case |observer_list_| is modified during iteration. ObserverList list = observer_list_; @@ -242,7 +244,17 @@ class ServerManager { CefRefPtr request) { CEF_REQUIRE_UI_THREAD(); - DCHECK(!observer_list_.empty()); + // TODO(chrome-runtime): Debug why favicon requests don't always have the + // correct resource type. + const std::string& url = request->GetURL(); + if (request->GetResourceType() == RT_FAVICON || + url.find("/favicon.ico") != std::string::npos) { + // We don't currently handle favicon requests. + server->SendHttp404Response(connection_id); + return; + } + + DCHECK(!observer_list_.empty()) << url; // Use a copy in case |observer_list_| is modified during iteration. ObserverList list = observer_list_; diff --git a/tests/ceftests/test_suite.cc b/tests/ceftests/test_suite.cc index d96eefdba..aeef16b99 100644 --- a/tests/ceftests/test_suite.cc +++ b/tests/ceftests/test_suite.cc @@ -119,6 +119,10 @@ int CefTestSuite::Run() { } void CefTestSuite::GetSettings(CefSettings& settings) const { + // Enable the experimental Chrome runtime. See issue #2969 for details. + settings.chrome_runtime = + command_line_->HasSwitch(client::switches::kEnableChromeRuntime); + #if (defined(OS_WIN) || defined(OS_LINUX)) settings.multi_threaded_message_loop = command_line_->HasSwitch(client::switches::kMultiThreadedMessageLoop); diff --git a/tests/ceftests/test_util.cc b/tests/ceftests/test_util.cc index 723c03208..8da3df96a 100644 --- a/tests/ceftests/test_util.cc +++ b/tests/ceftests/test_util.cc @@ -292,6 +292,16 @@ bool IsOutOfBlinkCorsEnabled() { return state ? true : false; } +bool IsChromeRuntimeEnabled() { + static int state = -1; + if (state == -1) { + CefRefPtr command_line = + CefCommandLine::GetGlobalCommandLine(); + state = command_line->HasSwitch("enable-chrome-runtime") ? 1 : 0; + } + return state ? true : false; +} + CefRefPtr CreateTestRequestContext( TestRequestContextMode mode, const std::string& cache_path) { diff --git a/tests/ceftests/test_util.h b/tests/ceftests/test_util.h index d45f10e42..547bddc74 100644 --- a/tests/ceftests/test_util.h +++ b/tests/ceftests/test_util.h @@ -84,6 +84,9 @@ bool TestOldResourceAPI(); // Returns true if OutOfBlinkCors is enabled. bool IsOutOfBlinkCorsEnabled(); +// Returns true if the Chrome runtime is enabled. +bool IsChromeRuntimeEnabled(); + // Return a RequestContext object matching the specified |mode|. // |cache_path| may be specified for CUSTOM modes. // Use the RC_TEST_GROUP_BASE macro to test all valid combinations. diff --git a/tests/ceftests/thread_helper.h b/tests/ceftests/thread_helper.h index 5fccb129b..db6320883 100644 --- a/tests/ceftests/thread_helper.h +++ b/tests/ceftests/thread_helper.h @@ -20,15 +20,16 @@ void WaitForThread(CefRefPtr task_runner, int64 delay_ms = 0); #define WaitForIOThread() WaitForThread(TID_IO) #define WaitForUIThread() WaitForThread(TID_UI) -#define WaitForFILEThread() WaitForThread(TID_FILE) +#define WaitForFILEThread() WaitForThread(TID_FILE_USER_VISIBLE) #define WaitForIOThreadWithDelay(delay_ms) WaitForThread(TID_IO, delay_ms) #define WaitForUIThreadWithDelay(delay_ms) WaitForThread(TID_UI, delay_ms) -#define WaitForFILEThreadWithDelay(delay_ms) WaitForThread(TID_FILE, delay_ms) +#define WaitForFILEThreadWithDelay(delay_ms) \ + WaitForThread(TID_FILE_USER_VISIBLE, delay_ms) // Assert that execution is occuring on the named thread. #define EXPECT_UI_THREAD() EXPECT_TRUE(CefCurrentlyOn(TID_UI)); #define EXPECT_IO_THREAD() EXPECT_TRUE(CefCurrentlyOn(TID_IO)); -#define EXPECT_FILE_THREAD() EXPECT_TRUE(CefCurrentlyOn(TID_FILE)); +#define EXPECT_FILE_THREAD() EXPECT_TRUE(CefCurrentlyOn(TID_FILE_USER_VISIBLE)); #define EXPECT_RENDERER_THREAD() EXPECT_TRUE(CefCurrentlyOn(TID_RENDERER)); // Executes |test_impl| on the specified |thread_id|. |event| will be signaled diff --git a/tests/ceftests/thread_unittest.cc b/tests/ceftests/thread_unittest.cc index db2390970..e68ca5312 100644 --- a/tests/ceftests/thread_unittest.cc +++ b/tests/ceftests/thread_unittest.cc @@ -287,8 +287,9 @@ TEST(ThreadTest, CreateFromBrowserIOThread) { // Test creation of new threads from the browser FILE thread. TEST(ThreadTest, CreateFromBrowserFILEThread) { + // Use a FILE thread that will run tasks relatively quickly. CefRefPtr handler = - new BrowserThreadTestHandler(TID_FILE); + new BrowserThreadTestHandler(TID_FILE_USER_VISIBLE); handler->ExecuteTest(); ReleaseAndWaitForDestructor(handler); } diff --git a/tests/ceftests/tracing_unittest.cc b/tests/ceftests/tracing_unittest.cc index caa3942b3..d02d763f9 100644 --- a/tests/ceftests/tracing_unittest.cc +++ b/tests/ceftests/tracing_unittest.cc @@ -328,8 +328,9 @@ class TracingTestHandler : public CefEndTracingCallback, void OnEndTracingComplete(const CefString& tracing_file) override { EXPECT_UI_THREAD(); - CefPostTask(TID_FILE, base::Bind(&TracingTestHandler::ReadTracingFile, this, - tracing_file)); + CefPostTask( + TID_FILE_USER_VISIBLE, + base::Bind(&TracingTestHandler::ReadTracingFile, this, tracing_file)); } void ReadTracingFile(const std::string& file_path) { diff --git a/tests/ceftests/urlrequest_unittest.cc b/tests/ceftests/urlrequest_unittest.cc index 8406b75fd..a0b4bf0d9 100644 --- a/tests/ceftests/urlrequest_unittest.cc +++ b/tests/ceftests/urlrequest_unittest.cc @@ -22,6 +22,7 @@ #include "tests/ceftests/test_suite.h" #include "tests/ceftests/test_util.h" #include "tests/gtest/include/gtest/gtest.h" +#include "tests/shared/browser/client_app_browser.h" #include "tests/shared/browser/file_util.h" #include "tests/shared/renderer/client_app_renderer.h" @@ -36,6 +37,22 @@ using client::ClientAppRenderer; namespace { +// Browser-side app delegate. +class URLRequestBrowserTest : public client::ClientAppBrowser::Delegate { + public: + URLRequestBrowserTest() {} + + void OnBeforeCommandLineProcessing( + CefRefPtr app, + CefRefPtr command_line) override { + // Delegate auth callbacks to GetAuthCredentials with the chrome runtime. + command_line->AppendSwitch("disable-chrome-login-prompt"); + } + + private: + IMPLEMENT_REFCOUNTING(URLRequestBrowserTest); +}; + // Unique values for URLRequest tests. const char kRequestTestMsg[] = "URLRequestTest.Test"; const char kIncompleteRequestTestMsg[] = "URLRequestTest.IncompleteRequestTest"; @@ -1285,9 +1302,11 @@ class RequestServerHandler : public test_server::ObserverHelper { int connection_id) override { EXPECT_UI_THREAD(); - EXPECT_TRUE(connection_id_set_.find(connection_id) == - connection_id_set_.end()); - connection_id_set_.insert(connection_id); + if (!IsChromeRuntimeEnabled()) { + EXPECT_TRUE(connection_id_set_.find(connection_id) == + connection_id_set_.end()); + connection_id_set_.insert(connection_id); + } actual_connection_ct_++; @@ -1298,9 +1317,11 @@ class RequestServerHandler : public test_server::ObserverHelper { int connection_id) override { EXPECT_UI_THREAD(); - ConnectionIdSet::iterator it = connection_id_set_.find(connection_id); - EXPECT_TRUE(it != connection_id_set_.end()); - connection_id_set_.erase(it); + if (!IsChromeRuntimeEnabled()) { + ConnectionIdSet::iterator it = connection_id_set_.find(connection_id); + EXPECT_TRUE(it != connection_id_set_.end()); + connection_id_set_.erase(it); + } return true; } @@ -1310,13 +1331,25 @@ class RequestServerHandler : public test_server::ObserverHelper { const CefString& client_address, CefRefPtr request) override { EXPECT_UI_THREAD(); - EXPECT_TRUE(VerifyConnection(connection_id)); + if (!IsChromeRuntimeEnabled()) { + EXPECT_TRUE(VerifyConnection(connection_id)); + } EXPECT_FALSE(client_address.empty()); // Log the requests for better error reporting. request_log_ += request->GetMethod().ToString() + " " + request->GetURL().ToString() + "\n"; + // TODO(chrome-runtime): Debug why favicon requests don't always have the + // correct resource type. + const std::string& url = request->GetURL(); + if (request->GetResourceType() == RT_FAVICON || + url.find("/favicon.ico") != std::string::npos) { + // We don't currently handle favicon requests. + server->SendHttp404Response(connection_id); + return true; + } + HandleRequest(server, connection_id, request); actual_http_request_ct_++; @@ -1332,10 +1365,12 @@ class RequestServerHandler : public test_server::ObserverHelper { void VerifyResults() { EXPECT_TRUE(got_initialized_); EXPECT_TRUE(got_shutdown_); - EXPECT_TRUE(connection_id_set_.empty()); - EXPECT_EQ(expected_connection_ct_, actual_connection_ct_) << request_log_; - EXPECT_EQ(expected_http_request_ct_, actual_http_request_ct_) - << request_log_; + if (!IsChromeRuntimeEnabled()) { + EXPECT_TRUE(connection_id_set_.empty()); + EXPECT_EQ(expected_connection_ct_, actual_connection_ct_) << request_log_; + EXPECT_EQ(expected_http_request_ct_, actual_http_request_ct_) + << request_log_; + } } void HandleRequest(CefRefPtr server, @@ -1631,7 +1666,7 @@ class RequestTestRunner : public base::RefCountedThreadSafe { if (!post_file_tmpdir_.IsEmpty()) { EXPECT_TRUE(is_browser_process_); - CefPostTask(TID_FILE, + CefPostTask(TID_FILE_USER_VISIBLE, base::Bind(&RequestTestRunner::RunDeleteTempDirectory, this, safe_complete_callback)); return; @@ -1882,13 +1917,13 @@ class RequestTestRunner : public base::RefCountedThreadSafe { settings_.response_data = "POST TEST SUCCESS"; - CefPostTask(TID_FILE, + CefPostTask(TID_FILE_USER_VISIBLE, base::Bind(&RequestTestRunner::SetupPostFileTestContinue, this, complete_callback)); } void SetupPostFileTestContinue(const base::Closure& complete_callback) { - EXPECT_TRUE(CefCurrentlyOn(TID_FILE)); + EXPECT_TRUE(CefCurrentlyOn(TID_FILE_USER_VISIBLE)); EXPECT_TRUE(post_file_tmpdir_.CreateUniqueTempDir()); const std::string& path = @@ -2540,7 +2575,7 @@ class RequestTestRunner : public base::RefCountedThreadSafe { } void RunDeleteTempDirectory(const base::Closure& complete_callback) { - EXPECT_TRUE(CefCurrentlyOn(TID_FILE)); + EXPECT_TRUE(CefCurrentlyOn(TID_FILE_USER_VISIBLE)); EXPECT_TRUE(post_file_tmpdir_.Delete()); EXPECT_TRUE(post_file_tmpdir_.IsEmpty()); @@ -2815,12 +2850,12 @@ class RequestTestHandler : public TestHandler { } void PreSetupStart() { - CefPostTask(TID_FILE, + CefPostTask(TID_FILE_USER_VISIBLE, base::Bind(&RequestTestHandler::PreSetupFileTasks, this)); } void PreSetupFileTasks() { - EXPECT_TRUE(CefCurrentlyOn(TID_FILE)); + EXPECT_TRUE(CefCurrentlyOn(TID_FILE_USER_VISIBLE)); if (context_mode_ == CONTEXT_ONDISK) { EXPECT_TRUE(context_tmpdir_.CreateUniqueTempDir()); @@ -3150,7 +3185,7 @@ class RequestTestHandler : public TestHandler { // Wait a bit for cache file handles to close after browser or request // context destruction. CefPostDelayedTask( - TID_FILE, + TID_FILE_USER_VISIBLE, base::Bind(&RequestTestHandler::PostTestCompleteFileTasks, this), 100); } else { @@ -3159,7 +3194,7 @@ class RequestTestHandler : public TestHandler { } void PostTestCompleteFileTasks() { - EXPECT_TRUE(CefCurrentlyOn(TID_FILE)); + EXPECT_TRUE(CefCurrentlyOn(TID_FILE_USER_VISIBLE)); EXPECT_TRUE(context_tmpdir_.Delete()); EXPECT_TRUE(context_tmpdir_.IsEmpty()); @@ -3509,3 +3544,10 @@ TEST(URLRequestTest, BrowserInvalidURL) { CefRefPtr client = new InvalidURLTestClient(); client->RunTest(); } + +// Entry point for creating plugin browser test objects. +// Called from client_app_delegates.cc. +void CreateURLRequestBrowserTests( + client::ClientAppBrowser::DelegateSet& delegates) { + delegates.insert(new URLRequestBrowserTest); +} diff --git a/tests/shared/browser/client_app_browser.cc b/tests/shared/browser/client_app_browser.cc index e37d0cc54..739d42505 100644 --- a/tests/shared/browser/client_app_browser.cc +++ b/tests/shared/browser/client_app_browser.cc @@ -58,15 +58,15 @@ void ClientAppBrowser::OnBeforeCommandLineProcessing( } } -void ClientAppBrowser::OnContextInitialized() { +void ClientAppBrowser::GetCookieableSchemes(std::vector& schemes, + bool& include_defaults) { if (!cookieable_schemes_.empty()) { - // Register cookieable schemes with the global cookie manager. - CefRefPtr manager = - CefCookieManager::GetGlobalManager(nullptr); - DCHECK(manager.get()); - manager->SetSupportedSchemes(cookieable_schemes_, true, nullptr); + schemes = cookieable_schemes_; + include_defaults = true; } +} +void ClientAppBrowser::OnContextInitialized() { print_handler_ = CreatePrintHandler(); DelegateSet::iterator it = delegates_.begin(); diff --git a/tests/shared/browser/client_app_browser.h b/tests/shared/browser/client_app_browser.h index 4eaee3a10..d7329a7e4 100644 --- a/tests/shared/browser/client_app_browser.h +++ b/tests/shared/browser/client_app_browser.h @@ -53,6 +53,8 @@ class ClientAppBrowser : public ClientApp, public CefBrowserProcessHandler { } // CefBrowserProcessHandler methods. + void GetCookieableSchemes(std::vector& schemes, + bool& include_defaults) OVERRIDE; void OnContextInitialized() OVERRIDE; void OnBeforeChildProcessLaunch( CefRefPtr command_line) OVERRIDE; diff --git a/tests/shared/common/client_switches.cc b/tests/shared/common/client_switches.cc index 9feef7cc2..81d6b70fd 100644 --- a/tests/shared/common/client_switches.cc +++ b/tests/shared/common/client_switches.cc @@ -44,6 +44,7 @@ const char kSslClientCertificate[] = "ssl-client-certificate"; const char kCRLSetsPath[] = "crl-sets-path"; const char kLoadExtension[] = "load-extension"; const char kNoActivate[] = "no-activate"; +const char kEnableChromeRuntime[] = "enable-chrome-runtime"; } // namespace switches } // namespace client diff --git a/tests/shared/common/client_switches.h b/tests/shared/common/client_switches.h index 0ff5938c4..c1332e307 100644 --- a/tests/shared/common/client_switches.h +++ b/tests/shared/common/client_switches.h @@ -38,6 +38,7 @@ extern const char kSslClientCertificate[]; extern const char kCRLSetsPath[]; extern const char kLoadExtension[]; extern const char kNoActivate[]; +extern const char kEnableChromeRuntime[]; } // namespace switches } // namespace client