diff --git a/libcef/browser/browser_host_impl.cc b/libcef/browser/browser_host_impl.cc index 2199bd0d9..4e1f24bf0 100644 --- a/libcef/browser/browser_host_impl.cc +++ b/libcef/browser/browser_host_impl.cc @@ -16,24 +16,16 @@ #include "libcef/browser/browser_util.h" #include "libcef/browser/context.h" #include "libcef/browser/devtools/devtools_manager.h" -#include "libcef/browser/extensions/browser_extensions_util.h" -#include "libcef/browser/extensions/extension_background_host.h" -#include "libcef/browser/extensions/extension_system.h" -#include "libcef/browser/extensions/extension_view_host.h" -#include "libcef/browser/extensions/extension_web_contents_observer.h" #include "libcef/browser/image_impl.h" #include "libcef/browser/media_capture_devices_dispatcher.h" #include "libcef/browser/navigation_entry_impl.h" -#include "libcef/browser/net/chrome_scheme_handler.h" #include "libcef/browser/net/scheme_handler.h" #include "libcef/browser/osr/osr_util.h" -#include "libcef/browser/printing/print_view_manager.h" #include "libcef/browser/request_context_impl.h" #include "libcef/browser/thread_util.h" #include "libcef/common/cef_messages.h" #include "libcef/common/cef_switches.h" #include "libcef/common/drag_data_impl.h" -#include "libcef/common/extensions/extensions_util.h" #include "libcef/common/request_impl.h" #include "libcef/common/values_impl.h" #include "libcef/features/runtime_checks.h" @@ -42,15 +34,12 @@ #include "base/bind_helpers.h" #include "base/command_line.h" #include "chrome/browser/picture_in_picture/picture_in_picture_window_manager.h" -#include "chrome/browser/printing/print_view_manager.h" #include "chrome/browser/spellchecker/spellcheck_factory.h" #include "chrome/browser/spellchecker/spellcheck_service.h" -#include "chrome/browser/ui/prefs/prefs_tab_helper.h" #include "components/favicon/core/favicon_url.h" #include "components/spellcheck/common/spellcheck_features.h" -#include "components/zoom/zoom_controller.h" #include "content/browser/gpu/compositor_util.h" -#include "content/browser/web_contents/web_contents_impl.h" +#include "content/browser/renderer_host/render_widget_host_impl.h" #include "content/common/widget_messages.h" #include "content/public/browser/desktop_media_id.h" #include "content/public/browser/download_manager.h" @@ -71,11 +60,11 @@ #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/browser/process_manager.h" +#include "extensions/common/extension.h" #include "net/base/net_errors.h" -#include "third_party/blink/public/mojom/frame/find_in_page.mojom.h" #include "third_party/blink/public/mojom/page/widget.mojom-test-utils.h" #include "ui/events/base_event_utils.h" +#include "ui/gfx/image/image_skia.h" #if defined(OS_MACOSX) #include "components/spellcheck/browser/spellcheck_platform.h" @@ -359,78 +348,36 @@ CefRefPtr CefBrowserHostImpl::Create( is_devtools_popup, platform_delegate->IsWindowless(), create_params.extra_info); - // Get or create the request context and browser context. - CefRefPtr request_context_impl = - CefRequestContextImpl::GetOrCreateForRequestContext( - create_params.request_context); - DCHECK(request_context_impl); - CefBrowserContext* cef_browser_context = - request_context_impl->GetBrowserContext(); - DCHECK(cef_browser_context); - auto browser_context = cef_browser_context->AsBrowserContext(); + bool own_web_contents = false; - if (!create_params.request_context) { - // Using the global request context. - create_params.request_context = request_context_impl.get(); - } + // This call may modify |create_params|. + auto web_contents = + platform_delegate->CreateWebContents(create_params, own_web_contents); + + auto request_context_impl = + static_cast(create_params.request_context.get()); CefRefPtr cef_extension; - scoped_refptr site_instance; - if (extensions::ExtensionsEnabled() && !create_params.url.is_empty()) { - if (!create_params.extension) { - // We might be loading an extension app view where the extension URL is - // provided by the client. - create_params.extension = - extensions::GetExtensionForUrl(browser_context, create_params.url); - } - if (create_params.extension) { - cef_extension = - cef_browser_context->GetExtension(create_params.extension->id()); - DCHECK(cef_extension); - - if (create_params.extension_host_type == extensions::VIEW_TYPE_INVALID) { - // Default to dialog behavior. - create_params.extension_host_type = - extensions::VIEW_TYPE_EXTENSION_DIALOG; - } - - // Extension resources will fail to load if we don't use a SiteInstance - // associated with the extension. - // (AlloyContentBrowserClient::SiteInstanceGotProcess won't find the - // extension to register with InfoMap, and AllowExtensionResourceLoad in - // ExtensionProtocolHandler::MaybeCreateJob will return false resulting in - // ERR_BLOCKED_BY_CLIENT). - site_instance = extensions::ProcessManager::Get(browser_context) - ->GetSiteInstanceForURL(create_params.url); - DCHECK(site_instance); - } + if (create_params.extension) { + auto cef_browser_context = request_context_impl->GetBrowserContext(); + cef_extension = + cef_browser_context->GetExtension(create_params.extension->id()); + CHECK(cef_extension); } - content::WebContents::CreateParams wc_create_params(browser_context, - site_instance); - - if (platform_delegate->IsWindowless()) { - // Create the OSR view for the WebContents. - platform_delegate->CreateViewForWebContents( - &wc_create_params.view, &wc_create_params.delegate_view); - } - - std::unique_ptr web_contents = - content::WebContents::Create(wc_create_params); - DCHECK(web_contents); + auto platform_delegate_ptr = platform_delegate.get(); CefRefPtr browser = CreateInternal( - create_params.settings, create_params.client, web_contents.release(), - true, info, create_params.devtools_opener, is_devtools_popup, - static_cast(create_params.request_context.get()), - std::move(platform_delegate), cef_extension); + create_params.settings, create_params.client, web_contents, + own_web_contents, info, create_params.devtools_opener, is_devtools_popup, + request_context_impl, std::move(platform_delegate), cef_extension); if (!browser) return nullptr; if (create_params.extension) { - browser->CreateExtensionHost(create_params.extension, browser_context, - browser->web_contents(), create_params.url, - create_params.extension_host_type); + platform_delegate_ptr->CreateExtensionHost( + 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, @@ -464,6 +411,8 @@ CefRefPtr CefBrowserHostImpl::CreateInternal( if (opener) { if (!opener->platform_delegate_) { // The opener window is being destroyed. Cancel the popup. + if (own_web_contents) + delete web_contents; return nullptr; } @@ -474,13 +423,12 @@ CefRefPtr CefBrowserHostImpl::CreateInternal( is_devtools_popup); } - platform_delegate->WebContentsCreated(web_contents); + // Take ownership of |web_contents| if |own_web_contents| is true. + platform_delegate->WebContentsCreated(web_contents, own_web_contents); CefRefPtr browser = new CefBrowserHostImpl( settings, client, web_contents, browser_info, opener, request_context, std::move(platform_delegate), extension); - if (own_web_contents) - browser->set_owned_web_contents(web_contents); if (!browser->CreateHostWindow()) return nullptr; @@ -801,44 +749,26 @@ void CefBrowserHostImpl::DownloadImage( } void CefBrowserHostImpl::Print() { - if (CEF_CURRENTLY_ON_UIT()) { - auto actionable_contents = GetActionableWebContents(); - if (!actionable_contents) - return; - - auto rfh = actionable_contents->GetMainFrame(); - - if (IsPrintPreviewSupported()) { - printing::CefPrintViewManager::FromWebContents(actionable_contents) - ->PrintPreviewNow(rfh, false); - } else { - printing::PrintViewManager::FromWebContents(actionable_contents) - ->PrintNow(rfh); - } - } else { + if (!CEF_CURRENTLY_ON_UIT()) { CEF_POST_TASK(CEF_UIT, base::BindOnce(&CefBrowserHostImpl::Print, this)); + return; } + + if (platform_delegate_) + platform_delegate_->Print(); } void CefBrowserHostImpl::PrintToPDF(const CefString& path, const CefPdfPrintSettings& settings, CefRefPtr callback) { - if (CEF_CURRENTLY_ON_UIT()) { - content::WebContents* actionable_contents = GetActionableWebContents(); - if (!actionable_contents) - return; - - printing::CefPrintViewManager::PdfPrintCallback pdf_callback; - if (callback.get()) { - pdf_callback = base::Bind(&CefPdfPrintCallback::OnPdfPrintFinished, - callback.get(), path); - } - printing::CefPrintViewManager::FromWebContents(actionable_contents) - ->PrintToPDF(actionable_contents->GetMainFrame(), base::FilePath(path), - settings, pdf_callback); - } else { + if (!CEF_CURRENTLY_ON_UIT()) { CEF_POST_TASK(CEF_UIT, base::BindOnce(&CefBrowserHostImpl::PrintToPDF, this, path, settings, callback)); + return; + } + + if (platform_delegate_) { + platform_delegate_->PrintToPDF(path, settings, callback); } } @@ -847,43 +777,28 @@ void CefBrowserHostImpl::Find(int identifier, bool forward, bool matchCase, bool findNext) { - if (CEF_CURRENTLY_ON_UIT()) { - if (!web_contents()) - return; - - // Every find request must have a unique ID and these IDs must strictly - // increase so that newer requests always have greater IDs than older - // requests. - if (identifier <= find_request_id_counter_) - identifier = ++find_request_id_counter_; - else - find_request_id_counter_ = identifier; - - auto options = blink::mojom::FindOptions::New(); - options->forward = forward; - options->match_case = matchCase; - options->find_next = findNext; - web_contents()->Find(identifier, searchText, std::move(options)); - } else { + if (!CEF_CURRENTLY_ON_UIT()) { CEF_POST_TASK(CEF_UIT, base::BindOnce(&CefBrowserHostImpl::Find, this, identifier, searchText, forward, matchCase, findNext)); + return; + } + + if (platform_delegate_) { + platform_delegate_->Find(identifier, searchText, forward, matchCase, + findNext); } } void CefBrowserHostImpl::StopFinding(bool clearSelection) { - if (CEF_CURRENTLY_ON_UIT()) { - if (!web_contents()) - return; - - content::StopFindAction action = - clearSelection ? content::STOP_FIND_ACTION_CLEAR_SELECTION - : content::STOP_FIND_ACTION_KEEP_SELECTION; - web_contents()->StopFinding(action); - } else { + if (!CEF_CURRENTLY_ON_UIT()) { CEF_POST_TASK(CEF_UIT, base::BindOnce(&CefBrowserHostImpl::StopFinding, this, clearSelection)); + return; } + + if (platform_delegate_) + platform_delegate_->StopFinding(clearSelection); } void CefBrowserHostImpl::ShowDevTools(const CefWindowInfo& windowInfo, @@ -1058,12 +973,6 @@ CefRefPtr CefBrowserHostImpl::GetVisibleNavigationEntry() { void CefBrowserHostImpl::SetAccessibilityState( cef_state_t accessibility_state) { - // Do nothing if state is set to default. It'll be disabled by default and - // controlled by the commmand-line flags "force-renderer-accessibility" and - // "disable-renderer-accessibility". - if (accessibility_state == STATE_DEFAULT) - return; - if (!CEF_CURRENTLY_ON_UIT()) { CEF_POST_TASK(CEF_UIT, base::BindOnce(&CefBrowserHostImpl::SetAccessibilityState, @@ -1071,19 +980,9 @@ void CefBrowserHostImpl::SetAccessibilityState( return; } - content::WebContentsImpl* web_contents_impl = - static_cast(web_contents()); - - if (!web_contents_impl) - return; - - ui::AXMode accMode; - // In windowless mode set accessibility to TreeOnly mode. Else native - // accessibility APIs, specific to each platform, are also created. - if (accessibility_state == STATE_ENABLED) { - accMode = IsWindowless() ? ui::kAXModeWebContentsOnly : ui::kAXModeComplete; + if (platform_delegate_) { + platform_delegate_->SetAccessibilityState(accessibility_state); } - web_contents_impl->SetAccessibilityMode(accMode); } void CefBrowserHostImpl::SetAutoResizeEnabled(bool enabled, @@ -1096,17 +995,9 @@ void CefBrowserHostImpl::SetAutoResizeEnabled(bool enabled, return; } - if (enabled == auto_resize_enabled_) - return; - - auto_resize_enabled_ = enabled; - if (enabled) { - auto_resize_min_ = gfx::Size(min_size.width, min_size.height); - auto_resize_max_ = gfx::Size(max_size.width, max_size.height); - } else { - auto_resize_min_ = auto_resize_max_ = gfx::Size(); + if (platform_delegate_) { + platform_delegate_->SetAutoResizeEnabled(enabled, min_size, max_size); } - ConfigureAutoResize(); } CefRefPtr CefBrowserHostImpl::GetExtension() { @@ -1178,10 +1069,8 @@ void CefBrowserHostImpl::WasResized() { return; } - if (!web_contents() || !platform_delegate_) - return; - - platform_delegate_->WasResized(); + if (platform_delegate_) + platform_delegate_->WasResized(); } void CefBrowserHostImpl::WasHidden(bool hidden) { @@ -1196,10 +1085,8 @@ void CefBrowserHostImpl::WasHidden(bool hidden) { return; } - if (!web_contents() || !platform_delegate_) - return; - - platform_delegate_->WasHidden(hidden); + if (platform_delegate_) + platform_delegate_->WasHidden(hidden); } void CefBrowserHostImpl::NotifyScreenInfoChanged() { @@ -1215,10 +1102,8 @@ void CefBrowserHostImpl::NotifyScreenInfoChanged() { return; } - if (!web_contents() || !platform_delegate_) - return; - - platform_delegate_->NotifyScreenInfoChanged(); + if (platform_delegate_) + platform_delegate_->NotifyScreenInfoChanged(); } void CefBrowserHostImpl::Invalidate(PaintElementType type) { @@ -1233,10 +1118,8 @@ void CefBrowserHostImpl::Invalidate(PaintElementType type) { return; } - if (!web_contents() || !platform_delegate_) - return; - - platform_delegate_->Invalidate(type); + if (platform_delegate_) + platform_delegate_->Invalidate(type); } void CefBrowserHostImpl::SendExternalBeginFrame() { @@ -1251,10 +1134,8 @@ void CefBrowserHostImpl::SendExternalBeginFrame() { return; } - if (!web_contents() || !platform_delegate_) - return; - - platform_delegate_->SendExternalBeginFrame(); + if (platform_delegate_) + platform_delegate_->SendExternalBeginFrame(); } void CefBrowserHostImpl::SendKeyEvent(const CefKeyEvent& event) { @@ -1264,10 +1145,8 @@ void CefBrowserHostImpl::SendKeyEvent(const CefKeyEvent& event) { return; } - if (!web_contents() || !platform_delegate_) - return; - - platform_delegate_->SendKeyEvent(event); + if (platform_delegate_) + platform_delegate_->SendKeyEvent(event); } void CefBrowserHostImpl::SendMouseClickEvent(const CefMouseEvent& event, @@ -1281,10 +1160,9 @@ void CefBrowserHostImpl::SendMouseClickEvent(const CefMouseEvent& event, return; } - if (!web_contents() || !platform_delegate_) - return; - - platform_delegate_->SendMouseClickEvent(event, type, mouseUp, clickCount); + if (platform_delegate_) { + platform_delegate_->SendMouseClickEvent(event, type, mouseUp, clickCount); + } } void CefBrowserHostImpl::SendMouseMoveEvent(const CefMouseEvent& event, @@ -1296,10 +1174,9 @@ void CefBrowserHostImpl::SendMouseMoveEvent(const CefMouseEvent& event, return; } - if (!web_contents() || !platform_delegate_) - return; - - platform_delegate_->SendMouseMoveEvent(event, mouseLeave); + if (platform_delegate_) { + platform_delegate_->SendMouseMoveEvent(event, mouseLeave); + } } void CefBrowserHostImpl::SendMouseWheelEvent(const CefMouseEvent& event, @@ -1317,10 +1194,25 @@ void CefBrowserHostImpl::SendMouseWheelEvent(const CefMouseEvent& event, return; } - if (!web_contents() || !platform_delegate_) - return; + if (platform_delegate_) { + platform_delegate_->SendMouseWheelEvent(event, deltaX, deltaY); + } +} - platform_delegate_->SendMouseWheelEvent(event, deltaX, deltaY); +void CefBrowserHostImpl::SendTouchEvent(const CefTouchEvent& event) { + if (!IsWindowless()) { + NOTREACHED() << "Window rendering is not disabled"; + return; + } + + if (!CEF_CURRENTLY_ON_UIT()) { + CEF_POST_TASK(CEF_UIT, + base::Bind(&CefBrowserHostImpl::SendTouchEvent, this, event)); + return; + } + + if (platform_delegate_) + platform_delegate_->SendTouchEvent(event); } void CefBrowserHostImpl::SendFocusEvent(bool setFocus) { @@ -1335,10 +1227,8 @@ void CefBrowserHostImpl::SendCaptureLostEvent() { return; } - if (!web_contents() || !platform_delegate_) - return; - - platform_delegate_->SendCaptureLostEvent(); + if (platform_delegate_) + platform_delegate_->SendCaptureLostEvent(); } void CefBrowserHostImpl::NotifyMoveOrResizeStarted() { @@ -1350,10 +1240,8 @@ void CefBrowserHostImpl::NotifyMoveOrResizeStarted() { return; } - if (!web_contents() || !platform_delegate_) - return; - - platform_delegate_->NotifyMoveOrResizeStarted(); + if (platform_delegate_) + platform_delegate_->NotifyMoveOrResizeStarted(); #endif } @@ -1581,22 +1469,6 @@ bool CefBrowserHostImpl::IsViewsHosted() const { return is_views_hosted_; } -bool CefBrowserHostImpl::IsPrintPreviewSupported() const { - CEF_REQUIRE_UIT(); - auto actionable_contents = GetActionableWebContents(); - if (!actionable_contents) - return false; - - auto cef_browser_context = CefBrowserContext::FromBrowserContext( - actionable_contents->GetBrowserContext()); - if (!cef_browser_context->IsPrintPreviewSupported()) { - return false; - } - - // Print preview is not currently supported with OSR. - return !IsWindowless(); -} - bool CefBrowserHostImpl::IsPictureInPictureSupported() const { // Not currently supported with OSR. return !IsWindowless(); @@ -1638,7 +1510,6 @@ void CefBrowserHostImpl::DestroyBrowser() { javascript_dialog_manager_->Destroy(); if (menu_manager_.get()) menu_manager_->Destroy(); - DestroyExtensionHost(); // Notify any observers that may have state associated with this browser. for (auto& observer : observers_) @@ -1649,8 +1520,6 @@ void CefBrowserHostImpl::DestroyBrowser() { registrar_.reset(nullptr); content::WebContentsObserver::Observe(nullptr); - if (owned_web_contents_) - owned_web_contents_.reset(nullptr); // Delete objects created by the platform delegate that may be referenced by // the WebContents. @@ -1781,13 +1650,19 @@ int CefBrowserHostImpl::browser_id() const { return browser_info_->browser_id(); } -content::BrowserContext* CefBrowserHostImpl::GetBrowserContext() { +content::BrowserContext* CefBrowserHostImpl::GetBrowserContext() const { CEF_REQUIRE_UIT(); if (web_contents()) return web_contents()->GetBrowserContext(); return nullptr; } +extensions::ExtensionHost* CefBrowserHostImpl::GetExtensionHost() const { + CEF_REQUIRE_UIT(); + DCHECK(platform_delegate_); + return platform_delegate_->extension_host(); +} + void CefBrowserHostImpl::OnSetFocus(cef_focus_source_t source) { if (CEF_CURRENTLY_ON_UIT()) { // SetFocus() might be called while inside the OnSetFocus() callback. If @@ -1885,11 +1760,10 @@ void CefBrowserHostImpl::ImeSetComposition( return; } - if (!web_contents() || !platform_delegate_) - return; - - platform_delegate_->ImeSetComposition(text, underlines, replacement_range, - selection_range); + if (platform_delegate_) { + platform_delegate_->ImeSetComposition(text, underlines, replacement_range, + selection_range); + } } void CefBrowserHostImpl::ImeCommitText(const CefString& text, @@ -1907,11 +1781,10 @@ void CefBrowserHostImpl::ImeCommitText(const CefString& text, return; } - if (!web_contents() || !platform_delegate_) - return; - - platform_delegate_->ImeCommitText(text, replacement_range, - relative_cursor_pos); + if (platform_delegate_) { + platform_delegate_->ImeCommitText(text, replacement_range, + relative_cursor_pos); + } } void CefBrowserHostImpl::ImeFinishComposingText(bool keep_selection) { @@ -1927,10 +1800,9 @@ void CefBrowserHostImpl::ImeFinishComposingText(bool keep_selection) { return; } - if (!web_contents() || !platform_delegate_) - return; - - platform_delegate_->ImeFinishComposingText(keep_selection); + if (platform_delegate_) { + platform_delegate_->ImeFinishComposingText(keep_selection); + } } void CefBrowserHostImpl::ImeCancelComposition() { @@ -1946,10 +1818,8 @@ void CefBrowserHostImpl::ImeCancelComposition() { return; } - if (!web_contents() || !platform_delegate_) - return; - - platform_delegate_->ImeCancelComposition(); + if (platform_delegate_) + platform_delegate_->ImeCancelComposition(); } void CefBrowserHostImpl::DragTargetDragEnter( @@ -1973,10 +1843,9 @@ void CefBrowserHostImpl::DragTargetDragEnter( return; } - if (!web_contents() || !platform_delegate_) - return; - - platform_delegate_->DragTargetDragEnter(drag_data, event, allowed_ops); + if (platform_delegate_) { + platform_delegate_->DragTargetDragEnter(drag_data, event, allowed_ops); + } } void CefBrowserHostImpl::DragTargetDragOver( @@ -1994,10 +1863,9 @@ void CefBrowserHostImpl::DragTargetDragOver( return; } - if (!web_contents() || !platform_delegate_) - return; - - platform_delegate_->DragTargetDragOver(event, allowed_ops); + if (platform_delegate_) { + platform_delegate_->DragTargetDragOver(event, allowed_ops); + } } void CefBrowserHostImpl::DragTargetDragLeave() { @@ -2012,10 +1880,8 @@ void CefBrowserHostImpl::DragTargetDragLeave() { return; } - if (!web_contents() || !platform_delegate_) - return; - - platform_delegate_->DragTargetDragLeave(); + if (platform_delegate_) + platform_delegate_->DragTargetDragLeave(); } void CefBrowserHostImpl::DragTargetDrop(const CefMouseEvent& event) { @@ -2030,10 +1896,8 @@ void CefBrowserHostImpl::DragTargetDrop(const CefMouseEvent& event) { return; } - if (!web_contents() || !platform_delegate_) - return; - - platform_delegate_->DragTargetDrop(event); + if (platform_delegate_) + platform_delegate_->DragTargetDrop(event); } void CefBrowserHostImpl::DragSourceSystemDragEnded() { @@ -2049,10 +1913,8 @@ void CefBrowserHostImpl::DragSourceSystemDragEnded() { return; } - if (!web_contents() || !platform_delegate_) - return; - - platform_delegate_->DragSourceSystemDragEnded(); + if (platform_delegate_) + platform_delegate_->DragSourceSystemDragEnded(); } void CefBrowserHostImpl::DragSourceEndedAt( @@ -2071,10 +1933,8 @@ void CefBrowserHostImpl::DragSourceEndedAt( return; } - if (!web_contents() || !platform_delegate_) - return; - - platform_delegate_->DragSourceEndedAt(x, y, op); + if (platform_delegate_) + platform_delegate_->DragSourceEndedAt(x, y, op); } void CefBrowserHostImpl::SetAudioMuted(bool mute) { @@ -2132,10 +1992,7 @@ content::WebContents* CefBrowserHostImpl::OpenURLFromTab( bool CefBrowserHostImpl::ShouldTransferNavigation( bool is_main_frame_navigation) { - if (extension_host_) { - return extension_host_->ShouldTransferNavigation(is_main_frame_navigation); - } - return true; + return platform_delegate_->ShouldTransferNavigation(is_main_frame_navigation); } void CefBrowserHostImpl::AddNewContents( @@ -2146,19 +2003,9 @@ void CefBrowserHostImpl::AddNewContents( const gfx::Rect& initial_rect, bool user_gesture, bool* was_blocked) { - CefRefPtr owner = - GetBrowserForContents(new_contents.get()); - if (owner) { - // Taking ownership of |new_contents|. - owner->set_owned_web_contents(new_contents.release()); - return; - } - - if (extension_host_) { - extension_host_->AddNewContents(source, std::move(new_contents), target_url, - disposition, initial_rect, user_gesture, - was_blocked); - } + platform_delegate_->AddNewContents(source, std::move(new_contents), + target_url, disposition, initial_rect, + user_gesture, was_blocked); } void CefBrowserHostImpl::LoadingStateChanged(content::WebContents* source, @@ -2314,16 +2161,6 @@ bool CefBrowserHostImpl::HandleContextMenu( return HandleContextMenu(web_contents(), params); } -content::WebContents* CefBrowserHostImpl::GetActionableWebContents() const { - if (web_contents() && extensions::ExtensionsEnabled()) { - content::WebContents* guest_contents = - extensions::GetFullPageGuestForOwnerContents(web_contents()); - if (guest_contents) - return guest_contents; - } - return web_contents(); -} - KeyboardEventProcessingResult CefBrowserHostImpl::PreHandleKeyboardEvent( content::WebContents* source, const content::NativeWebKeyboardEvent& event) { @@ -2379,9 +2216,7 @@ bool CefBrowserHostImpl::HandleKeyboardEvent( bool CefBrowserHostImpl::PreHandleGestureEvent( content::WebContents* source, const blink::WebGestureEvent& event) { - if (extension_host_) - return extension_host_->PreHandleGestureEvent(source, event); - return false; + return platform_delegate_->PreHandleGestureEvent(source, event); } bool CefBrowserHostImpl::CanDragEnter(content::WebContents* source, @@ -2433,22 +2268,23 @@ void CefBrowserHostImpl::WebContentsCreated( scoped_refptr info = CefBrowserInfoManager::GetInstance()->CreatePopupBrowserInfo( new_contents, platform_delegate->IsWindowless(), extra_info); - DCHECK(info.get()); - DCHECK(info->is_popup()); + CHECK(info.get()); + CHECK(info->is_popup()); CefRefPtr opener = GetBrowserForContents(source_contents); - if (!opener.get()) + if (!opener) return; // Popups must share the same RequestContext as the parent. CefRefPtr request_context = opener->request_context(); - DCHECK(request_context); + CHECK(request_context); // We don't officially own |new_contents| until AddNewContents() is called. // However, we need to install observers/delegates here. CefRefPtr browser = - CreateInternal(settings, client, new_contents, false, info, opener, false, - request_context, std::move(platform_delegate), nullptr); + CreateInternal(settings, client, new_contents, /*own_web_contents=*/false, + info, opener, /*is_devtools_popup=*/false, request_context, + std::move(platform_delegate), /*cef_extension=*/nullptr); } void CefBrowserHostImpl::DidNavigateMainFramePostCommit( @@ -2579,9 +2415,7 @@ bool CefBrowserHostImpl::CheckMediaAccessPermission( } bool CefBrowserHostImpl::IsNeverComposited(content::WebContents* web_contents) { - if (extension_host_) - return extension_host_->IsNeverComposited(web_contents); - return false; + return platform_delegate_->IsNeverComposited(web_contents); } content::PictureInPictureResult CefBrowserHostImpl::EnterPictureInPicture( @@ -2658,7 +2492,7 @@ void CefBrowserHostImpl::RenderViewDeleted( } void CefBrowserHostImpl::RenderViewReady() { - ConfigureAutoResize(); + platform_delegate_->ConfigureAutoResize(); if (client_.get()) { CefRefPtr handler = client_->GetRequestHandler(); @@ -3021,8 +2855,6 @@ CefBrowserHostImpl::CefBrowserHostImpl( DCHECK(!browser_info_->browser().get()); browser_info_->SetBrowser(this); - web_contents->SetDelegate(this); - // Associate the WebContents with this browser object. WebContentsUserDataAdapter::Register(this); @@ -3037,31 +2869,11 @@ CefBrowserHostImpl::CefBrowserHostImpl( content::Source( &web_contents->GetController())); - PrefsTabHelper::CreateForWebContents(web_contents); - printing::CefPrintViewManager::CreateForWebContents(web_contents); - - if (extensions::ExtensionsEnabled()) { - extensions::CefExtensionWebContentsObserver::CreateForWebContents( - web_contents); - - // Used by the tabs extension API. - zoom::ZoomController::CreateForWebContents(web_contents); - } + // Associate the platform delegate with this browser. + platform_delegate_->BrowserCreated(this); // Make sure RenderViewCreated is called at least one time. RenderViewCreated(web_contents->GetRenderViewHost()); - - // Associate the platform delegate with this browser. - platform_delegate_->BrowserCreated(this); -} - -void CefBrowserHostImpl::set_owned_web_contents( - content::WebContents* owned_contents) { - // Should not currently own a WebContents. - CHECK(!owned_web_contents_); - // Should already be associated with |owned_contents|. - CHECK(web_contents() == owned_contents); - owned_web_contents_.reset(owned_contents); } bool CefBrowserHostImpl::CreateHostWindow() { @@ -3075,58 +2887,6 @@ bool CefBrowserHostImpl::CreateHostWindow() { return success; } -void CefBrowserHostImpl::CreateExtensionHost( - const extensions::Extension* extension, - content::BrowserContext* browser_context, - content::WebContents* host_contents, - const GURL& url, - extensions::ViewType host_type) { - DCHECK(!extension_host_); - - 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( - this, extension, browser_context, host_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; - // Create an extension host that will be owned by ProcessManager. - extension_host_ = new extensions::CefExtensionBackgroundHost( - this, base::BindOnce(&CefBrowserHostImpl::OnExtensionHostDeleted, this), - extension, browser_context, host_contents, url, host_type); - // Load will be triggered by ProcessManager::CreateBackgroundHost. - } else { - NOTREACHED() << " Unsupported extension host type: " << host_type; - } -} - -void CefBrowserHostImpl::DestroyExtensionHost() { - if (!extension_host_) - return; - if (extension_host_->extension_host_type() == - extensions::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) { - DCHECK(is_background_host_); - // Close notification for background pages arrives via CloseContents. - // The extension host will be deleted by - // ProcessManager::CloseBackgroundHost and OnExtensionHostDeleted will be - // called to notify us. - extension_host_->Close(); - } else { - DCHECK(!is_background_host_); - // We own the extension host and must delete it. - delete extension_host_; - extension_host_ = nullptr; - } -} - -void CefBrowserHostImpl::OnExtensionHostDeleted() { - DCHECK(is_background_host_); - DCHECK(extension_host_); - extension_host_ = nullptr; -} - gfx::Point CefBrowserHostImpl::GetScreenPoint(const gfx::Point& view) const { CEF_REQUIRE_UIT(); if (platform_delegate_) @@ -3228,35 +2988,3 @@ void CefBrowserHostImpl::EnsureFileDialogManager() { this, platform_delegate_->CreateFileDialogRunner())); } } - -void CefBrowserHostImpl::ConfigureAutoResize() { - CEF_REQUIRE_UIT(); - if (!web_contents() || !web_contents()->GetRenderWidgetHostView()) { - return; - } - - if (auto_resize_enabled_) { - web_contents()->GetRenderWidgetHostView()->EnableAutoResize( - auto_resize_min_, auto_resize_max_); - } else { - web_contents()->GetRenderWidgetHostView()->DisableAutoResize(gfx::Size()); - } -} - -void CefBrowserHostImpl::SendTouchEvent(const CefTouchEvent& event) { - if (!IsWindowless()) { - NOTREACHED() << "Window rendering is not disabled"; - return; - } - - if (!CEF_CURRENTLY_ON_UIT()) { - CEF_POST_TASK(CEF_UIT, - base::Bind(&CefBrowserHostImpl::SendTouchEvent, this, event)); - return; - } - - if (!web_contents() || !platform_delegate_) - return; - - platform_delegate_->SendTouchEvent(event); -} diff --git a/libcef/browser/browser_host_impl.h b/libcef/browser/browser_host_impl.h index e57075a32..a57482746 100644 --- a/libcef/browser/browser_host_impl.h +++ b/libcef/browser/browser_host_impl.h @@ -285,9 +285,6 @@ class CefBrowserHostImpl : public CefBrowserHost, // Returns true if this browser is views-hosted. bool IsViewsHosted() const; - // Returns true if this browser supports print preview. - bool IsPrintPreviewSupported() const; - // Returns true if this browser supports picture-in-picture. bool IsPictureInPictureSupported() const; @@ -354,8 +351,8 @@ class CefBrowserHostImpl : public CefBrowserHost, } // Accessors that must be called on the UI thread. - content::BrowserContext* GetBrowserContext(); - extensions::ExtensionHost* extension_host() const { return extension_host_; } + content::BrowserContext* GetBrowserContext() const; + extensions::ExtensionHost* GetExtensionHost() const; void OnSetFocus(cef_focus_source_t source); @@ -368,12 +365,6 @@ class CefBrowserHostImpl : public CefBrowserHost, bool HandleContextMenu(content::WebContents* web_contents, const content::ContextMenuParams& params); - // Returns the WebContents most likely to handle an action. If extensions are - // enabled and this browser has a full-page guest (for example, a full-page - // PDF viewer extension) then the guest's WebContents will be returned. - // Otherwise, the browser's WebContents will be returned. - content::WebContents* GetActionableWebContents() const; - enum DestructionState { DESTRUCTION_STATE_NONE = 0, DESTRUCTION_STATE_PENDING, @@ -408,7 +399,6 @@ class CefBrowserHostImpl : public CefBrowserHost, bool proceed, bool* proceed_to_fire_unload) override; bool TakeFocus(content::WebContents* source, bool reverse) override; - bool HandleContextMenu(content::RenderFrameHost* render_frame_host, const content::ContextMenuParams& params) override; content::KeyboardEventProcessingResult PreHandleKeyboardEvent( @@ -507,7 +497,6 @@ class CefBrowserHostImpl : public CefBrowserHost, void AccessibilityLocationChangesReceived( const std::vector& locData) override; - void OnWebContentsFocused( content::RenderWidgetHost* render_widget_host) override; @@ -533,6 +522,8 @@ class CefBrowserHostImpl : public CefBrowserHost, std::unique_ptr CreateNavigationLock(); private: + friend class CefBrowserPlatformDelegate; + static CefRefPtr CreateInternal( const CefBrowserSettings& settings, CefRefPtr client, @@ -560,20 +551,9 @@ class CefBrowserHostImpl : public CefBrowserHost, std::unique_ptr platform_delegate, CefRefPtr extension); - void set_owned_web_contents(content::WebContents* owned_contents); - // Give the platform delegate an opportunity to create the host window. bool CreateHostWindow(); - // Create/delete the host for extensions. - void CreateExtensionHost(const extensions::Extension* extension, - content::BrowserContext* browser_context, - content::WebContents* host_contents, - const GURL& url, - extensions::ViewType host_type); - void DestroyExtensionHost(); - void OnExtensionHostDeleted(); - // Returns true if navigation actions are currently locked. bool navigation_locked() const; // Action to be executed once the navigation lock is released. @@ -592,8 +572,6 @@ class CefBrowserHostImpl : public CefBrowserHost, // Create the CefFileDialogManager if it doesn't already exist. void EnsureFileDialogManager(); - void ConfigureAutoResize(); - void StartAudioCapturer(); void OnRecentlyAudibleTimerFired(); @@ -610,12 +588,8 @@ class CefBrowserHostImpl : public CefBrowserHost, const bool is_windowless_; const bool is_views_hosted_; CefWindowHandle host_window_handle_ = kNullWindowHandle; - - // Non-nullptr if this object owns the WebContents. Will be nullptr for popup - // browsers between the calls to WebContentsCreated() and AddNewContents(), - // and may never be set if the parent browser is destroyed during popup - // creation. - std::unique_ptr owned_web_contents_; + CefRefPtr extension_; + bool is_background_host_ = false; // Volatile state information. All access must be protected by the state lock. base::Lock state_lock_; @@ -671,14 +645,6 @@ class CefBrowserHostImpl : public CefBrowserHost, // Observers that want to be notified of changes to this object. base::ObserverList::Unchecked observers_; - // Used to provide unique incremental IDs for each find request. - int find_request_id_counter_ = 0; - - // Used when the browser is hosting an extension. - extensions::ExtensionHost* extension_host_ = nullptr; - CefRefPtr extension_; - bool is_background_host_ = false; - // Used for capturing audio for CefAudioHandler. std::unique_ptr audio_capturer_; @@ -687,11 +653,6 @@ class CefBrowserHostImpl : public CefBrowserHost, // being audible again before it fires. base::OneShotTimer recently_audible_timer_; - // Used with auto-resize. - bool auto_resize_enabled_ = false; - gfx::Size auto_resize_min_; - gfx::Size auto_resize_max_; - IMPLEMENT_REFCOUNTING(CefBrowserHostImpl); DISALLOW_COPY_AND_ASSIGN(CefBrowserHostImpl); }; diff --git a/libcef/browser/browser_platform_delegate.cc b/libcef/browser/browser_platform_delegate.cc index 5a7790628..97dca7606 100644 --- a/libcef/browser/browser_platform_delegate.cc +++ b/libcef/browser/browser_platform_delegate.cc @@ -5,21 +5,97 @@ #include "libcef/browser/browser_platform_delegate.h" #include "libcef/browser/browser_host_impl.h" -#include "libcef/browser/osr/browser_platform_delegate_osr.h" +#include "libcef/browser/extensions/browser_extensions_util.h" +#include "libcef/browser/extensions/extension_background_host.h" +#include "libcef/browser/extensions/extension_system.h" +#include "libcef/browser/extensions/extension_view_host.h" +#include "libcef/browser/extensions/extension_web_contents_observer.h" +#include "libcef/browser/printing/print_view_manager.h" #include "libcef/browser/web_contents_dialog_helper.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" +#include "chrome/browser/ui/prefs/prefs_tab_helper.h" +#include "components/zoom/zoom_controller.h" #include "content/browser/renderer_host/render_widget_host_impl.h" +#include "content/browser/web_contents/web_contents_impl.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/render_widget_host.h" +#include "extensions/browser/process_manager.h" +#include "third_party/blink/public/mojom/frame/find_in_page.mojom.h" -CefBrowserPlatformDelegate::CefBrowserPlatformDelegate() {} +CefBrowserPlatformDelegate::CefBrowserPlatformDelegate() + : weak_ptr_factory_(this) {} CefBrowserPlatformDelegate::~CefBrowserPlatformDelegate() { DCHECK(!browser_); } +content::WebContents* CefBrowserPlatformDelegate::CreateWebContents( + CefBrowserHostImpl::CreateParams& create_params, + bool& own_web_contents) { + // TODO(chrome-runtime): Add a path to create a Browser. + REQUIRE_ALLOY_RUNTIME(); + + // Get or create the request context and browser context. + CefRefPtr request_context_impl = + CefRequestContextImpl::GetOrCreateForRequestContext( + create_params.request_context); + CHECK(request_context_impl); + auto cef_browser_context = request_context_impl->GetBrowserContext(); + CHECK(cef_browser_context); + auto browser_context = cef_browser_context->AsBrowserContext(); + + if (!create_params.request_context) { + // Using the global request context. + create_params.request_context = request_context_impl.get(); + } + + scoped_refptr site_instance; + if (extensions::ExtensionsEnabled() && !create_params.url.is_empty()) { + if (!create_params.extension) { + // We might be loading an extension app view where the extension URL is + // provided by the client. + create_params.extension = + extensions::GetExtensionForUrl(browser_context, create_params.url); + } + if (create_params.extension) { + if (create_params.extension_host_type == extensions::VIEW_TYPE_INVALID) { + // Default to dialog behavior. + create_params.extension_host_type = + extensions::VIEW_TYPE_EXTENSION_DIALOG; + } + + // Extension resources will fail to load if we don't use a SiteInstance + // associated with the extension. + // (AlloyContentBrowserClient::SiteInstanceGotProcess won't find the + // extension to register with InfoMap, and AllowExtensionResourceLoad in + // ExtensionProtocolHandler::MaybeCreateJob will return false resulting in + // ERR_BLOCKED_BY_CLIENT). + site_instance = extensions::ProcessManager::Get(browser_context) + ->GetSiteInstanceForURL(create_params.url); + DCHECK(site_instance); + } + } + + content::WebContents::CreateParams wc_create_params(browser_context, + site_instance); + + if (IsWindowless()) { + // Create the OSR view for the WebContents. + CreateViewForWebContents(&wc_create_params.view, + &wc_create_params.delegate_view); + } + + auto web_contents = content::WebContents::Create(wc_create_params); + CHECK(web_contents); + + own_web_contents = true; + return web_contents.release(); +} + void CefBrowserPlatformDelegate::CreateViewForWebContents( content::WebContentsView** view, content::RenderViewHostDelegateView** delegate_view) { @@ -27,7 +103,50 @@ void CefBrowserPlatformDelegate::CreateViewForWebContents( } void CefBrowserPlatformDelegate::WebContentsCreated( - content::WebContents* web_contents) {} + content::WebContents* web_contents, + bool owned) { + // We should not have a browser at this point. + DCHECK(!browser_); + + DCHECK(!web_contents_); + web_contents_ = web_contents; + if (owned) { + SetOwnedWebContents(web_contents); + } +} + +void CefBrowserPlatformDelegate::AddNewContents( + content::WebContents* source, + std::unique_ptr new_contents, + const GURL& target_url, + WindowOpenDisposition disposition, + const gfx::Rect& initial_rect, + bool user_gesture, + bool* was_blocked) { + REQUIRE_ALLOY_RUNTIME(); + + CefRefPtr owner = + CefBrowserHostImpl::GetBrowserForContents(new_contents.get()); + if (owner) { + // Taking ownership of |new_contents|. + owner->platform_delegate_->SetOwnedWebContents(new_contents.release()); + return; + } + + if (extension_host_) { + extension_host_->AddNewContents(source, std::move(new_contents), target_url, + disposition, initial_rect, user_gesture, + was_blocked); + } +} + +bool CefBrowserPlatformDelegate::ShouldTransferNavigation( + bool is_main_frame_navigation) { + if (extension_host_) { + return extension_host_->ShouldTransferNavigation(is_main_frame_navigation); + } + return true; +} void CefBrowserPlatformDelegate::RenderViewCreated( content::RenderViewHost* render_view_host) { @@ -38,13 +157,60 @@ void CefBrowserPlatformDelegate::RenderViewCreated( } void CefBrowserPlatformDelegate::BrowserCreated(CefBrowserHostImpl* browser) { + // We should have an associated WebContents at this point. + DCHECK(web_contents_); + DCHECK(!browser_); DCHECK(browser); browser_ = browser; - if (browser_->IsPrintPreviewSupported()) { + web_contents_->SetDelegate(browser); + + PrefsTabHelper::CreateForWebContents(web_contents_); + printing::CefPrintViewManager::CreateForWebContents(web_contents_); + + if (extensions::ExtensionsEnabled()) { + extensions::CefExtensionWebContentsObserver::CreateForWebContents( + web_contents_); + + // Used by the tabs extension API. + zoom::ZoomController::CreateForWebContents(web_contents_); + } + + if (IsPrintPreviewSupported()) { web_contents_dialog_helper_.reset( - new CefWebContentsDialogHelper(browser_->web_contents(), this)); + new CefWebContentsDialogHelper(web_contents_, this)); + } +} + +void CefBrowserPlatformDelegate::CreateExtensionHost( + const extensions::Extension* extension, + const GURL& url, + extensions::ViewType host_type) { + // Should get WebContentsCreated and BrowserCreated calls first. + DCHECK(web_contents_); + DCHECK(browser_); + DCHECK(!extension_host_); + + 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); + // 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; + // Create an extension host that will be owned by ProcessManager. + extension_host_ = new extensions::CefExtensionBackgroundHost( + browser_, + base::BindOnce(&CefBrowserPlatformDelegate::OnExtensionHostDeleted, + weak_ptr_factory_.GetWeakPtr()), + extension, web_contents_, url, host_type); + // Load will be triggered by ProcessManager::CreateBackgroundHost. + } else { + NOTREACHED() << " Unsupported extension host type: " << host_type; } } @@ -53,6 +219,10 @@ void CefBrowserPlatformDelegate::NotifyBrowserCreated() {} void CefBrowserPlatformDelegate::NotifyBrowserDestroyed() {} void CefBrowserPlatformDelegate::BrowserDestroyed(CefBrowserHostImpl* browser) { + DestroyExtensionHost(); + owned_web_contents_.reset(); + web_contents_ = nullptr; + DCHECK(browser_ && browser_ == browser); browser_ = nullptr; } @@ -107,6 +277,21 @@ void CefBrowserPlatformDelegate::NotifyMoveOrResizeStarted() { void CefBrowserPlatformDelegate::SizeTo(int width, int height) {} #endif +bool CefBrowserPlatformDelegate::PreHandleGestureEvent( + content::WebContents* source, + const blink::WebGestureEvent& event) { + if (extension_host_) + return extension_host_->PreHandleGestureEvent(source, event); + return false; +} + +bool CefBrowserPlatformDelegate::IsNeverComposited( + content::WebContents* web_contents) { + if (extension_host_) + return extension_host_->IsNeverComposited(web_contents); + return false; +} + std::unique_ptr CefBrowserPlatformDelegate::CreateFileDialogRunner() { return nullptr; @@ -228,6 +413,140 @@ gfx::Size CefBrowserPlatformDelegate::GetMaximumDialogSize() { return gfx::Size(); } +void CefBrowserPlatformDelegate::SetAutoResizeEnabled(bool enabled, + const CefSize& min_size, + const CefSize& max_size) { + if (enabled == auto_resize_enabled_) + return; + + auto_resize_enabled_ = enabled; + if (enabled) { + auto_resize_min_ = gfx::Size(min_size.width, min_size.height); + auto_resize_max_ = gfx::Size(max_size.width, max_size.height); + } else { + auto_resize_min_ = auto_resize_max_ = gfx::Size(); + } + ConfigureAutoResize(); +} + +void CefBrowserPlatformDelegate::ConfigureAutoResize() { + if (!web_contents_ || !web_contents_->GetRenderWidgetHostView()) { + return; + } + + if (auto_resize_enabled_) { + web_contents_->GetRenderWidgetHostView()->EnableAutoResize( + auto_resize_min_, auto_resize_max_); + } else { + web_contents_->GetRenderWidgetHostView()->DisableAutoResize(gfx::Size()); + } +} + +void CefBrowserPlatformDelegate::SetAccessibilityState( + cef_state_t accessibility_state) { + // Do nothing if state is set to default. It'll be disabled by default and + // controlled by the commmand-line flags "force-renderer-accessibility" and + // "disable-renderer-accessibility". + if (accessibility_state == STATE_DEFAULT) + return; + + content::WebContentsImpl* web_contents_impl = + static_cast(web_contents_); + + if (!web_contents_impl) + return; + + ui::AXMode accMode; + // In windowless mode set accessibility to TreeOnly mode. Else native + // accessibility APIs, specific to each platform, are also created. + if (accessibility_state == STATE_ENABLED) { + accMode = IsWindowless() ? ui::kAXModeWebContentsOnly : ui::kAXModeComplete; + } + web_contents_impl->SetAccessibilityMode(accMode); +} + +bool CefBrowserPlatformDelegate::IsPrintPreviewSupported() const { + CEF_REQUIRE_UIT(); + auto actionable_contents = GetActionableWebContents(); + if (!actionable_contents) + return false; + + auto cef_browser_context = CefBrowserContext::FromBrowserContext( + actionable_contents->GetBrowserContext()); + if (!cef_browser_context->IsPrintPreviewSupported()) { + return false; + } + + // Print preview is not currently supported with OSR. + return !IsWindowless(); +} + +void CefBrowserPlatformDelegate::Print() { + auto actionable_contents = GetActionableWebContents(); + if (!actionable_contents) + return; + + auto rfh = actionable_contents->GetMainFrame(); + + if (IsPrintPreviewSupported()) { + printing::CefPrintViewManager::FromWebContents(actionable_contents) + ->PrintPreviewNow(rfh, false); + } else { + printing::PrintViewManager::FromWebContents(actionable_contents) + ->PrintNow(rfh); + } +} + +void CefBrowserPlatformDelegate::PrintToPDF( + const CefString& path, + const CefPdfPrintSettings& settings, + CefRefPtr callback) { + content::WebContents* actionable_contents = GetActionableWebContents(); + if (!actionable_contents) + return; + printing::CefPrintViewManager::PdfPrintCallback pdf_callback; + if (callback.get()) { + pdf_callback = base::Bind(&CefPdfPrintCallback::OnPdfPrintFinished, + callback.get(), path); + } + printing::CefPrintViewManager::FromWebContents(actionable_contents) + ->PrintToPDF(actionable_contents->GetMainFrame(), base::FilePath(path), + settings, pdf_callback); +} + +void CefBrowserPlatformDelegate::Find(int identifier, + const CefString& searchText, + bool forward, + bool matchCase, + bool findNext) { + if (!web_contents_) + return; + + // Every find request must have a unique ID and these IDs must strictly + // increase so that newer requests always have greater IDs than older + // requests. + if (identifier <= find_request_id_counter_) + identifier = ++find_request_id_counter_; + else + find_request_id_counter_ = identifier; + + auto options = blink::mojom::FindOptions::New(); + options->forward = forward; + options->match_case = matchCase; + options->find_next = findNext; + web_contents_->Find(identifier, searchText, std::move(options)); +} + +void CefBrowserPlatformDelegate::StopFinding(bool clearSelection) { + if (!web_contents_) + return; + + content::StopFindAction action = + clearSelection ? content::STOP_FIND_ACTION_CLEAR_SELECTION + : content::STOP_FIND_ACTION_KEEP_SELECTION; + web_contents_->StopFinding(action); +} + base::RepeatingClosure CefBrowserPlatformDelegate::GetBoundsChangedCallback() { if (web_contents_dialog_helper_) { return web_contents_dialog_helper_->GetBoundsChangedCallback(); @@ -267,3 +586,48 @@ int CefBrowserPlatformDelegate::TranslateWebEventModifiers( result |= blink::WebInputEvent::kIsKeyPad; return result; } + +content::WebContents* CefBrowserPlatformDelegate::GetActionableWebContents() + const { + if (web_contents_ && extensions::ExtensionsEnabled()) { + content::WebContents* guest_contents = + extensions::GetFullPageGuestForOwnerContents(web_contents_); + if (guest_contents) + return guest_contents; + } + return web_contents_; +} + +void CefBrowserPlatformDelegate::SetOwnedWebContents( + content::WebContents* owned_contents) { + REQUIRE_ALLOY_RUNTIME(); + + // Should not currently own a WebContents. + CHECK(!owned_web_contents_); + owned_web_contents_.reset(owned_contents); +} + +void CefBrowserPlatformDelegate::DestroyExtensionHost() { + if (!extension_host_) + return; + if (extension_host_->extension_host_type() == + extensions::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) { + DCHECK(is_background_host_); + // Close notification for background pages arrives via CloseContents. + // The extension host will be deleted by + // ProcessManager::CloseBackgroundHost and OnExtensionHostDeleted will be + // called to notify us. + extension_host_->Close(); + } else { + DCHECK(!is_background_host_); + // We own the extension host and must delete it. + delete extension_host_; + extension_host_ = nullptr; + } +} + +void CefBrowserPlatformDelegate::OnExtensionHostDeleted() { + DCHECK(is_background_host_); + DCHECK(extension_host_); + extension_host_ = nullptr; +} diff --git a/libcef/browser/browser_platform_delegate.h b/libcef/browser/browser_platform_delegate.h index a14c7ff4e..317f51e9e 100644 --- a/libcef/browser/browser_platform_delegate.h +++ b/libcef/browser/browser_platform_delegate.h @@ -16,6 +16,7 @@ #include "libcef/browser/browser_host_impl.h" #include "base/callback_forward.h" +#include "base/memory/weak_ptr.h" #include "content/public/browser/web_contents.h" namespace blink { @@ -32,6 +33,10 @@ class RenderViewHostDelegateView; class WebContentsView; } // namespace content +namespace extensions { +class ExtensionHost; +} + #if defined(USE_AURA) namespace views { class Widget; @@ -54,6 +59,13 @@ class CefBrowserPlatformDelegate { static std::unique_ptr Create( CefBrowserHostImpl::CreateParams& create_params); + // Called from CefBrowserHostImpl::Create. + // Wait for the call to WebContentsCreated(owned=true) before taking ownership + // of the resulting WebContents object. + virtual content::WebContents* CreateWebContents( + CefBrowserHostImpl::CreateParams& 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 // used with windowless rendering. @@ -61,9 +73,28 @@ class CefBrowserPlatformDelegate { content::WebContentsView** view, content::RenderViewHostDelegateView** delegate_view); - // Called after the WebContents for the browser is created. Will only be - // called a single time per instance. - virtual void WebContentsCreated(content::WebContents* web_contents); + // Called after the WebContents for a browser has been created. |owned| will + // be true if |web_contents| was created via CreateWebContents() and we should + // take ownership. This will also be called for popup WebContents created + // indirectly by Chromium. Will only be called a single time per instance. + virtual void WebContentsCreated(content::WebContents* web_contents, + bool owned); + + // Called when Chromium is ready to hand over ownership of a popup + // WebContents. WebContentsCreated(owned=false) will be called first for + // |new_contents|. Will only be called a single time per instance. See also + // the WebContentsDelegate documentation. + virtual void AddNewContents( + content::WebContents* source, + std::unique_ptr new_contents, + const GURL& target_url, + WindowOpenDisposition disposition, + const gfx::Rect& initial_rect, + bool user_gesture, + bool* was_blocked); + + // See WebContentsDelegate documentation. + virtual bool ShouldTransferNavigation(bool is_main_frame_navigation); // Called after the RenderViewHost is created. virtual void RenderViewCreated(content::RenderViewHost* render_view_host); @@ -73,6 +104,11 @@ class CefBrowserPlatformDelegate { // method. virtual void BrowserCreated(CefBrowserHostImpl* browser); + // Called from CefBrowserHostImpl::Create. + void CreateExtensionHost(const extensions::Extension* extension, + const GURL& url, + extensions::ViewType host_type); + // Send any notifications related to browser creation. Called after // BrowserCreated(). virtual void NotifyBrowserCreated(); @@ -189,6 +225,13 @@ class CefBrowserPlatformDelegate { virtual bool HandleKeyboardEvent( const content::NativeWebKeyboardEvent& event) = 0; + // See WebContentsDelegate documentation. + virtual bool PreHandleGestureEvent(content::WebContents* source, + const blink::WebGestureEvent& event); + + // See WebContentsDelegate documentation. + virtual bool IsNeverComposited(content::WebContents* web_contents); + // Invoke platform specific handling for the external protocol. static void HandleExternalProtocol(const GURL& url); @@ -267,6 +310,26 @@ class CefBrowserPlatformDelegate { virtual gfx::Point GetDialogPosition(const gfx::Size& size); virtual gfx::Size GetMaximumDialogSize(); + // See CefBrowserHost documentation. + void SetAutoResizeEnabled(bool enabled, + const CefSize& min_size, + const CefSize& max_size); + virtual void ConfigureAutoResize(); + virtual void SetAccessibilityState(cef_state_t accessibility_state); + virtual bool IsPrintPreviewSupported() const; + virtual void Print(); + virtual void PrintToPDF(const CefString& path, + const CefPdfPrintSettings& settings, + CefRefPtr callback); + virtual void Find(int identifier, + const CefString& searchText, + bool forward, + bool matchCase, + bool findNext); + virtual void StopFinding(bool clearSelection); + + extensions::ExtensionHost* extension_host() const { return extension_host_; } + protected: // Allow deletion via scoped_ptr only. friend std::default_delete; @@ -278,12 +341,45 @@ class CefBrowserPlatformDelegate { static int TranslateWebEventModifiers(uint32 cef_modifiers); - CefBrowserHostImpl* browser_ = nullptr; // Not owned by this object. + // Returns the WebContents most likely to handle an action. If extensions are + // enabled and this browser has a full-page guest (for example, a full-page + // PDF viewer extension) then the guest's WebContents will be returned. + // Otherwise, the browser's WebContents will be returned. + content::WebContents* GetActionableWebContents() const; + + // Not owned by this object. + content::WebContents* web_contents_ = nullptr; + CefBrowserHostImpl* browser_ = nullptr; private: + void SetOwnedWebContents(content::WebContents* owned_contents); + + void DestroyExtensionHost(); + void OnExtensionHostDeleted(); + + // Non-nullptr if this object owns the WebContents. Will be nullptr for popup + // browsers between the calls to WebContentsCreated() and AddNewContents(), + // and may never be set if the parent browser is destroyed during popup + // creation. + std::unique_ptr owned_web_contents_; + // Used for the print preview dialog. std::unique_ptr web_contents_dialog_helper_; + // Used to provide unique incremental IDs for each find request. + int find_request_id_counter_ = 0; + + // Used when the browser is hosting an extension. + extensions::ExtensionHost* extension_host_ = nullptr; + bool is_background_host_ = false; + + // Used with auto-resize. + bool auto_resize_enabled_ = false; + gfx::Size auto_resize_min_; + gfx::Size auto_resize_max_; + + base::WeakPtrFactory weak_ptr_factory_; + DISALLOW_COPY_AND_ASSIGN(CefBrowserPlatformDelegate); }; diff --git a/libcef/browser/extensions/extension_background_host.cc b/libcef/browser/extensions/extension_background_host.cc index 2f5cbc878..d14efe194 100644 --- a/libcef/browser/extensions/extension_background_host.cc +++ b/libcef/browser/extensions/extension_background_host.cc @@ -15,13 +15,12 @@ CefExtensionBackgroundHost::CefExtensionBackgroundHost( CefBrowserHostImpl* browser, base::OnceClosure deleted_callback, const Extension* extension, - content::BrowserContext* browser_context, content::WebContents* host_contents, const GURL& url, ViewType host_type) : ExtensionHost(new CefExtensionHostDelegate(browser), extension, - browser_context, + host_contents->GetBrowserContext(), host_contents, url, host_type), diff --git a/libcef/browser/extensions/extension_background_host.h b/libcef/browser/extensions/extension_background_host.h index bdefe8130..086763ca6 100644 --- a/libcef/browser/extensions/extension_background_host.h +++ b/libcef/browser/extensions/extension_background_host.h @@ -27,7 +27,6 @@ class CefExtensionBackgroundHost : public ExtensionHost { CefExtensionBackgroundHost(CefBrowserHostImpl* browser, base::OnceClosure deleted_callback, const Extension* extension, - content::BrowserContext* browser_context, content::WebContents* host_contents, const GURL& url, ViewType host_type); diff --git a/libcef/browser/extensions/extension_view_host.cc b/libcef/browser/extensions/extension_view_host.cc index d7af71626..eb34ab03d 100644 --- a/libcef/browser/extensions/extension_view_host.cc +++ b/libcef/browser/extensions/extension_view_host.cc @@ -21,16 +21,14 @@ using content::WebContentsObserver; namespace extensions { -CefExtensionViewHost::CefExtensionViewHost( - CefBrowserHostImpl* browser, - const Extension* extension, - content::BrowserContext* browser_context, - content::WebContents* host_contents, - const GURL& url, - ViewType host_type) +CefExtensionViewHost::CefExtensionViewHost(CefBrowserHostImpl* browser, + const Extension* extension, + content::WebContents* host_contents, + const GURL& url, + ViewType host_type) : ExtensionHost(new CefExtensionHostDelegate(browser), extension, - browser_context, + host_contents->GetBrowserContext(), host_contents, url, host_type) { diff --git a/libcef/browser/extensions/extension_view_host.h b/libcef/browser/extensions/extension_view_host.h index 438f7e0b2..fe0d2ea98 100644 --- a/libcef/browser/extensions/extension_view_host.h +++ b/libcef/browser/extensions/extension_view_host.h @@ -29,7 +29,6 @@ class CefExtensionViewHost : public ExtensionHost, public: CefExtensionViewHost(CefBrowserHostImpl* browser, const Extension* extension, - content::BrowserContext* browser_context, content::WebContents* host_contents, const GURL& url, ViewType host_type); diff --git a/libcef/browser/extensions/extensions_browser_client.cc b/libcef/browser/extensions/extensions_browser_client.cc index 95cc8c274..3751ce70c 100644 --- a/libcef/browser/extensions/extensions_browser_client.cc +++ b/libcef/browser/extensions/extensions_browser_client.cc @@ -272,7 +272,7 @@ bool CefExtensionsBrowserClient::CreateBackgroundExtensionHost( CefRefPtr browser = CefBrowserHostImpl::Create(create_params); if (browser) { - *host = browser->extension_host(); + *host = browser->GetExtensionHost(); DCHECK(*host); } return true; diff --git a/libcef/browser/osr/browser_platform_delegate_osr.cc b/libcef/browser/osr/browser_platform_delegate_osr.cc index 42e003db5..829ae8b63 100644 --- a/libcef/browser/osr/browser_platform_delegate_osr.cc +++ b/libcef/browser/osr/browser_platform_delegate_osr.cc @@ -38,8 +38,9 @@ void CefBrowserPlatformDelegateOsr::CreateViewForWebContents( } void CefBrowserPlatformDelegateOsr::WebContentsCreated( - content::WebContents* web_contents) { - CefBrowserPlatformDelegate::WebContentsCreated(web_contents); + content::WebContents* web_contents, + bool owned) { + CefBrowserPlatformDelegate::WebContentsCreated(web_contents, owned); DCHECK(view_osr_); DCHECK(!view_osr_->web_contents()); diff --git a/libcef/browser/osr/browser_platform_delegate_osr.h b/libcef/browser/osr/browser_platform_delegate_osr.h index ffb6d855a..4dc3fcd44 100644 --- a/libcef/browser/osr/browser_platform_delegate_osr.h +++ b/libcef/browser/osr/browser_platform_delegate_osr.h @@ -24,7 +24,8 @@ class CefBrowserPlatformDelegateOsr void CreateViewForWebContents( content::WebContentsView** view, content::RenderViewHostDelegateView** delegate_view) override; - void WebContentsCreated(content::WebContents* web_contents) override; + void WebContentsCreated(content::WebContents* web_contents, + bool owned) override; void BrowserCreated(CefBrowserHostImpl* browser) override; void BrowserDestroyed(CefBrowserHostImpl* browser) override; SkColor GetBackgroundColor() const override; diff --git a/libcef/browser/views/browser_platform_delegate_views.cc b/libcef/browser/views/browser_platform_delegate_views.cc index 48c09f712..ae4b615b9 100644 --- a/libcef/browser/views/browser_platform_delegate_views.cc +++ b/libcef/browser/views/browser_platform_delegate_views.cc @@ -66,8 +66,9 @@ void CefBrowserPlatformDelegateViews::SetBrowserView( } void CefBrowserPlatformDelegateViews::WebContentsCreated( - content::WebContents* web_contents) { - CefBrowserPlatformDelegate::WebContentsCreated(web_contents); + content::WebContents* web_contents, + bool owned) { + CefBrowserPlatformDelegate::WebContentsCreated(web_contents, owned); browser_view_->WebContentsCreated(web_contents); } diff --git a/libcef/browser/views/browser_platform_delegate_views.h b/libcef/browser/views/browser_platform_delegate_views.h index d10619488..ce23f4c18 100644 --- a/libcef/browser/views/browser_platform_delegate_views.h +++ b/libcef/browser/views/browser_platform_delegate_views.h @@ -21,7 +21,8 @@ class CefBrowserPlatformDelegateViews CefRefPtr browser_view); // CefBrowserPlatformDelegate methods: - void WebContentsCreated(content::WebContents* web_contents) override; + void WebContentsCreated(content::WebContents* web_contents, + bool owned) override; void BrowserCreated(CefBrowserHostImpl* browser) override; void NotifyBrowserCreated() override; void NotifyBrowserDestroyed() override;