Move browser runtime-specific logic to CefBrowserPlatformDelegate (see issue #2969)

This change moves the runtime-specific implementations of CefBrowserHostImpl
methods to CefBrowserPlatformDelegate. Some WebContentsDelegate methods
implemented by CefBrowserHostImpl set state or trigger client callbacks.
Those implementations will likely stay with CefBrowserHostImpl and will
need to be called from the Browser equivalents when using the Chrome runtime.
This commit is contained in:
Marshall Greenblatt 2020-07-03 16:13:27 -04:00
parent 6152d68b6a
commit 6cb9f0c695
13 changed files with 636 additions and 488 deletions

View File

@ -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,77 +348,35 @@ CefRefPtr<CefBrowserHostImpl> CefBrowserHostImpl::Create(
is_devtools_popup, platform_delegate->IsWindowless(),
create_params.extra_info);
// Get or create the request context and browser context.
CefRefPtr<CefRequestContextImpl> 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<CefRequestContextImpl*>(create_params.request_context.get());
CefRefPtr<CefExtension> cef_extension;
scoped_refptr<content::SiteInstance> 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) {
auto cef_browser_context = request_context_impl->GetBrowserContext();
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;
CHECK(cef_extension);
}
// 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 (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<content::WebContents> web_contents =
content::WebContents::Create(wc_create_params);
DCHECK(web_contents);
auto platform_delegate_ptr = platform_delegate.get();
CefRefPtr<CefBrowserHostImpl> browser = CreateInternal(
create_params.settings, create_params.client, web_contents.release(),
true, info, create_params.devtools_opener, is_devtools_popup,
static_cast<CefRequestContextImpl*>(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,
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(),
@ -464,6 +411,8 @@ CefRefPtr<CefBrowserHostImpl> 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> 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<CefBrowserHostImpl> 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<CefPdfPrintCallback> 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<CefNavigationEntry> 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<content::WebContentsImpl*>(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<CefExtension> CefBrowserHostImpl::GetExtension() {
@ -1178,9 +1069,7 @@ void CefBrowserHostImpl::WasResized() {
return;
}
if (!web_contents() || !platform_delegate_)
return;
if (platform_delegate_)
platform_delegate_->WasResized();
}
@ -1196,9 +1085,7 @@ void CefBrowserHostImpl::WasHidden(bool hidden) {
return;
}
if (!web_contents() || !platform_delegate_)
return;
if (platform_delegate_)
platform_delegate_->WasHidden(hidden);
}
@ -1215,9 +1102,7 @@ void CefBrowserHostImpl::NotifyScreenInfoChanged() {
return;
}
if (!web_contents() || !platform_delegate_)
return;
if (platform_delegate_)
platform_delegate_->NotifyScreenInfoChanged();
}
@ -1233,9 +1118,7 @@ void CefBrowserHostImpl::Invalidate(PaintElementType type) {
return;
}
if (!web_contents() || !platform_delegate_)
return;
if (platform_delegate_)
platform_delegate_->Invalidate(type);
}
@ -1251,9 +1134,7 @@ void CefBrowserHostImpl::SendExternalBeginFrame() {
return;
}
if (!web_contents() || !platform_delegate_)
return;
if (platform_delegate_)
platform_delegate_->SendExternalBeginFrame();
}
@ -1264,9 +1145,7 @@ void CefBrowserHostImpl::SendKeyEvent(const CefKeyEvent& event) {
return;
}
if (!web_contents() || !platform_delegate_)
return;
if (platform_delegate_)
platform_delegate_->SendKeyEvent(event);
}
@ -1281,11 +1160,10 @@ void CefBrowserHostImpl::SendMouseClickEvent(const CefMouseEvent& event,
return;
}
if (!web_contents() || !platform_delegate_)
return;
if (platform_delegate_) {
platform_delegate_->SendMouseClickEvent(event, type, mouseUp, clickCount);
}
}
void CefBrowserHostImpl::SendMouseMoveEvent(const CefMouseEvent& event,
bool mouseLeave) {
@ -1296,11 +1174,10 @@ void CefBrowserHostImpl::SendMouseMoveEvent(const CefMouseEvent& event,
return;
}
if (!web_contents() || !platform_delegate_)
return;
if (platform_delegate_) {
platform_delegate_->SendMouseMoveEvent(event, mouseLeave);
}
}
void CefBrowserHostImpl::SendMouseWheelEvent(const CefMouseEvent& event,
int deltaX,
@ -1317,11 +1194,26 @@ void CefBrowserHostImpl::SendMouseWheelEvent(const CefMouseEvent& event,
return;
}
if (!web_contents() || !platform_delegate_)
return;
if (platform_delegate_) {
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) {
SetFocus(setFocus);
@ -1335,9 +1227,7 @@ void CefBrowserHostImpl::SendCaptureLostEvent() {
return;
}
if (!web_contents() || !platform_delegate_)
return;
if (platform_delegate_)
platform_delegate_->SendCaptureLostEvent();
}
@ -1350,9 +1240,7 @@ void CefBrowserHostImpl::NotifyMoveOrResizeStarted() {
return;
}
if (!web_contents() || !platform_delegate_)
return;
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,12 +1760,11 @@ void CefBrowserHostImpl::ImeSetComposition(
return;
}
if (!web_contents() || !platform_delegate_)
return;
if (platform_delegate_) {
platform_delegate_->ImeSetComposition(text, underlines, replacement_range,
selection_range);
}
}
void CefBrowserHostImpl::ImeCommitText(const CefString& text,
const CefRange& replacement_range,
@ -1907,12 +1781,11 @@ void CefBrowserHostImpl::ImeCommitText(const CefString& text,
return;
}
if (!web_contents() || !platform_delegate_)
return;
if (platform_delegate_) {
platform_delegate_->ImeCommitText(text, replacement_range,
relative_cursor_pos);
}
}
void CefBrowserHostImpl::ImeFinishComposingText(bool keep_selection) {
if (!IsWindowless()) {
@ -1927,11 +1800,10 @@ void CefBrowserHostImpl::ImeFinishComposingText(bool keep_selection) {
return;
}
if (!web_contents() || !platform_delegate_)
return;
if (platform_delegate_) {
platform_delegate_->ImeFinishComposingText(keep_selection);
}
}
void CefBrowserHostImpl::ImeCancelComposition() {
if (!IsWindowless()) {
@ -1946,9 +1818,7 @@ void CefBrowserHostImpl::ImeCancelComposition() {
return;
}
if (!web_contents() || !platform_delegate_)
return;
if (platform_delegate_)
platform_delegate_->ImeCancelComposition();
}
@ -1973,11 +1843,10 @@ void CefBrowserHostImpl::DragTargetDragEnter(
return;
}
if (!web_contents() || !platform_delegate_)
return;
if (platform_delegate_) {
platform_delegate_->DragTargetDragEnter(drag_data, event, allowed_ops);
}
}
void CefBrowserHostImpl::DragTargetDragOver(
const CefMouseEvent& event,
@ -1994,11 +1863,10 @@ void CefBrowserHostImpl::DragTargetDragOver(
return;
}
if (!web_contents() || !platform_delegate_)
return;
if (platform_delegate_) {
platform_delegate_->DragTargetDragOver(event, allowed_ops);
}
}
void CefBrowserHostImpl::DragTargetDragLeave() {
if (!IsWindowless()) {
@ -2012,9 +1880,7 @@ void CefBrowserHostImpl::DragTargetDragLeave() {
return;
}
if (!web_contents() || !platform_delegate_)
return;
if (platform_delegate_)
platform_delegate_->DragTargetDragLeave();
}
@ -2030,9 +1896,7 @@ void CefBrowserHostImpl::DragTargetDrop(const CefMouseEvent& event) {
return;
}
if (!web_contents() || !platform_delegate_)
return;
if (platform_delegate_)
platform_delegate_->DragTargetDrop(event);
}
@ -2049,9 +1913,7 @@ void CefBrowserHostImpl::DragSourceSystemDragEnded() {
return;
}
if (!web_contents() || !platform_delegate_)
return;
if (platform_delegate_)
platform_delegate_->DragSourceSystemDragEnded();
}
@ -2071,9 +1933,7 @@ void CefBrowserHostImpl::DragSourceEndedAt(
return;
}
if (!web_contents() || !platform_delegate_)
return;
if (platform_delegate_)
platform_delegate_->DragSourceEndedAt(x, y, op);
}
@ -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<CefBrowserHostImpl> 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<CefBrowserInfo> 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<CefBrowserHostImpl> opener = GetBrowserForContents(source_contents);
if (!opener.get())
if (!opener)
return;
// Popups must share the same RequestContext as the parent.
CefRefPtr<CefRequestContextImpl> 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<CefBrowserHostImpl> 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<CefRequestHandler> 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<content::NavigationController>(
&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);
}

View File

@ -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<content::AXLocationChangeNotificationDetails>& locData)
override;
void OnWebContentsFocused(
content::RenderWidgetHost* render_widget_host) override;
@ -533,6 +522,8 @@ class CefBrowserHostImpl : public CefBrowserHost,
std::unique_ptr<NavigationLock> CreateNavigationLock();
private:
friend class CefBrowserPlatformDelegate;
static CefRefPtr<CefBrowserHostImpl> CreateInternal(
const CefBrowserSettings& settings,
CefRefPtr<CefClient> client,
@ -560,20 +551,9 @@ class CefBrowserHostImpl : public CefBrowserHost,
std::unique_ptr<CefBrowserPlatformDelegate> platform_delegate,
CefRefPtr<CefExtension> 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<content::WebContents> owned_web_contents_;
CefRefPtr<CefExtension> 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<Observer>::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<CefExtension> extension_;
bool is_background_host_ = false;
// Used for capturing audio for CefAudioHandler.
std::unique_ptr<CefAudioCapturer> 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);
};

View File

@ -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<CefRequestContextImpl> request_context_impl =
CefRequestContextImpl::GetOrCreateForRequestContext(
create_params.request_context);
CHECK(request_context_impl);
auto cef_browser_context = request_context_impl->GetBrowserContext();
CHECK(cef_browser_context);
auto browser_context = cef_browser_context->AsBrowserContext();
if (!create_params.request_context) {
// Using the global request context.
create_params.request_context = request_context_impl.get();
}
scoped_refptr<content::SiteInstance> 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<content::WebContents> new_contents,
const GURL& target_url,
WindowOpenDisposition disposition,
const gfx::Rect& initial_rect,
bool user_gesture,
bool* was_blocked) {
REQUIRE_ALLOY_RUNTIME();
CefRefPtr<CefBrowserHostImpl> 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<CefFileDialogRunner>
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<content::WebContentsImpl*>(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<CefPdfPrintCallback> 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;
}

View File

@ -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<CefBrowserPlatformDelegate> 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<content::WebContents> 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<CefPdfPrintCallback> 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<CefBrowserPlatformDelegate>;
@ -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<content::WebContents> owned_web_contents_;
// Used for the print preview dialog.
std::unique_ptr<CefWebContentsDialogHelper> 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<CefBrowserPlatformDelegate> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(CefBrowserPlatformDelegate);
};

View File

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

View File

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

View File

@ -21,16 +21,14 @@ using content::WebContentsObserver;
namespace extensions {
CefExtensionViewHost::CefExtensionViewHost(
CefBrowserHostImpl* browser,
CefExtensionViewHost::CefExtensionViewHost(CefBrowserHostImpl* browser,
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) {

View File

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

View File

@ -272,7 +272,7 @@ bool CefExtensionsBrowserClient::CreateBackgroundExtensionHost(
CefRefPtr<CefBrowserHostImpl> browser =
CefBrowserHostImpl::Create(create_params);
if (browser) {
*host = browser->extension_host();
*host = browser->GetExtensionHost();
DCHECK(*host);
}
return true;

View File

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

View File

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

View File

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

View File

@ -21,7 +21,8 @@ class CefBrowserPlatformDelegateViews
CefRefPtr<CefBrowserViewImpl> 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;