chrome: Add support for Alloy style browsers and windows (see #3681)

Split the Alloy runtime into bootstrap and style components. Support
creation of Alloy style browsers and windows with the Chrome runtime.
Chrome runtime (`--enable-chrome-runtime`) + Alloy style
(`--use-alloy-style`) supports Views (`--use-views`), native parent
(`--use-native`) and windowless rendering
(`--off-screen-rendering-enabled`).

Print preview is supported in all cases except with windowless rendering
on all platforms and native parent on MacOS. It is disabled by default
with Alloy style for legacy compatibility. Where supported it can be
enabled or disabled globally using `--[enable|disable]-print-preview` or
configured on a per-RequestContext basis using the
`printing.print_preview_disabled` preference. It also behaves as
expected when triggered via the PDF viewer print button.

Chrome runtime + Alloy style behavior differs from Alloy runtime in the
following significant ways:

- Supports Chrome error pages by default.
- DevTools popups are Chrome style only (cannot be windowless).
- The Alloy extension API will not supported.

Chrome runtime + Alloy style passes all expected Alloy ceftests except
the following:

- `DisplayTest.AutoResize` (Alloy extension API not supported)
- `DownloadTest.*` (Download API not yet supported)
- `ExtensionTest.*` (Alloy extension API not supported)

This change also adds Chrome runtime support for
CefContextMenuHandler::RunContextMenu (see #3293).

This change also explicitly blocks (and doesn't retry) FrameAttached
requests from PDF viewer and print preview excluded frames (see #3664).

Known issues specific to Chrome runtime + Alloy style:
- DevTools popup with windowless rendering doesn't load successfully.
  Use windowed rendering or remote debugging as a workaround.
- Chrome style Window with Alloy style BrowserView (`--use-alloy-style
  --use-chrome-style-window`) does not show Chrome theme changes.

To test:
- Run `ceftests --enable-chrome-runtime --use-alloy-style
       [--use-chrome-style-window] [--use-views|--use-native]
       --gtest_filter=...`
- Run `cefclient --enable-chrome-runtime --use-alloy-style
       [--use-chrome-style-window]
       [--use-views|--use-native|--off-screen-rendering-enabled]`
- Run `cefsimple --enable-chrome-runtime --use-alloy-style [--use-views]`
This commit is contained in:
Marshall Greenblatt 2024-04-17 12:01:26 -04:00
parent 62c93f01f4
commit dca0435d2f
216 changed files with 3388 additions and 1565 deletions

View File

@ -471,6 +471,14 @@ source_set("libcef_static") {
"libcef/browser/alloy/alloy_web_contents_view_delegate.h",
"libcef/browser/alloy/browser_platform_delegate_alloy.cc",
"libcef/browser/alloy/browser_platform_delegate_alloy.h",
"libcef/browser/alloy/devtools/alloy_devtools_window_runner.cc",
"libcef/browser/alloy/devtools/alloy_devtools_window_runner.h",
"libcef/browser/alloy/devtools/devtools_file_manager.cc",
"libcef/browser/alloy/devtools/devtools_file_manager.h",
"libcef/browser/alloy/devtools/devtools_frontend.cc",
"libcef/browser/alloy/devtools/devtools_frontend.h",
"libcef/browser/alloy/devtools/devtools_manager_delegate.cc",
"libcef/browser/alloy/devtools/devtools_manager_delegate.h",
"libcef/browser/alloy/dialogs/alloy_constrained_window_views_client.cc",
"libcef/browser/alloy/dialogs/alloy_constrained_window_views_client.h",
"libcef/browser/alloy/dialogs/alloy_javascript_dialog_manager_delegate.cc",
@ -528,8 +536,11 @@ source_set("libcef_static") {
"libcef/browser/chrome/chrome_content_browser_client_cef.h",
"libcef/browser/chrome/chrome_context_menu_handler.cc",
"libcef/browser/chrome/chrome_context_menu_handler.h",
"libcef/browser/chrome/chrome_devtools_window_runner.cc",
"libcef/browser/chrome/chrome_devtools_window_runner.h",
"libcef/browser/chrome/chrome_startup_browser_creator.cc",
"libcef/browser/chrome/chrome_startup_browser_creator.h",
"libcef/browser/chrome/chrome_web_contents_view_delegate_cef.h",
"libcef/browser/chrome_crash_reporter_client_stub.cc",
"libcef/browser/chrome/extensions/chrome_mime_handler_view_guest_delegate_cef.cc",
"libcef/browser/chrome/extensions/chrome_mime_handler_view_guest_delegate_cef.h",
@ -555,14 +566,10 @@ source_set("libcef_static") {
"libcef/browser/context_menu_params_impl.h",
"libcef/browser/devtools/devtools_controller.cc",
"libcef/browser/devtools/devtools_controller.h",
"libcef/browser/devtools/devtools_file_manager.cc",
"libcef/browser/devtools/devtools_file_manager.h",
"libcef/browser/devtools/devtools_frontend.cc",
"libcef/browser/devtools/devtools_frontend.h",
"libcef/browser/devtools/devtools_manager.cc",
"libcef/browser/devtools/devtools_manager.h",
"libcef/browser/devtools/devtools_manager_delegate.cc",
"libcef/browser/devtools/devtools_manager_delegate.h",
"libcef/browser/devtools/devtools_protocol_manager.cc",
"libcef/browser/devtools/devtools_protocol_manager.h",
"libcef/browser/devtools/devtools_window_runner.h",
"libcef/browser/devtools/devtools_window_runner_create.cc",
"libcef/browser/download_item_impl.cc",
"libcef/browser/download_item_impl.h",
"libcef/browser/download_manager_delegate.cc",
@ -939,8 +946,6 @@ source_set("libcef_static") {
"libcef/renderer/extensions/extensions_renderer_api_provider.h",
"libcef/renderer/extensions/extensions_renderer_client.cc",
"libcef/renderer/extensions/extensions_renderer_client.h",
"libcef/renderer/extensions/print_render_frame_helper_delegate.cc",
"libcef/renderer/extensions/print_render_frame_helper_delegate.h",
"libcef/renderer/frame_impl.cc",
"libcef/renderer/frame_impl.h",
"libcef/renderer/render_frame_observer.cc",
@ -1151,6 +1156,8 @@ source_set("libcef_static") {
if (is_mac) {
sources += includes_mac + [
"libcef/browser/chrome/chrome_content_browser_client_cef_mac.mm",
"libcef/browser/chrome/chrome_web_contents_view_delegate_cef_mac.mm",
"libcef/browser/native/browser_platform_delegate_native_mac.h",
"libcef/browser/native/browser_platform_delegate_native_mac.mm",
"libcef/browser/native/cursor_util_mac.mm",
@ -1172,6 +1179,10 @@ source_set("libcef_static") {
"//chrome/app/chrome_main_mac.h",
"//chrome/app/chrome_main_mac.mm",
]
} else {
sources += [
"libcef/browser/chrome/chrome_web_contents_view_delegate_cef.cc",
]
}
if (ozone_platform_x11) {

View File

@ -56,6 +56,7 @@
'include/internal/cef_types.h',
'include/internal/cef_types_content_settings.h',
'include/internal/cef_types_geometry.h',
'include/internal/cef_types_runtime.h',
],
'includes_capi': [
'include/capi/cef_base_capi.h',

View File

@ -33,7 +33,7 @@
// by hand. See the translator.README.txt file in the tools directory for
// more information.
//
// $hash=abcb584dbf5965834f415a0f2daeda3e361696b2$
// $hash=7733ed87ade32dfd311c24c51263d20b9b469868$
//
#ifndef CEF_INCLUDE_CAPI_CEF_BROWSER_CAPI_H_
@ -985,6 +985,13 @@ typedef struct _cef_browser_host_t {
///
int(CEF_CALLBACK* is_render_process_unresponsive)(
struct _cef_browser_host_t* self);
///
/// Returns the runtime style for this browser (ALLOY or CHROME). See
/// cef_runtime_style_t documentation for details.
///
cef_runtime_style_t(CEF_CALLBACK* get_runtime_style)(
struct _cef_browser_host_t* self);
} cef_browser_host_t;
///

View File

@ -33,7 +33,7 @@
// by hand. See the translator.README.txt file in the tools directory for
// more information.
//
// $hash=2e5a3b3b1f427a7eb1e6a447fe0d31c5ace49469$
// $hash=1c2fbbffaf51e90a2d55bfa7eb3fa3a4e315f4ac$
//
#ifndef CEF_INCLUDE_CAPI_VIEWS_CEF_BROWSER_VIEW_CAPI_H_
@ -93,6 +93,13 @@ typedef struct _cef_browser_view_t {
///
void(CEF_CALLBACK* set_prefer_accelerators)(struct _cef_browser_view_t* self,
int prefer_accelerators);
///
/// Returns the runtime style for this BrowserView (ALLOY or CHROME). See
/// cef_runtime_style_t documentation for details.
///
cef_runtime_style_t(CEF_CALLBACK* get_runtime_style)(
struct _cef_browser_view_t* self);
} cef_browser_view_t;
///

View File

@ -33,7 +33,7 @@
// by hand. See the translator.README.txt file in the tools directory for
// more information.
//
// $hash=1f2a6e206b86945386bef57167b80e2fb6067c59$
// $hash=a0a9f2bfcdf8e05d3d1114fcd8860caaa726ec98$
//
#ifndef CEF_INCLUDE_CAPI_VIEWS_CEF_BROWSER_VIEW_DELEGATE_CAPI_H_
@ -141,6 +141,13 @@ typedef struct _cef_browser_view_delegate_t {
struct _cef_browser_view_delegate_t* self,
struct _cef_browser_view_t* browser_view,
cef_gesture_command_t gesture_command);
///
/// Optionally change the runtime style for this BrowserView. See
/// cef_runtime_style_t documentation for details.
///
cef_runtime_style_t(CEF_CALLBACK* get_browser_runtime_style)(
struct _cef_browser_view_delegate_t* self);
} cef_browser_view_delegate_t;
#ifdef __cplusplus

View File

@ -33,7 +33,7 @@
// by hand. See the translator.README.txt file in the tools directory for
// more information.
//
// $hash=2abb3759a22a95ffc0207f0538c645a74a5030c6$
// $hash=dd32b58ec9aca0e04a1d30ccf94a741995fcc094$
//
#ifndef CEF_INCLUDE_CAPI_VIEWS_CEF_WINDOW_CAPI_H_
@ -401,6 +401,13 @@ typedef struct _cef_window_t {
/// or cef_view_delegate_t::OnThemeChanged.
///
void(CEF_CALLBACK* theme_changed)(struct _cef_window_t* self);
///
/// Returns the runtime style for this Window (ALLOY or CHROME). See
/// cef_runtime_style_t documentation for details.
///
cef_runtime_style_t(CEF_CALLBACK* get_runtime_style)(
struct _cef_window_t* self);
} cef_window_t;
///

View File

@ -33,7 +33,7 @@
// by hand. See the translator.README.txt file in the tools directory for
// more information.
//
// $hash=e6bbc33db1b5ed3832982f8799e14557204f4028$
// $hash=e8c9e32caa8d317a7cb6ff2f0ad6be49cf1b7ad1$
//
#ifndef CEF_INCLUDE_CAPI_VIEWS_CEF_WINDOW_DELEGATE_CAPI_H_
@ -275,6 +275,13 @@ typedef struct _cef_window_delegate_t {
struct _cef_window_delegate_t* self,
struct _cef_window_t* window,
int chrome_theme);
///
/// Optionally change the runtime style for this Window. See
/// cef_runtime_style_t documentation for details.
///
cef_runtime_style_t(CEF_CALLBACK* get_window_runtime_style)(
struct _cef_window_delegate_t* self);
} cef_window_delegate_t;
#ifdef __cplusplus

View File

@ -42,13 +42,13 @@
// way that may cause binary incompatibility with other builds. The universal
// hash value will change if any platform is affected whereas the platform hash
// values will change only if that particular platform is affected.
#define CEF_API_HASH_UNIVERSAL "de72aee0623e568ded52b7075c7fda576844e8b3"
#define CEF_API_HASH_UNIVERSAL "faa2d7c5a95e129e5a746785cbbcb5f5f99cfe53"
#if defined(OS_WIN)
#define CEF_API_HASH_PLATFORM "46bb69fe7038d7e9f8d4ee86e4a0825bb2d289b7"
#define CEF_API_HASH_PLATFORM "9123354f4395b59f275ee3389f21734aeeac7a5e"
#elif defined(OS_MAC)
#define CEF_API_HASH_PLATFORM "e3ef47d5541f5260eba70030386d692138315900"
#define CEF_API_HASH_PLATFORM "5ae2b1b7fbe4bdbd25dc6f707f6e3bfc163120ad"
#elif defined(OS_LINUX)
#define CEF_API_HASH_PLATFORM "579ef9c5282456c7de906cf055aed0ff4ba0a5a3"
#define CEF_API_HASH_PLATFORM "41ddfb7023cda15e5b813b237b06111b6d4cabb8"
#endif
#ifdef __cplusplus

View File

@ -1018,6 +1018,13 @@ class CefBrowserHost : public virtual CefBaseRefCounted {
///
/*--cef()--*/
virtual bool IsRenderProcessUnresponsive() = 0;
///
/// Returns the runtime style for this browser (ALLOY or CHROME). See
/// cef_runtime_style_t documentation for details.
///
/*--cef(default_retval=CEF_RUNTIME_STYLE_DEFAULT)--*/
virtual cef_runtime_style_t GetRuntimeStyle() = 0;
};
#endif // CEF_INCLUDE_CEF_BROWSER_H_

View File

@ -70,6 +70,7 @@ struct CefWindowInfoTraits {
target->shared_texture_enabled = src->shared_texture_enabled;
target->external_begin_frame_enabled = src->external_begin_frame_enabled;
target->window = src->window;
target->runtime_style = src->runtime_style;
}
};
@ -110,6 +111,7 @@ class CefWindowInfo : public CefStructBase<CefWindowInfoTraits> {
void SetAsWindowless(CefWindowHandle parent) {
windowless_rendering_enabled = true;
parent_window = parent;
runtime_style = CEF_RUNTIME_STYLE_ALLOY;
}
};

View File

@ -71,6 +71,7 @@ struct CefWindowInfoTraits {
target->shared_texture_enabled = src->shared_texture_enabled;
target->external_begin_frame_enabled = src->external_begin_frame_enabled;
target->view = src->view;
target->runtime_style = src->runtime_style;
}
};
@ -112,6 +113,7 @@ class CefWindowInfo : public CefStructBase<CefWindowInfoTraits> {
void SetAsWindowless(CefWindowHandle parent) {
windowless_rendering_enabled = true;
parent_view = parent;
runtime_style = CEF_RUNTIME_STYLE_ALLOY;
}
};

View File

@ -44,6 +44,7 @@ typedef struct _XDisplay XDisplay;
#include "include/internal/cef_export.h"
#include "include/internal/cef_string.h"
#include "include/internal/cef_types_geometry.h"
#include "include/internal/cef_types_runtime.h"
// Handle types.
#if defined(CEF_X11)
@ -135,6 +136,13 @@ typedef struct _cef_window_info_t {
/// Pointer for the new browser window. Only used with windowed rendering.
///
cef_window_handle_t window;
///
/// Optionally change the runtime style. Alloy style will always be used if
/// |windowless_rendering_enabled| is true. See cef_runtime_style_t
/// documentation for details.
///
cef_runtime_style_t runtime_style;
} cef_window_info_t;
#ifdef __cplusplus

View File

@ -36,6 +36,7 @@
#if defined(OS_MAC)
#include "include/internal/cef_string.h"
#include "include/internal/cef_types_geometry.h"
#include "include/internal/cef_types_runtime.h"
// Handle types.
// Actually NSCursor*
@ -134,6 +135,13 @@ typedef struct _cef_window_info_t {
/// rendering.
///
cef_window_handle_t view;
///
/// Optionally change the runtime style. Alloy style will always be used if
/// |windowless_rendering_enabled| is true or if |parent_view| is provided.
/// See cef_runtime_style_t documentation for details.
///
cef_runtime_style_t runtime_style;
} cef_window_info_t;
#ifdef __cplusplus

View File

@ -0,0 +1,88 @@
// Copyright (c) 2024 Marshall A. Greenblatt. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the name Chromium Embedded
// Framework nor the names of its contributors may be used to endorse
// or promote products derived from this software without specific prior
// written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef CEF_INCLUDE_INTERNAL_CEF_TYPES_RUNTIME_H_
#define CEF_INCLUDE_INTERNAL_CEF_TYPES_RUNTIME_H_
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
///
/// CEF supports both a Chrome runtime (based on the Chrome UI layer) and an
/// Alloy runtime (based on the Chromium content layer). The Chrome runtime
/// provides the full Chrome UI and browser functionality whereas the Alloy
/// runtime provides less default browser functionality but adds additional
/// client callbacks and support for windowless (off-screen) rendering. For
/// additional comparative details on runtime types see
/// https://bitbucket.org/chromiumembedded/cef/wiki/Architecture.md#markdown-header-cef3
///
/// Each runtime is composed of a bootstrap component and a style component. The
/// bootstrap component is configured via CefSettings.chrome_runtime and cannot
/// be changed after CefInitialize. The style component is individually
/// configured for each window/browser at creation time and, in combination with
/// the Chrome bootstrap, different styles can be mixed during runtime.
///
/// Windowless rendering will always use Alloy style. Windowed rendering with a
/// default window or client-provided parent window can configure the style via
/// CefWindowInfo.runtime_style. Windowed rendering with the Views framework can
/// configure the style via CefWindowDelegate::GetWindowRuntimeStyle and
/// CefBrowserViewDelegate::GetBrowserRuntimeStyle. Alloy style Windows with the
/// Views framework can host only Alloy style BrowserViews but Chrome style
/// Windows can host both style BrowserViews. Additionally, a Chrome style
/// Window can host at most one Chrome style BrowserView but potentially
/// multiple Alloy style BrowserViews. See CefWindowInfo.runtime_style
/// documentation for any additional platform-specific limitations.
///
typedef enum {
///
/// Use the default runtime style. The default style will match the
/// CefSettings.chrome_runtime value in most cases. See above documentation
/// for exceptions.
///
CEF_RUNTIME_STYLE_DEFAULT,
///
/// Use the Chrome runtime style. Only supported with the Chrome runtime.
///
CEF_RUNTIME_STYLE_CHROME,
///
/// Use the Alloy runtime style. Supported with both the Alloy and Chrome
/// runtime.
///
CEF_RUNTIME_STYLE_ALLOY,
} cef_runtime_style_t;
#ifdef __cplusplus
}
#endif
#endif // CEF_INCLUDE_INTERNAL_CEF_TYPES_RUNTIME_H_

View File

@ -38,6 +38,7 @@
#include "include/internal/cef_string.h"
#include "include/internal/cef_types_geometry.h"
#include "include/internal/cef_types_runtime.h"
// Handle types.
#define cef_cursor_handle_t HCURSOR
@ -102,6 +103,13 @@ typedef struct _cef_window_info_t {
/// Handle for the new browser window. Only used with windowed rendering.
///
cef_window_handle_t window;
///
/// Optionally change the runtime style. Alloy style will always be used if
/// |windowless_rendering_enabled| is true. See cef_runtime_style_t
/// documentation for details.
///
cef_runtime_style_t runtime_style;
} cef_window_info_t;
#ifdef __cplusplus

View File

@ -73,6 +73,7 @@ struct CefWindowInfoTraits {
target->shared_texture_enabled = src->shared_texture_enabled;
target->external_begin_frame_enabled = src->external_begin_frame_enabled;
target->window = src->window;
target->runtime_style = src->runtime_style;
}
};
@ -130,6 +131,7 @@ class CefWindowInfo : public CefStructBase<CefWindowInfoTraits> {
void SetAsWindowless(CefWindowHandle parent) {
windowless_rendering_enabled = TRUE;
parent_window = parent;
runtime_style = CEF_RUNTIME_STYLE_ALLOY;
}
};

View File

@ -107,6 +107,13 @@ class CefBrowserView : public CefView {
///
/*--cef()--*/
virtual void SetPreferAccelerators(bool prefer_accelerators) = 0;
///
/// Returns the runtime style for this BrowserView (ALLOY or CHROME). See
/// cef_runtime_style_t documentation for details.
///
/*--cef(default_retval=CEF_RUNTIME_STYLE_DEFAULT)--*/
virtual cef_runtime_style_t GetRuntimeStyle() = 0;
};
#endif // CEF_INCLUDE_VIEWS_CEF_BROWSER_VIEW_H_

View File

@ -140,6 +140,15 @@ class CefBrowserViewDelegate : public CefViewDelegate {
cef_gesture_command_t gesture_command) {
return false;
}
///
/// Optionally change the runtime style for this BrowserView. See
/// cef_runtime_style_t documentation for details.
///
/*--cef(default_retval=CEF_RUNTIME_STYLE_DEFAULT)--*/
virtual cef_runtime_style_t GetBrowserRuntimeStyle() {
return CEF_RUNTIME_STYLE_DEFAULT;
}
};
#endif // CEF_INCLUDE_VIEWS_CEF_BROWSER_VIEW_DELEGATE_H_

View File

@ -414,6 +414,13 @@ class CefWindow : public CefPanel {
///
/*--cef()--*/
virtual void ThemeChanged() = 0;
///
/// Returns the runtime style for this Window (ALLOY or CHROME). See
/// cef_runtime_style_t documentation for details.
///
/*--cef(default_retval=CEF_RUNTIME_STYLE_DEFAULT)--*/
virtual cef_runtime_style_t GetRuntimeStyle() = 0;
};
#endif // CEF_INCLUDE_VIEWS_CEF_WINDOW_H_

View File

@ -271,6 +271,15 @@ class CefWindowDelegate : public CefPanelDelegate {
/*--cef()--*/
virtual void OnThemeColorsChanged(CefRefPtr<CefWindow> window,
bool chrome_theme) {}
///
/// Optionally change the runtime style for this Window. See
/// cef_runtime_style_t documentation for details.
///
/*--cef(default_retval=CEF_RUNTIME_STYLE_DEFAULT)--*/
virtual cef_runtime_style_t GetWindowRuntimeStyle() {
return CEF_RUNTIME_STYLE_DEFAULT;
}
};
#endif // CEF_INCLUDE_VIEWS_CEF_WINDOW_DELEGATE_H_

View File

@ -297,15 +297,6 @@ bool AlloyBrowserContext::UnloadExtension(const CefString& extension_id) {
return extension_system()->UnloadExtension(extension_id);
}
bool AlloyBrowserContext::IsPrintPreviewSupported() const {
CEF_REQUIRE_UIT();
if (!extensions::PrintPreviewEnabled()) {
return false;
}
return !GetPrefs()->GetBoolean(prefs::kPrintPreviewDisabled);
}
content::ClientHintsControllerDelegate*
AlloyBrowserContext::GetClientHintsControllerDelegate() {
return nullptr;
@ -469,6 +460,13 @@ DownloadPrefs* AlloyBrowserContext::GetDownloadPrefs() {
return download_prefs_.get();
}
void AlloyBrowserContext::AddVisitedURLs(const std::vector<GURL>& urls) {
visitedlink_master_->AddURLs(urls);
void AlloyBrowserContext::AddVisitedURLs(
const GURL& url,
const std::vector<GURL>& redirect_chain,
ui::PageTransition /*transition*/) {
if (!redirect_chain.empty()) {
visitedlink_master_->AddURLs(redirect_chain);
} else {
visitedlink_master_->AddURL(url);
}
}

View File

@ -56,7 +56,9 @@ class AlloyBrowserContext : public ChromeProfileAlloy,
bool GetExtensions(std::vector<CefString>& extension_ids) override;
CefRefPtr<CefExtension> GetExtension(const CefString& extension_id) override;
bool UnloadExtension(const CefString& extension_id) override;
bool IsPrintPreviewSupported() const override;
void AddVisitedURLs(const GURL& url,
const std::vector<GURL>& redirect_chain,
ui::PageTransition transition) override;
// content::BrowserContext overrides.
content::ClientHintsControllerDelegate* GetClientHintsControllerDelegate()
@ -114,11 +116,8 @@ class AlloyBrowserContext : public ChromeProfileAlloy,
return extension_system_;
}
// Called from AlloyBrowserHostImpl::DidFinishNavigation to update the table
// of visited links.
void AddVisitedURLs(const std::vector<GURL>& urls);
// Called from DownloadPrefs::FromBrowserContext.
// Called from DownloadPrefs::FromBrowserContext via
// alloy::GetDownloadPrefsFromBrowserContext.
DownloadPrefs* GetDownloadPrefs();
private:

View File

@ -9,7 +9,6 @@
#include <string>
#include <utility>
#include "libcef/browser/alloy/alloy_browser_context.h"
#include "libcef/browser/alloy/browser_platform_delegate_alloy.h"
#include "libcef/browser/audio_capturer.h"
#include "libcef/browser/browser_context.h"
@ -17,7 +16,6 @@
#include "libcef/browser/browser_info_manager.h"
#include "libcef/browser/browser_platform_delegate.h"
#include "libcef/browser/context.h"
#include "libcef/browser/devtools/devtools_manager.h"
#include "libcef/browser/hang_monitor.h"
#include "libcef/browser/media_access_query.h"
#include "libcef/browser/osr/osr_util.h"
@ -29,7 +27,7 @@
#include "libcef/common/net/url_util.h"
#include "libcef/common/request_impl.h"
#include "libcef/common/values_impl.h"
#include "libcef/features/runtime_checks.h"
#include "libcef/features/runtime.h"
#include "base/command_line.h"
#include "base/functional/bind.h"
@ -73,11 +71,15 @@ CefRefPtr<AlloyBrowserHostImpl> AlloyBrowserHostImpl::Create(
CefBrowserPlatformDelegate::Create(create_params);
CHECK(platform_delegate);
// Expect runtime style to match.
CHECK(platform_delegate->IsAlloyStyle());
const bool is_devtools_popup = !!create_params.devtools_opener;
scoped_refptr<CefBrowserInfo> info =
CefBrowserInfoManager::GetInstance()->CreateBrowserInfo(
is_devtools_popup, platform_delegate->IsWindowless(),
platform_delegate->IsPrintPreviewSupported(),
create_params.extra_info);
bool own_web_contents = false;
@ -101,8 +103,7 @@ CefRefPtr<AlloyBrowserHostImpl> AlloyBrowserHostImpl::Create(
CefRefPtr<AlloyBrowserHostImpl> browser = CreateInternal(
create_params.settings, create_params.client, web_contents,
own_web_contents, info,
static_cast<AlloyBrowserHostImpl*>(create_params.devtools_opener.get()),
own_web_contents, info, FromBaseChecked(create_params.devtools_opener),
is_devtools_popup, request_context_impl, std::move(platform_delegate),
cef_extension);
if (!browser) {
@ -181,8 +182,8 @@ CefRefPtr<AlloyBrowserHostImpl> AlloyBrowserHostImpl::CreateInternal(
// 1. Notify the opener browser's platform delegate. With Views this will
// result in a call to CefBrowserViewDelegate::OnPopupBrowserViewCreated().
// Do this first for consistency with the Chrome runtime.
opener->platform_delegate_->PopupBrowserCreated(browser.get(),
is_devtools_popup);
opener->platform_delegate_->PopupBrowserCreated(
browser->platform_delegate(), browser.get(), is_devtools_popup);
}
// 2. Notify the browser's LifeSpanHandler. This must always be the first
@ -200,36 +201,38 @@ CefRefPtr<AlloyBrowserHostImpl> AlloyBrowserHostImpl::CreateInternal(
return browser;
}
// static
CefRefPtr<AlloyBrowserHostImpl> AlloyBrowserHostImpl::FromBaseChecked(
CefRefPtr<CefBrowserHostBase> host_base) {
if (!host_base) {
return nullptr;
}
CHECK(host_base->IsAlloyStyle());
return static_cast<AlloyBrowserHostImpl*>(host_base.get());
}
// static
CefRefPtr<AlloyBrowserHostImpl> AlloyBrowserHostImpl::GetBrowserForHost(
const content::RenderViewHost* host) {
REQUIRE_ALLOY_RUNTIME();
auto browser = CefBrowserHostBase::GetBrowserForHost(host);
return static_cast<AlloyBrowserHostImpl*>(browser.get());
return FromBaseChecked(CefBrowserHostBase::GetBrowserForHost(host));
}
// static
CefRefPtr<AlloyBrowserHostImpl> AlloyBrowserHostImpl::GetBrowserForHost(
const content::RenderFrameHost* host) {
REQUIRE_ALLOY_RUNTIME();
auto browser = CefBrowserHostBase::GetBrowserForHost(host);
return static_cast<AlloyBrowserHostImpl*>(browser.get());
return FromBaseChecked(CefBrowserHostBase::GetBrowserForHost(host));
}
// static
CefRefPtr<AlloyBrowserHostImpl> AlloyBrowserHostImpl::GetBrowserForContents(
const content::WebContents* contents) {
REQUIRE_ALLOY_RUNTIME();
auto browser = CefBrowserHostBase::GetBrowserForContents(contents);
return static_cast<AlloyBrowserHostImpl*>(browser.get());
return FromBaseChecked(CefBrowserHostBase::GetBrowserForContents(contents));
}
// static
CefRefPtr<AlloyBrowserHostImpl> AlloyBrowserHostImpl::GetBrowserForGlobalId(
const content::GlobalRenderFrameHostId& global_id) {
REQUIRE_ALLOY_RUNTIME();
auto browser = CefBrowserHostBase::GetBrowserForGlobalId(global_id);
return static_cast<AlloyBrowserHostImpl*>(browser.get());
return FromBaseChecked(CefBrowserHostBase::GetBrowserForGlobalId(global_id));
}
// AlloyBrowserHostImpl methods.
@ -333,42 +336,6 @@ void AlloyBrowserHostImpl::StopFinding(bool clearSelection) {
}
}
void AlloyBrowserHostImpl::ShowDevToolsOnUIThread(
std::unique_ptr<CefShowDevToolsParams> params) {
CEF_REQUIRE_UIT();
if (!EnsureDevToolsManager()) {
return;
}
devtools_manager_->ShowDevTools(params->window_info_, params->client_,
params->settings_,
params->inspect_element_at_);
}
void AlloyBrowserHostImpl::CloseDevTools() {
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(CEF_UIT,
base::BindOnce(&AlloyBrowserHostImpl::CloseDevTools, this));
return;
}
if (!devtools_manager_) {
return;
}
devtools_manager_->CloseDevTools();
}
bool AlloyBrowserHostImpl::HasDevTools() {
if (!CEF_CURRENTLY_ON_UIT()) {
DCHECK(false) << "called on invalid thread";
return false;
}
if (!devtools_manager_) {
return false;
}
return devtools_manager_->HasDevTools();
}
void AlloyBrowserHostImpl::SetAutoResizeEnabled(bool enabled,
const CefSize& min_size,
const CefSize& max_size) {
@ -636,8 +603,10 @@ void AlloyBrowserHostImpl::CancelContextMenu() {
bool AlloyBrowserHostImpl::MaybeAllowNavigation(
content::RenderFrameHost* opener,
bool is_guest_view,
const content::OpenURLParams& params) {
bool is_guest_view = false;
GetFrameForHost(opener, &is_guest_view);
if (is_guest_view && !params.is_pdf &&
!params.url.SchemeIs(extensions::kExtensionScheme) &&
!params.url.SchemeIs(content::kChromeUIScheme)) {
@ -1175,7 +1144,8 @@ void AlloyBrowserHostImpl::WebContentsCreated(
scoped_refptr<CefBrowserInfo> info =
CefBrowserInfoManager::GetInstance()->CreatePopupBrowserInfo(
new_contents, platform_delegate->IsWindowless(), extra_info);
new_contents, platform_delegate->IsWindowless(),
platform_delegate->IsPrintPreviewSupported(), extra_info);
CHECK(info.get());
CHECK(info->is_popup());
@ -1303,8 +1273,8 @@ void AlloyBrowserHostImpl::ExitPictureInPicture() {
}
bool AlloyBrowserHostImpl::IsBackForwardCacheSupported() {
// Disabled due to issue #3237.
return false;
// Disabled with Alloy bootstrap due to issue #3237.
return cef::IsChromeRuntimeEnabled();
}
content::PreloadingEligibility AlloyBrowserHostImpl::IsPrerender2Supported(
@ -1318,11 +1288,12 @@ content::PreloadingEligibility AlloyBrowserHostImpl::IsPrerender2Supported(
void AlloyBrowserHostImpl::DidFinishNavigation(
content::NavigationHandle* navigation_handle) {
if (web_contents()) {
auto cef_browser_context =
static_cast<AlloyBrowserContext*>(web_contents()->GetBrowserContext());
auto cef_browser_context = CefBrowserContext::FromBrowserContext(
web_contents()->GetBrowserContext());
if (cef_browser_context) {
cef_browser_context->AddVisitedURLs(
navigation_handle->GetRedirectChain());
navigation_handle->GetURL(), navigation_handle->GetRedirectChain(),
navigation_handle->GetPageTransition());
}
}
}

View File

@ -62,6 +62,11 @@ class AlloyBrowserHostImpl : public CefBrowserHostBase,
static CefRefPtr<AlloyBrowserHostImpl> Create(
CefBrowserCreateParams& create_params);
// Safe (checked) conversion from CefBrowserHostBase to AlloyBrowserHostImpl.
// Use this method instead of static_cast.
static CefRefPtr<AlloyBrowserHostImpl> FromBaseChecked(
CefRefPtr<CefBrowserHostBase> host_base);
// Returns the browser associated with the specified RenderViewHost.
static CefRefPtr<AlloyBrowserHostImpl> GetBrowserForHost(
const content::RenderViewHost* host);
@ -85,8 +90,6 @@ class AlloyBrowserHostImpl : public CefBrowserHostBase,
bool matchCase,
bool findNext) override;
void StopFinding(bool clearSelection) override;
void CloseDevTools() override;
bool HasDevTools() override;
bool IsWindowRenderingDisabled() override;
void WasResized() override;
void WasHidden(bool hidden) override;
@ -126,9 +129,9 @@ class AlloyBrowserHostImpl : public CefBrowserHostBase,
void ExecuteChromeCommand(int command_id,
cef_window_open_disposition_t disposition) override;
// Returns true if windowless rendering is enabled.
// CefBrowserHostBase methods:
bool IsWindowless() const override;
bool IsAlloyStyle() const override { return true; }
bool IsVisible() const override;
// Returns true if this browser supports picture-in-picture.
@ -147,7 +150,6 @@ class AlloyBrowserHostImpl : public CefBrowserHostBase,
void CancelContextMenu();
bool MaybeAllowNavigation(content::RenderFrameHost* opener,
bool is_guest_view,
const content::OpenURLParams& params) override;
// Convert from view DIP coordinates to screen coordinates. If
@ -290,10 +292,6 @@ class AlloyBrowserHostImpl : public CefBrowserHostBase,
override;
void WebContentsDestroyed() override;
protected:
void ShowDevToolsOnUIThread(
std::unique_ptr<CefShowDevToolsParams> params) override;
private:
friend class CefBrowserPlatformDelegateAlloy;

View File

@ -9,11 +9,11 @@
#include <memory>
#include <string>
#include "libcef/browser/alloy/devtools/devtools_manager_delegate.h"
#include "libcef/browser/alloy/dialogs/alloy_constrained_window_views_client.h"
#include "libcef/browser/browser_context.h"
#include "libcef/browser/browser_context_keyed_service_factories.h"
#include "libcef/browser/context.h"
#include "libcef/browser/devtools/devtools_manager_delegate.h"
#include "libcef/browser/extensions/extension_system_factory.h"
#include "libcef/browser/file_dialog_runner.h"
#include "libcef/browser/net/chrome_scheme_handler.h"
@ -191,7 +191,8 @@ AlloyBrowserMainParts::~AlloyBrowserMainParts() {
}
void AlloyBrowserMainParts::ToolkitInitialized() {
SetConstrainedWindowViewsClient(CreateAlloyConstrainedWindowViewsClient());
SetConstrainedWindowViewsClient(
CreateAlloyConstrainedWindowViewsClient(nullptr));
#if defined(USE_AURA)
CHECK(aura::Env::GetInstance());

View File

@ -13,6 +13,7 @@
#include "libcef/browser/alloy/alloy_browser_host_impl.h"
#include "libcef/browser/alloy/alloy_browser_main.h"
#include "libcef/browser/alloy/alloy_web_contents_view_delegate.h"
#include "libcef/browser/alloy/devtools/devtools_manager_delegate.h"
#include "libcef/browser/browser_context.h"
#include "libcef/browser/browser_frame.h"
#include "libcef/browser/browser_info.h"
@ -21,7 +22,6 @@
#include "libcef/browser/browser_platform_delegate.h"
#include "libcef/browser/certificate_query.h"
#include "libcef/browser/context.h"
#include "libcef/browser/devtools/devtools_manager_delegate.h"
#include "libcef/browser/extensions/extension_system.h"
#include "libcef/browser/extensions/extension_web_contents_observer.h"
#include "libcef/browser/media_capture_devices_dispatcher.h"
@ -625,10 +625,6 @@ void AlloyContentBrowserClient::AppendExtraCommandLineSwitches(
process ? CefBrowserContext::FromBrowserContext(browser_context)
: nullptr;
if (cef_browser_context) {
if (cef_browser_context->IsPrintPreviewSupported()) {
command_line->AppendSwitch(switches::kEnablePrintPreview);
}
// Based on ChromeContentBrowserClientExtensionsPart::
// AppendExtraRendererCommandLineSwitches
if (extensions::ProcessMap::Get(browser_context)

View File

@ -10,6 +10,8 @@ namespace alloy {
DownloadPrefs* GetDownloadPrefsFromBrowserContext(
content::BrowserContext* context) {
// This function is only called with Alloy bootstrap, so the static_cast is
// safe.
return static_cast<AlloyBrowserContext*>(context)->GetDownloadPrefs();
}

View File

@ -18,7 +18,7 @@
#include "libcef/features/runtime_checks.h"
#include "base/logging.h"
#include "chrome/browser/printing/print_view_manager.h"
#include "chrome/browser/printing/printing_init.h"
#include "chrome/browser/ui/prefs/prefs_tab_helper.h"
#include "components/find_in_page/find_tab_helper.h"
#include "components/find_in_page/find_types.h"
@ -37,7 +37,6 @@ CefBrowserPlatformDelegateAlloy::CefBrowserPlatformDelegateAlloy()
content::WebContents* CefBrowserPlatformDelegateAlloy::CreateWebContents(
CefBrowserCreateParams& create_params,
bool& own_web_contents) {
REQUIRE_ALLOY_RUNTIME();
DCHECK(primary_);
if (!create_params.request_context) {
@ -118,7 +117,6 @@ void CefBrowserPlatformDelegateAlloy::AddNewContents(
const blink::mojom::WindowFeatures& window_features,
bool user_gesture,
bool* was_blocked) {
REQUIRE_ALLOY_RUNTIME();
DCHECK(primary_);
CefRefPtr<AlloyBrowserHostImpl> owner =
@ -162,11 +160,12 @@ void CefBrowserPlatformDelegateAlloy::BrowserCreated(
}
DCHECK(!web_contents_->GetDelegate());
web_contents_->SetDelegate(static_cast<AlloyBrowserHostImpl*>(browser));
web_contents_->SetDelegate(
AlloyBrowserHostImpl::FromBaseChecked(browser).get());
permissions::PermissionRequestManager::CreateForWebContents(web_contents_);
PrefsTabHelper::CreateForWebContents(web_contents_);
printing::PrintViewManager::CreateForWebContents(web_contents_);
printing::InitializePrintingForWebContents(web_contents_);
zoom::ZoomController::CreateForWebContents(web_contents_);
javascript_dialogs::TabModalDialogManager::CreateForWebContents(
@ -190,12 +189,12 @@ void CefBrowserPlatformDelegateAlloy::CreateExtensionHost(
DCHECK(browser_);
DCHECK(!extension_host_);
auto alloy_browser = static_cast<AlloyBrowserHostImpl*>(browser_);
auto alloy_browser = AlloyBrowserHostImpl::FromBaseChecked(browser_);
if (host_type == extensions::mojom::ViewType::kExtensionPopup) {
// Create an extension host that we own.
extension_host_ = new extensions::CefExtensionViewHost(
alloy_browser, extension, web_contents_, url, host_type);
alloy_browser.get(), extension, web_contents_, url, host_type);
// Trigger load of the extension URL.
extension_host_->CreateRendererSoon();
} else if (host_type ==
@ -204,7 +203,7 @@ void CefBrowserPlatformDelegateAlloy::CreateExtensionHost(
alloy_browser->is_background_host_ = true;
// Create an extension host that will be owned by ProcessManager.
extension_host_ = new extensions::CefExtensionBackgroundHost(
alloy_browser,
alloy_browser.get(),
base::BindOnce(&CefBrowserPlatformDelegateAlloy::OnExtensionHostDeleted,
weak_ptr_factory_.GetWeakPtr()),
extension, web_contents_, url, host_type);
@ -312,19 +311,6 @@ void CefBrowserPlatformDelegateAlloy::ConfigureAutoResize() {
}
}
bool CefBrowserPlatformDelegateAlloy::IsPrintPreviewSupported() const {
REQUIRE_ALLOY_RUNTIME();
// Print preview is not currently supported with OSR.
if (IsWindowless()) {
return false;
}
auto cef_browser_context =
CefBrowserContext::FromBrowserContext(web_contents_->GetBrowserContext());
return cef_browser_context->IsPrintPreviewSupported();
}
void CefBrowserPlatformDelegateAlloy::Find(const CefString& searchText,
bool forward,
bool matchCase,

View File

@ -51,10 +51,10 @@ class CefBrowserPlatformDelegateAlloy : public CefBrowserPlatformDelegate {
bool PreHandleGestureEvent(content::WebContents* source,
const blink::WebGestureEvent& event) override;
bool IsNeverComposited(content::WebContents* web_contents) override;
bool IsAlloyStyle() const override { return true; }
void SetAutoResizeEnabled(bool enabled,
const CefSize& min_size,
const CefSize& max_size) override;
bool IsPrintPreviewSupported() const override;
void Find(const CefString& searchText,
bool forward,
bool matchCase,

View File

@ -0,0 +1,46 @@
// Copyright 2024 The Chromium Embedded Framework Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "libcef/browser/alloy/devtools/alloy_devtools_window_runner.h"
#include "libcef/browser/alloy/devtools/devtools_frontend.h"
#include "libcef/browser/thread_util.h"
void AlloyDevToolsWindowRunner::ShowDevTools(
CefBrowserHostBase* opener,
std::unique_ptr<CefShowDevToolsParams> params) {
CEF_REQUIRE_UIT();
if (devtools_frontend_) {
if (!params->inspect_element_at_.IsEmpty()) {
devtools_frontend_->InspectElementAt(params->inspect_element_at_.x,
params->inspect_element_at_.y);
}
devtools_frontend_->Focus();
return;
}
auto alloy_browser = AlloyBrowserHostImpl::FromBaseChecked(opener);
devtools_frontend_ = CefDevToolsFrontend::Show(
alloy_browser.get(), params->window_info_, params->client_,
params->settings_, params->inspect_element_at_,
base::BindOnce(&AlloyDevToolsWindowRunner::OnFrontEndDestroyed,
weak_ptr_factory_.GetWeakPtr()));
}
void AlloyDevToolsWindowRunner::CloseDevTools() {
CEF_REQUIRE_UIT();
if (devtools_frontend_) {
devtools_frontend_->Close();
}
}
bool AlloyDevToolsWindowRunner::HasDevTools() {
CEF_REQUIRE_UIT();
return !!devtools_frontend_;
}
void AlloyDevToolsWindowRunner::OnFrontEndDestroyed() {
CEF_REQUIRE_UIT();
devtools_frontend_ = nullptr;
}

View File

@ -0,0 +1,40 @@
// Copyright 2024 The Chromium Embedded Framework Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CEF_LIBCEF_BROWSER_ALLOY_DEVTOOLS_ALLOY_DEVTOOLS_WINDOW_RUNNER_H_
#define CEF_LIBCEF_BROWSER_ALLOY_DEVTOOLS_ALLOY_DEVTOOLS_WINDOW_RUNNER_H_
#pragma once
#include "libcef/browser/devtools/devtools_window_runner.h"
#include "base/memory/weak_ptr.h"
class CefDevToolsFrontend;
// Creates and runs a DevTools window instance. Only accessed on the UI thread.
class AlloyDevToolsWindowRunner : public CefDevToolsWindowRunner {
public:
AlloyDevToolsWindowRunner() = default;
AlloyDevToolsWindowRunner(const AlloyDevToolsWindowRunner&) = delete;
AlloyDevToolsWindowRunner& operator=(const AlloyDevToolsWindowRunner&) =
delete;
// CefDevToolsWindowRunner methods:
void ShowDevTools(CefBrowserHostBase* opener,
std::unique_ptr<CefShowDevToolsParams> params) override;
void CloseDevTools() override;
bool HasDevTools() override;
private:
void OnFrontEndDestroyed();
// CefDevToolsFrontend will delete itself when the frontend WebContents is
// destroyed.
CefDevToolsFrontend* devtools_frontend_ = nullptr;
base::WeakPtrFactory<AlloyDevToolsWindowRunner> weak_ptr_factory_{this};
};
#endif // CEF_LIBCEF_BROWSER_ALLOY_DEVTOOLS_ALLOY_DEVTOOLS_WINDOW_RUNNER_H_

View File

@ -2,7 +2,7 @@
// 2013 The Chromium Authors. All rights reserved. Use of this source code is
// governed by a BSD-style license that can be found in the LICENSE file.
#include "libcef/browser/devtools/devtools_file_manager.h"
#include "libcef/browser/alloy/devtools/devtools_file_manager.h"
#include "libcef/browser/alloy/alloy_browser_host_impl.h"

View File

@ -2,8 +2,8 @@
// 2013 The Chromium Authors. All rights reserved. Use of this source code is
// governed by a BSD-style license that can be found in the LICENSE file.
#ifndef CEF_LIBCEF_BROWSER_DEVTOOLS_DEVTOOLS_FILE_MANAGER_H_
#define CEF_LIBCEF_BROWSER_DEVTOOLS_DEVTOOLS_FILE_MANAGER_H_
#ifndef CEF_LIBCEF_BROWSER_ALLOY_DEVTOOLS_DEVTOOLS_FILE_MANAGER_H_
#define CEF_LIBCEF_BROWSER_ALLOY_DEVTOOLS_DEVTOOLS_FILE_MANAGER_H_
#include "base/functional/callback_forward.h"
#include "base/memory/weak_ptr.h"
@ -79,4 +79,4 @@ class CefDevToolsFileManager {
base::WeakPtrFactory<CefDevToolsFileManager> weak_factory_;
};
#endif // CEF_LIBCEF_BROWSER_DEVTOOLS_DEVTOOLS_FILE_MANAGER_H_
#endif // CEF_LIBCEF_BROWSER_ALLOY_DEVTOOLS_DEVTOOLS_FILE_MANAGER_H_

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "libcef/browser/devtools/devtools_frontend.h"
#include "libcef/browser/alloy/devtools/devtools_frontend.h"
#include <stddef.h>
@ -10,12 +10,13 @@
#include <memory>
#include <utility>
#include "libcef/browser/alloy/devtools/devtools_manager_delegate.h"
#include "libcef/browser/browser_context.h"
#include "libcef/browser/devtools/devtools_manager_delegate.h"
#include "libcef/browser/net/devtools_scheme_handler.h"
#include "libcef/browser/thread_util.h"
#include "libcef/common/cef_switches.h"
#include "libcef/common/task_runner_manager.h"
#include "libcef/features/runtime_checks.h"
#include "base/base64.h"
#include "base/command_line.h"
@ -243,6 +244,8 @@ CefDevToolsFrontend* CefDevToolsFrontend::Show(
const CefBrowserSettings& settings,
const CefPoint& inspect_element_at,
base::OnceClosure frontend_destroyed_callback) {
REQUIRE_ALLOY_RUNTIME();
CefBrowserSettings new_settings = settings;
if (!windowInfo.windowless_rendering_enabled &&
CefColorGetA(new_settings.background_color) != SK_AlphaOPAQUE) {
@ -252,11 +255,14 @@ CefDevToolsFrontend* CefDevToolsFrontend::Show(
}
CefBrowserCreateParams create_params;
create_params.MaybeSetWindowInfo(windowInfo, /*allow_alloy_style=*/true,
/*allow_chrome_style=*/false);
if (inspected_browser->is_views_hosted()) {
create_params.popup_with_views_hosted_opener = true;
} else {
create_params.window_info = std::make_unique<CefWindowInfo>(windowInfo);
}
create_params.popup_with_alloy_style_opener = true;
create_params.client = client;
create_params.settings = new_settings;
create_params.devtools_opener = inspected_browser;
@ -271,8 +277,7 @@ CefDevToolsFrontend* CefDevToolsFrontend::Show(
// CefDevToolsFrontend will delete itself when the frontend WebContents is
// destroyed.
CefDevToolsFrontend* devtools_frontend = new CefDevToolsFrontend(
static_cast<AlloyBrowserHostImpl*>(frontend_browser.get()),
inspected_contents, inspect_element_at,
frontend_browser.get(), inspected_contents, inspect_element_at,
std::move(frontend_destroyed_callback));
// Need to load the URL after creating the DevTools objects.

View File

@ -2,13 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CEF_LIBCEF_BROWSER_DEVTOOLS_DEVTOOLS_FRONTEND_H_
#define CEF_LIBCEF_BROWSER_DEVTOOLS_DEVTOOLS_FRONTEND_H_
#ifndef CEF_LIBCEF_BROWSER_ALLOY_DEVTOOLS_DEVTOOLS_FRONTEND_H_
#define CEF_LIBCEF_BROWSER_ALLOY_DEVTOOLS_DEVTOOLS_FRONTEND_H_
#include <memory>
#include "libcef/browser/alloy/alloy_browser_host_impl.h"
#include "libcef/browser/devtools/devtools_file_manager.h"
#include "libcef/browser/alloy/devtools/devtools_file_manager.h"
#include "base/files/file_path.h"
#include "base/memory/ref_counted.h"
@ -111,4 +111,4 @@ class CefDevToolsFrontend : public content::WebContentsObserver,
base::WeakPtrFactory<CefDevToolsFrontend> weak_factory_;
};
#endif // CEF_LIBCEF_BROWSER_DEVTOOLS_DEVTOOLS_FRONTEND_H_
#endif // CEF_LIBCEF_BROWSER_ALLOY_DEVTOOLS_DEVTOOLS_FRONTEND_H_

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "libcef/browser/devtools/devtools_manager_delegate.h"
#include "libcef/browser/alloy/devtools/devtools_manager_delegate.h"
#include <stdint.h>

View File

@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CEF_LIBCEF_BROWSER_DEVTOOLS_DEVTOOLS_MANAGER_DELEGATE_H_
#define CEF_LIBCEF_BROWSER_DEVTOOLS_DEVTOOLS_MANAGER_DELEGATE_H_
#ifndef CEF_LIBCEF_BROWSER_ALLOY_DEVTOOLS_DEVTOOLS_MANAGER_DELEGATE_H_
#define CEF_LIBCEF_BROWSER_ALLOY_DEVTOOLS_DEVTOOLS_MANAGER_DELEGATE_H_
#include "content/public/browser/devtools_manager_delegate.h"
@ -32,4 +32,4 @@ class CefDevToolsManagerDelegate : public content::DevToolsManagerDelegate {
bool HasBundledFrontendResources() override;
};
#endif // CEF_LIBCEF_BROWSER_DEVTOOLS_DEVTOOLS_MANAGER_DELEGATE_H_
#endif // CEF_LIBCEF_BROWSER_ALLOY_DEVTOOLS_DEVTOOLS_MANAGER_DELEGATE_H_

View File

@ -15,7 +15,10 @@ namespace {
class AlloyConstrainedWindowViewsClient
: public constrained_window::ConstrainedWindowViewsClient {
public:
AlloyConstrainedWindowViewsClient() = default;
explicit AlloyConstrainedWindowViewsClient(
std::unique_ptr<constrained_window::ConstrainedWindowViewsClient>
chrome_client)
: chrome_client_(std::move(chrome_client)) {}
AlloyConstrainedWindowViewsClient(const AlloyConstrainedWindowViewsClient&) =
delete;
@ -26,6 +29,12 @@ class AlloyConstrainedWindowViewsClient
// ConstrainedWindowViewsClient methods:
web_modal::ModalDialogHost* GetModalDialogHost(
gfx::NativeWindow parent) override {
if (chrome_client_) {
if (auto dialog_host = chrome_client_->GetModalDialogHost(parent)) {
return dialog_host;
}
}
if (auto browser = GetPreferredBrowser(parent)) {
return browser->platform_delegate()->GetWebContentsModalDialogHost();
}
@ -34,6 +43,12 @@ class AlloyConstrainedWindowViewsClient
}
gfx::NativeView GetDialogHostView(gfx::NativeWindow parent) override {
if (chrome_client_) {
if (auto host_view = chrome_client_->GetDialogHostView(parent)) {
return host_view;
}
}
if (auto dialog_host = GetModalDialogHost(parent)) {
return dialog_host->GetHostView();
}
@ -66,11 +81,17 @@ class AlloyConstrainedWindowViewsClient
return browser;
}
std::unique_ptr<constrained_window::ConstrainedWindowViewsClient>
chrome_client_;
};
} // namespace
std::unique_ptr<constrained_window::ConstrainedWindowViewsClient>
CreateAlloyConstrainedWindowViewsClient() {
return std::make_unique<AlloyConstrainedWindowViewsClient>();
CreateAlloyConstrainedWindowViewsClient(
std::unique_ptr<constrained_window::ConstrainedWindowViewsClient>
chrome_client) {
return std::make_unique<AlloyConstrainedWindowViewsClient>(
std::move(chrome_client));
}

View File

@ -12,6 +12,8 @@
// Creates a ConstrainedWindowViewsClient for the Chrome environment.
std::unique_ptr<constrained_window::ConstrainedWindowViewsClient>
CreateAlloyConstrainedWindowViewsClient();
CreateAlloyConstrainedWindowViewsClient(
std::unique_ptr<constrained_window::ConstrainedWindowViewsClient>
chrome_client);
#endif // CEF_LIBCEF_BROWSER_ALLOY_DIALOGS_ALLOY_CONSTRAINED_WINDOW_VIEWS_CLIENT_H_
#endif // CEF_LIBCEF_BROWSER_ALLOY_DIALOGS_ALLOY_CONSTRAINED_WINDOW_VIEWS_CLIENT_H_

View File

@ -44,14 +44,20 @@ AlloyWebContentsDialogHelper::GetWebContentsModalDialogHost() {
gfx::NativeView AlloyWebContentsDialogHelper::GetHostView() const {
// Windowless rendering uses GetAcceleratedWidget() instead.
if (browser_delegate_->IsWindowless()) {
return gfx::NativeView();
if (!browser_delegate_->IsWindowless()) {
#if BUILDFLAG(IS_MAC)
// This is supported with all configurations except MacOS with external
// parent because we can't provide a gfx::NativeView or a
// gfx::AcceleratedWidget on that platform (it's an arbitrary internal
// Chromium type). This code should not be reached in that case because
// print preview is disabled.
DCHECK(!browser_delegate_->HasExternalParent());
#endif
if (auto widget = browser_delegate_->GetWindowWidget()) {
return widget->GetNativeView();
}
}
if (auto widget = browser_delegate_->GetWindowWidget()) {
return widget->GetNativeView();
}
DCHECK(false);
NOTIMPLEMENTED();
return gfx::NativeView();
}
@ -59,15 +65,13 @@ gfx::AcceleratedWidget AlloyWebContentsDialogHelper::GetAcceleratedWidget()
const {
#if defined(USE_AURA)
// Windowed rendering uses GetHostView() instead.
if (!browser_delegate_->IsWindowless()) {
return gfx::kNullAcceleratedWidget;
}
if (auto parent_widget = browser_delegate_->GetHostWindowHandle()) {
return parent_widget;
if (browser_delegate_->IsWindowless()) {
if (auto parent_widget = browser_delegate_->GetHostWindowHandle()) {
return parent_widget;
}
}
#endif // defined(USE_AURA)
DCHECK(false);
NOTIMPLEMENTED();
return gfx::kNullAcceleratedWidget;
}

View File

@ -14,7 +14,6 @@
#include "libcef/browser/thread_util.h"
#include "libcef/common/cef_switches.h"
#include "libcef/common/frame_util.h"
#include "libcef/features/runtime.h"
#include "base/files/file_util.h"
#include "base/lazy_instance.h"
@ -396,10 +395,6 @@ bool CefBrowserContext::UnloadExtension(const CefString& extension_id) {
return false;
}
bool CefBrowserContext::IsPrintPreviewSupported() const {
return true;
}
network::mojom::NetworkContext* CefBrowserContext::GetNetworkContext() {
CEF_REQUIRE_UIT();
auto browser_context = AsBrowserContext();

View File

@ -20,6 +20,7 @@
#include "base/task/sequenced_task_runner_helpers.h"
#include "chrome/common/plugin.mojom.h"
#include "services/network/public/mojom/network_context.mojom.h"
#include "ui/base/page_transition_types.h"
#include "url/origin.h"
/*
@ -172,8 +173,11 @@ class CefBrowserContext {
// Called from CefExtensionImpl::Unload().
virtual bool UnloadExtension(const CefString& extension_id);
// Returns true if this context supports print preview.
virtual bool IsPrintPreviewSupported() const;
// Called from AlloyBrowserHostImpl::DidFinishNavigation to update the table
// of visited links.
virtual void AddVisitedURLs(const GURL& url,
const std::vector<GURL>& redirect_chain,
ui::PageTransition transition) = 0;
network::mojom::NetworkContext* GetNetworkContext();

View File

@ -5,7 +5,9 @@
#include "libcef/browser/browser_frame.h"
#include "libcef/browser/browser_host_base.h"
#include "libcef/browser/browser_info_manager.h"
#include "libcef/browser/thread_util.h"
#include "libcef/common/frame_util.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
@ -57,26 +59,31 @@ void CefBrowserFrame::FrameAttached(
bool reattached) {
// Always send to the newly created RFH, which may be speculative when
// navigating cross-origin.
if (auto host = GetFrameHost(/*prefer_speculative=*/true)) {
bool excluded_type;
if (auto host = GetFrameHost(/*prefer_speculative=*/true, &excluded_type)) {
host->FrameAttached(std::move(render_frame), reattached);
} else if (excluded_type) {
VLOG(1) << "frame "
<< frame_util::GetFrameDebugString(
render_frame_host()->GetGlobalFrameToken())
<< " attach denied";
mojo::Remote<cef::mojom::RenderFrame> render_frame_remote;
render_frame_remote.Bind(std::move(render_frame));
render_frame_remote->FrameAttachedAck(/*allow=*/false);
}
}
void CefBrowserFrame::UpdateDraggableRegions(
std::optional<std::vector<cef::mojom::DraggableRegionEntryPtr>> regions) {
if (auto host = GetFrameHost()) {
if (auto host = GetFrameHost(/*prefer_speculative=*/false)) {
host->UpdateDraggableRegions(std::move(regions));
}
}
CefRefPtr<CefFrameHostImpl> CefBrowserFrame::GetFrameHost(
bool prefer_speculative) const {
CEF_REQUIRE_UIT();
auto rfh = render_frame_host();
if (auto browser = CefBrowserHostBase::GetBrowserForHost(rfh)) {
return browser->browser_info()->GetFrameForHost(rfh, nullptr,
prefer_speculative);
}
DCHECK(false);
return nullptr;
bool prefer_speculative,
bool* excluded_type) const {
return CefBrowserInfoManager::GetFrameHost(
render_frame_host(), prefer_speculative,
/*browser_info=*/nullptr, excluded_type);
}

View File

@ -48,8 +48,8 @@ class CefBrowserFrame
// FrameServiceBase methods:
bool ShouldCloseOnFinishNavigation() const override { return false; }
CefRefPtr<CefFrameHostImpl> GetFrameHost(
bool prefer_speculative = false) const;
CefRefPtr<CefFrameHostImpl> GetFrameHost(bool prefer_speculative,
bool* excluded_type = nullptr) const;
};
#endif // CEF_LIBCEF_BROWSER_BROWSER_FRAME_H_

View File

@ -9,6 +9,7 @@
#include "libcef/browser/browser_info_manager.h"
#include "libcef/browser/browser_platform_delegate.h"
#include "libcef/browser/context.h"
#include "libcef/browser/extensions/browser_extensions_util.h"
#include "libcef/browser/hang_monitor.h"
#include "libcef/browser/image_impl.h"
#include "libcef/browser/navigation_entry_impl.h"
@ -83,6 +84,12 @@ class WebContentsUserDataAdapter : public base::SupportsUserData::Data {
} // namespace
// static
CefRefPtr<CefBrowserHostBase> CefBrowserHostBase::FromBrowser(
CefRefPtr<CefBrowser> browser) {
return static_cast<CefBrowserHostBase*>(browser.get());
}
// static
CefRefPtr<CefBrowserHostBase> CefBrowserHostBase::GetBrowserForHost(
const content::RenderViewHost* host) {
@ -115,7 +122,18 @@ CefRefPtr<CefBrowserHostBase> CefBrowserHostBase::GetBrowserForContents(
const content::WebContents* contents) {
DCHECK(contents);
CEF_REQUIRE_UIT();
return WebContentsUserDataAdapter::Get(contents);
if (auto browser = WebContentsUserDataAdapter::Get(contents)) {
return browser;
}
// Try the owner WebContents if |contents| originates from a guest view such
// as the PDF viewer or Print Preview.
// This is safe to call even if Alloy extensions are disabled.
if (auto* owner_contents = extensions::GetOwnerForGuestContents(contents)) {
return WebContentsUserDataAdapter::Get(owner_contents);
}
return nullptr;
}
// static
@ -135,10 +153,9 @@ CefRefPtr<CefBrowserHostBase> CefBrowserHostBase::GetBrowserForGlobalId(
return GetBrowserForHost(render_frame_host);
} else {
// Use the thread-safe approach.
bool is_guest_view = false;
auto info = CefBrowserInfoManager::GetInstance()->GetBrowserInfo(
global_id, &is_guest_view);
if (info && !is_guest_view) {
auto info = CefBrowserInfoManager::GetInstance()->GetBrowserInfo(global_id,
nullptr);
if (info) {
auto browser = info->browser();
if (!browser) {
LOG(WARNING) << "Found browser id " << info->browser_id()
@ -168,10 +185,9 @@ CefRefPtr<CefBrowserHostBase> CefBrowserHostBase::GetBrowserForGlobalToken(
return GetBrowserForHost(render_frame_host);
} else {
// Use the thread-safe approach.
bool is_guest_view = false;
auto info = CefBrowserInfoManager::GetInstance()->GetBrowserInfo(
global_token, &is_guest_view);
if (info && !is_guest_view) {
global_token, nullptr);
if (info) {
auto browser = info->browser();
if (!browser) {
LOG(WARNING) << "Found browser id " << info->browser_id()
@ -251,7 +267,8 @@ void CefBrowserHostBase::InitializeBrowser() {
void CefBrowserHostBase::DestroyBrowser() {
CEF_REQUIRE_UIT();
devtools_manager_.reset();
devtools_protocol_manager_.reset();
devtools_window_runner_.reset();
media_stream_registrar_.reset();
platform_delegate_.reset();
@ -562,6 +579,30 @@ void CefBrowserHostBase::ShowDevTools(const CefWindowInfo& windowInfo,
}
}
void CefBrowserHostBase::CloseDevTools() {
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(CEF_UIT,
base::BindOnce(&CefBrowserHostBase::CloseDevTools, this));
return;
}
if (devtools_window_runner_) {
devtools_window_runner_->CloseDevTools();
}
}
bool CefBrowserHostBase::HasDevTools() {
if (!CEF_CURRENTLY_ON_UIT()) {
DCHECK(false) << "called on invalid thread";
return false;
}
if (devtools_window_runner_) {
return devtools_window_runner_->HasDevTools();
}
return false;
}
bool CefBrowserHostBase::SendDevToolsMessage(const void* message,
size_t message_size) {
if (!message || message_size == 0) {
@ -580,10 +621,10 @@ bool CefBrowserHostBase::SendDevToolsMessage(const void* message,
return false;
}
if (!EnsureDevToolsManager()) {
if (!EnsureDevToolsProtocolManager()) {
return false;
}
return devtools_manager_->SendDevToolsMessage(message, message_size);
return devtools_protocol_manager_->SendDevToolsMessage(message, message_size);
}
int CefBrowserHostBase::ExecuteDevToolsMethod(
@ -598,10 +639,11 @@ int CefBrowserHostBase::ExecuteDevToolsMethod(
return 0;
}
if (!EnsureDevToolsManager()) {
if (!EnsureDevToolsProtocolManager()) {
return 0;
}
return devtools_manager_->ExecuteDevToolsMethod(message_id, method, params);
return devtools_protocol_manager_->ExecuteDevToolsMethod(message_id, method,
params);
}
CefRefPtr<CefRegistration> CefBrowserHostBase::AddDevToolsMessageObserver(
@ -609,7 +651,7 @@ CefRefPtr<CefRegistration> CefBrowserHostBase::AddDevToolsMessageObserver(
if (!observer) {
return nullptr;
}
auto registration = CefDevToolsManager::CreateRegistration(observer);
auto registration = CefDevToolsProtocolManager::CreateRegistration(observer);
InitializeDevToolsRegistrationOnUIThread(registration);
return registration.get();
}
@ -731,6 +773,10 @@ bool CefBrowserHostBase::IsRenderProcessUnresponsive() {
return false;
}
cef_runtime_style_t CefBrowserHostBase::GetRuntimeStyle() {
return IsAlloyStyle() ? CEF_RUNTIME_STYLE_ALLOY : CEF_RUNTIME_STYLE_CHROME;
}
void CefBrowserHostBase::ReplaceMisspelling(const CefString& word) {
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(
@ -948,8 +994,8 @@ int CefBrowserHostBase::GetIdentifier() {
}
bool CefBrowserHostBase::IsSame(CefRefPtr<CefBrowser> that) {
auto impl = static_cast<CefBrowserHostBase*>(that.get());
return (impl == this);
auto impl = FromBrowser(that);
return (impl.get() == this);
}
bool CefBrowserHostBase::HasDocument() {
@ -1075,13 +1121,14 @@ void CefBrowserHostBase::OnWebContentsDestroyed(
content::WebContents* web_contents) {}
CefRefPtr<CefFrame> CefBrowserHostBase::GetFrameForHost(
const content::RenderFrameHost* host) {
const content::RenderFrameHost* host,
bool* is_guest_view) {
CEF_REQUIRE_UIT();
if (!host) {
return nullptr;
}
return browser_info_->GetFrameForHost(host);
return browser_info_->GetFrameForHost(host, is_guest_view);
}
CefRefPtr<CefFrame> CefBrowserHostBase::GetFrameForGlobalId(
@ -1143,6 +1190,12 @@ bool CefBrowserHostBase::Navigate(const content::OpenURLParams& params) {
return false;
}
void CefBrowserHostBase::ShowDevToolsOnUIThread(
std::unique_ptr<CefShowDevToolsParams> params) {
CEF_REQUIRE_UIT();
GetDevToolsWindowRunner()->ShowDevTools(this, std::move(params));
}
void CefBrowserHostBase::ViewText(const std::string& text) {
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(CEF_UIT,
@ -1196,7 +1249,6 @@ void CefBrowserHostBase::SelectFileListenerDestroyed(
bool CefBrowserHostBase::MaybeAllowNavigation(
content::RenderFrameHost* opener,
bool is_guest_view,
const content::OpenURLParams& params) {
return true;
}
@ -1244,10 +1296,6 @@ SkColor CefBrowserHostBase::GetBackgroundColor() const {
&settings_, IsWindowless() ? STATE_ENABLED : STATE_DISABLED);
}
bool CefBrowserHostBase::IsWindowless() const {
return false;
}
content::WebContents* CefBrowserHostBase::GetWebContents() const {
CEF_REQUIRE_UIT();
return contents_delegate_->web_contents();
@ -1270,6 +1318,13 @@ CefMediaStreamRegistrar* CefBrowserHostBase::GetMediaStreamRegistrar() {
return media_stream_registrar_.get();
}
CefDevToolsWindowRunner* CefBrowserHostBase::GetDevToolsWindowRunner() {
if (!devtools_window_runner_) {
devtools_window_runner_ = CefDevToolsWindowRunner::Create();
}
return devtools_window_runner_.get();
}
views::Widget* CefBrowserHostBase::GetWindowWidget() const {
CEF_REQUIRE_UIT();
if (!platform_delegate_) {
@ -1321,14 +1376,15 @@ bool CefBrowserHostBase::IsVisible() const {
return false;
}
bool CefBrowserHostBase::EnsureDevToolsManager() {
bool CefBrowserHostBase::EnsureDevToolsProtocolManager() {
CEF_REQUIRE_UIT();
if (!contents_delegate_->web_contents()) {
return false;
}
if (!devtools_manager_) {
devtools_manager_ = std::make_unique<CefDevToolsManager>(this);
if (!devtools_protocol_manager_) {
devtools_protocol_manager_ =
std::make_unique<CefDevToolsProtocolManager>(this);
}
return true;
}
@ -1344,10 +1400,10 @@ void CefBrowserHostBase::InitializeDevToolsRegistrationOnUIThread(
return;
}
if (!EnsureDevToolsManager()) {
if (!EnsureDevToolsProtocolManager()) {
return;
}
devtools_manager_->InitializeRegistrationOnUIThread(registration);
devtools_protocol_manager_->InitializeRegistrationOnUIThread(registration);
}
bool CefBrowserHostBase::EnsureFileDialogManager() {

View File

@ -13,7 +13,8 @@
#include "libcef/browser/browser_contents_delegate.h"
#include "libcef/browser/browser_info.h"
#include "libcef/browser/browser_platform_delegate.h"
#include "libcef/browser/devtools/devtools_manager.h"
#include "libcef/browser/devtools/devtools_protocol_manager.h"
#include "libcef/browser/devtools/devtools_window_runner.h"
#include "libcef/browser/file_dialog_manager.h"
#include "libcef/browser/frame_host_impl.h"
#include "libcef/browser/media_stream_registrar.h"
@ -27,15 +28,19 @@ namespace extensions {
class Extension;
}
class RenderViewContextMenuObserver;
// Parameters that are passed to the runtime-specific Create methods.
struct CefBrowserCreateParams {
CefBrowserCreateParams() = default;
// Copy constructor used with the chrome runtime only.
// Copy constructor used with Chrome style only.
CefBrowserCreateParams(const CefBrowserCreateParams& that) {
operator=(that);
}
CefBrowserCreateParams& operator=(const CefBrowserCreateParams& that) {
DCHECK(that.IsChromeStyle());
// Not all parameters can be copied.
client = that.client;
url = that.url;
@ -43,14 +48,29 @@ struct CefBrowserCreateParams {
request_context = that.request_context;
extra_info = that.extra_info;
if (that.window_info) {
MaybeSetWindowInfo(*that.window_info);
MaybeSetWindowInfo(*that.window_info, /*allow_alloy_style=*/false,
/*allow_chrome_style=*/true);
}
browser_view = that.browser_view;
return *this;
}
// Initialize |window_info| with expected defaults before passing to a client
// callback. |opener| will be non-nullptr for popups, DevTools windows, etc.
static void InitWindowInfo(CefWindowInfo* window_info,
CefBrowserHostBase* opener);
// Set |window_info| if appropriate (see below).
void MaybeSetWindowInfo(const CefWindowInfo& window_info);
void MaybeSetWindowInfo(const CefWindowInfo& window_info,
bool allow_alloy_style,
bool allow_chrome_style);
// Returns true if |window_info| indicates creation of a Chrome style window.
static bool IsChromeStyle(const CefWindowInfo* window_info);
bool IsChromeStyle() const;
// Returns true if parameters indicate windowless (off-screen) rendering.
bool IsWindowless() const;
// Platform-specific window creation info. Will be nullptr for Views-hosted
// browsers except when using the Chrome runtime with a native parent handle.
@ -65,6 +85,10 @@ struct CefBrowserCreateParams {
// PopupWebContentsCreated).
bool popup_with_views_hosted_opener = false;
// True if this browser is a popup and has an Alloy style opener. Only used
// with the Chrome runtime.
bool popup_with_alloy_style_opener = false;
// Client implementation. May be nullptr.
CefRefPtr<CefClient> client;
@ -95,23 +119,6 @@ struct CefBrowserCreateParams {
extensions::mojom::ViewType::kInvalid;
};
// Parameters passed to ShowDevToolsOnUIThread().
struct CefShowDevToolsParams {
CefShowDevToolsParams(const CefWindowInfo& windowInfo,
CefRefPtr<CefClient> client,
const CefBrowserSettings& settings,
const CefPoint& inspect_element_at)
: window_info_(windowInfo),
client_(client),
settings_(settings),
inspect_element_at_(inspect_element_at) {}
CefWindowInfo window_info_;
CefRefPtr<CefClient> client_;
CefBrowserSettings settings_;
CefPoint inspect_element_at_;
};
// Base class for CefBrowserHost implementations. Includes functionality that is
// shared by the alloy and chrome runtimes. All methods are thread-safe unless
// otherwise indicated.
@ -136,6 +143,11 @@ class CefBrowserHostBase : public CefBrowserHost,
static CefRefPtr<CefBrowserHostBase> Create(
CefBrowserCreateParams& create_params);
// Safe conversion from CefBrowserHostBase to CefBrowserHostBase.
// Use this method instead of static_cast.
static CefRefPtr<CefBrowserHostBase> FromBrowser(
CefRefPtr<CefBrowser> browser);
// Returns the browser associated with the specified RenderViewHost.
static CefRefPtr<CefBrowserHostBase> GetBrowserForHost(
const content::RenderViewHost* host);
@ -216,6 +228,8 @@ class CefBrowserHostBase : public CefBrowserHost,
CefRefPtr<CefClient> client,
const CefBrowserSettings& settings,
const CefPoint& inspect_element_at) override;
void CloseDevTools() override;
bool HasDevTools() override;
void ReplaceMisspelling(const CefString& word) override;
void AddWordToDictionary(const CefString& word) override;
void SendKeyEvent(const CefKeyEvent& event) override;
@ -240,6 +254,7 @@ class CefBrowserHostBase : public CefBrowserHost,
bool IsFullscreen() override;
void ExitFullscreen(bool will_cause_resize) override;
bool IsRenderProcessUnresponsive() override;
cef_runtime_style_t GetRuntimeStyle() override;
// CefBrowser methods:
bool IsValid() override;
@ -270,8 +285,13 @@ class CefBrowserHostBase : public CefBrowserHost,
void OnStateChanged(CefBrowserContentsState state_changed) override;
void OnWebContentsDestroyed(content::WebContents* web_contents) override;
// Returns the frame associated with the specified RenderFrameHost.
CefRefPtr<CefFrame> GetFrameForHost(const content::RenderFrameHost* host);
// Returns the frame object matching the specified |host| or nullptr if no
// match is found. Nullptr will also be returned if a guest view match is
// found because we don't create frame objects for guest views. If
// |is_guest_view| is non-nullptr it will be set to true in this case. Must be
// called on the UI thread.
CefRefPtr<CefFrame> GetFrameForHost(const content::RenderFrameHost* host,
bool* is_guest_view = nullptr);
// Returns the frame associated with the specified global ID/token. See
// documentation on RenderFrameHost::GetFrameTreeNodeId/Token() for why the
@ -310,7 +330,6 @@ class CefBrowserHostBase : public CefBrowserHost,
// Called from CefBrowserInfoManager::MaybeAllowNavigation.
virtual bool MaybeAllowNavigation(content::RenderFrameHost* opener,
bool is_guest_view,
const content::OpenURLParams& params);
// Helpers for executing client callbacks. Must be called on the UI thread.
@ -330,7 +349,11 @@ class CefBrowserHostBase : public CefBrowserHost,
SkColor GetBackgroundColor() const;
// Returns true if windowless rendering is enabled.
virtual bool IsWindowless() const;
virtual bool IsWindowless() const = 0;
// Returns the runtime style of this browser.
virtual bool IsAlloyStyle() const = 0;
bool IsChromeStyle() const { return !IsAlloyStyle(); }
// Accessors that must be called on the UI thread.
content::WebContents* GetWebContents() const;
@ -342,6 +365,7 @@ class CefBrowserHostBase : public CefBrowserHost,
return contents_delegate_.get();
}
CefMediaStreamRegistrar* GetMediaStreamRegistrar();
CefDevToolsWindowRunner* GetDevToolsWindowRunner();
CefRefPtr<CefUnresponsiveProcessCallback> unresponsive_process_callback()
const {
@ -352,6 +376,13 @@ class CefBrowserHostBase : public CefBrowserHost,
unresponsive_process_callback_ = callback;
}
RenderViewContextMenuObserver* context_menu_observer() const {
return context_menu_observer_;
}
void set_context_menu_observer(RenderViewContextMenuObserver* observer) {
context_menu_observer_ = observer;
}
// Returns the Widget owner for the browser window. Only used with windowed
// browsers.
views::Widget* GetWindowWidget() const;
@ -378,7 +409,7 @@ class CefBrowserHostBase : public CefBrowserHost,
virtual bool IsVisible() const;
protected:
bool EnsureDevToolsManager();
bool EnsureDevToolsProtocolManager();
void InitializeDevToolsRegistrationOnUIThread(
CefRefPtr<CefRegistration> registration);
@ -386,8 +417,7 @@ class CefBrowserHostBase : public CefBrowserHost,
virtual bool Navigate(const content::OpenURLParams& params);
// Called from ShowDevTools to perform the actual show.
virtual void ShowDevToolsOnUIThread(
std::unique_ptr<CefShowDevToolsParams> params) = 0;
void ShowDevToolsOnUIThread(std::unique_ptr<CefShowDevToolsParams> params);
// Create the CefFileDialogManager if it doesn't already exist.
bool EnsureFileDialogManager();
@ -403,6 +433,7 @@ class CefBrowserHostBase : public CefBrowserHost,
// Only accessed on the UI thread.
std::unique_ptr<CefBrowserContentsDelegate> contents_delegate_;
CefRefPtr<CefUnresponsiveProcessCallback> unresponsive_process_callback_;
RenderViewContextMenuObserver* context_menu_observer_ = nullptr;
// Observers that want to be notified of changes to this object.
// Only accessed on the UI thread.
@ -421,8 +452,11 @@ class CefBrowserHostBase : public CefBrowserHost,
bool is_fullscreen_ = false;
CefRefPtr<CefFrameHostImpl> focused_frame_;
// Used for creating and managing DevTools instances.
std::unique_ptr<CefDevToolsManager> devtools_manager_;
// Used for managing DevTools instances without a frontend.
std::unique_ptr<CefDevToolsProtocolManager> devtools_protocol_manager_;
// Used for creating and running the DevTools window frontend.
std::unique_ptr<CefDevToolsWindowRunner> devtools_window_runner_;
std::unique_ptr<CefMediaStreamRegistrar> media_stream_registrar_;

View File

@ -65,8 +65,9 @@ bool CefBrowserHost::CreateBrowser(
// Verify windowless rendering requirements.
if (windowInfo.windowless_rendering_enabled &&
!client->GetRenderHandler().get()) {
DCHECK(false) << "CefRenderHandler implementation is required";
(!client || !client->GetRenderHandler().get())) {
LOG(ERROR)
<< "Windowless rendering requires a CefRenderHandler implementation";
return false;
}
@ -133,13 +134,15 @@ CefRefPtr<CefBrowser> CefBrowserHost::CreateBrowserSync(
// Verify windowless rendering requirements.
if (windowInfo.windowless_rendering_enabled &&
!client->GetRenderHandler().get()) {
DCHECK(false) << "CefRenderHandler implementation is required";
(!client || !client->GetRenderHandler().get())) {
LOG(ERROR)
<< "Windowless rendering requires a CefRenderHandler implementation";
return nullptr;
}
CefBrowserCreateParams create_params;
create_params.MaybeSetWindowInfo(windowInfo);
create_params.MaybeSetWindowInfo(windowInfo, /*allow_alloy_style=*/true,
/*allow_chrome_style=*/true);
create_params.client = client;
create_params.url = url;
create_params.settings = settings;
@ -149,18 +152,121 @@ CefRefPtr<CefBrowser> CefBrowserHost::CreateBrowserSync(
return CefBrowserHostBase::Create(create_params);
}
// static
bool CefBrowserCreateParams::IsChromeStyle(const CefWindowInfo* window_info) {
if (!cef::IsChromeRuntimeEnabled()) {
return false;
}
if (!window_info) {
return true;
}
// Both CHROME and DEFAULT indicate Chrome style with Chrome bootstrap.
return window_info->runtime_style == CEF_RUNTIME_STYLE_CHROME ||
window_info->runtime_style == CEF_RUNTIME_STYLE_DEFAULT;
}
bool CefBrowserCreateParams::IsChromeStyle() const {
if (!cef::IsChromeRuntimeEnabled()) {
return false;
}
const bool chrome_style_via_window_info = IsChromeStyle(window_info.get());
if (popup_with_alloy_style_opener) {
// Creating a popup where the opener is Alloy style.
if (chrome_style_via_window_info &&
window_info->runtime_style == CEF_RUNTIME_STYLE_CHROME) {
// Only use Chrome style for the popup if the client explicitly sets
// CHROME (and not DEFAULT) via CefWindowInfo.runtime_style.
return true;
}
return false;
}
if (browser_view) {
// Must match the BrowserView style. GetRuntimeStyle() will not return
// DEFAULT.
return browser_view->GetRuntimeStyle() == CEF_RUNTIME_STYLE_CHROME;
}
// Chrome style does not support windowless rendering.
return chrome_style_via_window_info && !IsWindowless();
}
bool CefBrowserCreateParams::IsWindowless() const {
return window_info && window_info->windowless_rendering_enabled && client &&
client->GetRenderHandler().get();
}
// static
void CefBrowserCreateParams::InitWindowInfo(CefWindowInfo* window_info,
CefBrowserHostBase* opener) {
#if BUILDFLAG(IS_WIN)
window_info->SetAsPopup(nullptr, CefString());
#endif
if (cef::IsChromeRuntimeEnabled() && opener->IsAlloyStyle()) {
// Give the popup the same runtime style as the opener.
window_info->runtime_style = CEF_RUNTIME_STYLE_ALLOY;
}
}
void CefBrowserCreateParams::MaybeSetWindowInfo(
const CefWindowInfo& new_window_info) {
if (!cef::IsChromeRuntimeEnabled() ||
const CefWindowInfo& new_window_info,
bool allow_alloy_style,
bool allow_chrome_style) {
if (!cef::IsChromeRuntimeEnabled()) {
// Chrome style is not supported wih the Alloy bootstrap.
allow_chrome_style = false;
}
if (allow_chrome_style && new_window_info.windowless_rendering_enabled) {
// Chrome style is not supported with windowles rendering.
allow_chrome_style = false;
}
#if BUILDFLAG(IS_MAC)
if (allow_chrome_style &&
chrome_child_window::HasParentHandle(new_window_info)) {
// Chrome style is not supported with native parent on MacOS. See issue
// #3294.
allow_chrome_style = false;
}
#endif
DCHECK(allow_alloy_style || allow_chrome_style);
bool reset_style = false;
if (new_window_info.runtime_style == CEF_RUNTIME_STYLE_ALLOY &&
!allow_alloy_style) {
LOG(ERROR) << "Alloy style is not supported for this browser";
reset_style = true;
} else if (new_window_info.runtime_style == CEF_RUNTIME_STYLE_CHROME &&
!allow_chrome_style) {
LOG(ERROR) << "Chrome style is not supported for this browser";
reset_style = true;
}
const bool is_chrome_style =
allow_chrome_style && IsChromeStyle(&new_window_info);
if (!is_chrome_style ||
chrome_child_window::HasParentHandle(new_window_info)) {
window_info = std::make_unique<CefWindowInfo>(new_window_info);
if (cef::IsChromeRuntimeEnabled() && !allow_chrome_style) {
// Only Alloy style is allowed.
window_info->runtime_style = CEF_RUNTIME_STYLE_ALLOY;
} else if (reset_style) {
// Use the default style.
window_info->runtime_style = CEF_RUNTIME_STYLE_DEFAULT;
}
}
}
// static
CefRefPtr<CefBrowserHostBase> CefBrowserHostBase::Create(
CefBrowserCreateParams& create_params) {
if (cef::IsChromeRuntimeEnabled()) {
if (create_params.IsChromeStyle()) {
if (auto browser =
chrome_child_window::MaybeCreateChildBrowser(create_params)) {
return browser.get();

View File

@ -29,10 +29,12 @@ CefBrowserInfo::FrameInfo::~FrameInfo() {
CefBrowserInfo::CefBrowserInfo(int browser_id,
bool is_popup,
bool is_windowless,
bool print_preview_enabled,
CefRefPtr<CefDictionaryValue> extra_info)
: browser_id_(browser_id),
is_popup_(is_popup),
is_windowless_(is_windowless),
print_preview_enabled_(print_preview_enabled),
extra_info_(extra_info) {
DCHECK_GT(browser_id, 0);

View File

@ -37,6 +37,7 @@ class CefBrowserInfo : public base::RefCountedThreadSafe<CefBrowserInfo> {
CefBrowserInfo(int browser_id,
bool is_popup,
bool is_windowless,
bool print_preview_enabled,
CefRefPtr<CefDictionaryValue> extra_info);
CefBrowserInfo(const CefBrowserInfo&) = delete;
@ -45,6 +46,7 @@ class CefBrowserInfo : public base::RefCountedThreadSafe<CefBrowserInfo> {
int browser_id() const { return browser_id_; }
bool is_popup() const { return is_popup_; }
bool is_windowless() const { return is_windowless_; }
bool print_preview_enabled() const { return print_preview_enabled_; }
CefRefPtr<CefDictionaryValue> extra_info() const { return extra_info_; }
// May return NULL if the browser has not yet been created or if the browser
@ -201,9 +203,10 @@ class CefBrowserInfo : public base::RefCountedThreadSafe<CefBrowserInfo> {
void RemoveAllFrames(CefRefPtr<CefBrowserHostBase> old_browser);
int browser_id_;
bool is_popup_;
bool is_windowless_;
const int browser_id_;
const bool is_popup_;
const bool is_windowless_;
const bool print_preview_enabled_;
CefRefPtr<CefDictionaryValue> extra_info_;
// Navigation will be blocked while |navigation_lock_| exists.

View File

@ -14,7 +14,7 @@
#include "libcef/common/extensions/extensions_util.h"
#include "libcef/common/frame_util.h"
#include "libcef/common/values_impl.h"
#include "libcef/features/runtime_checks.h"
#include "libcef/features/runtime.h"
#include "base/command_line.h"
#include "base/logging.h"
@ -66,11 +66,13 @@ CefBrowserInfoManager* CefBrowserInfoManager::GetInstance() {
scoped_refptr<CefBrowserInfo> CefBrowserInfoManager::CreateBrowserInfo(
bool is_popup,
bool is_windowless,
bool print_preview_enabled,
CefRefPtr<CefDictionaryValue> extra_info) {
base::AutoLock lock_scope(browser_info_lock_);
scoped_refptr<CefBrowserInfo> browser_info = new CefBrowserInfo(
++next_browser_id_, is_popup, is_windowless, extra_info);
scoped_refptr<CefBrowserInfo> browser_info =
new CefBrowserInfo(++next_browser_id_, is_popup, is_windowless,
print_preview_enabled, extra_info);
browser_info_list_.push_back(browser_info);
return browser_info;
@ -79,24 +81,23 @@ scoped_refptr<CefBrowserInfo> CefBrowserInfoManager::CreateBrowserInfo(
scoped_refptr<CefBrowserInfo> CefBrowserInfoManager::CreatePopupBrowserInfo(
content::WebContents* new_contents,
bool is_windowless,
bool print_preview_enabled,
CefRefPtr<CefDictionaryValue> extra_info) {
base::AutoLock lock_scope(browser_info_lock_);
CEF_REQUIRE_UIT();
auto frame_host = new_contents->GetPrimaryMainFrame();
scoped_refptr<CefBrowserInfo> browser_info =
new CefBrowserInfo(++next_browser_id_, true, is_windowless, extra_info);
browser_info_list_.push_back(browser_info);
scoped_refptr<CefBrowserInfo> browser_info;
{
base::AutoLock lock_scope(browser_info_lock_);
browser_info = new CefBrowserInfo(++next_browser_id_, true, is_windowless,
print_preview_enabled, extra_info);
browser_info_list_.push_back(browser_info);
}
// Continue any pending NewBrowserInfo request.
auto it =
pending_new_browser_info_map_.find(frame_host->GetGlobalFrameToken());
if (it != pending_new_browser_info_map_.end()) {
SendNewBrowserInfoResponse(browser_info, /*is_guest_view=*/false,
std::move(it->second->callback),
it->second->callback_runner);
pending_new_browser_info_map_.erase(it);
}
ContinueNewBrowserInfo(frame_host->GetGlobalFrameToken(), browser_info,
/*is_guest_view=*/false);
return browser_info;
}
@ -129,10 +130,7 @@ bool CefBrowserInfoManager::CanCreateWindow(
bool handled = false;
CefWindowInfo window_info;
#if BUILDFLAG(IS_WIN)
window_info.SetAsPopup(nullptr, CefString());
#endif
CefBrowserCreateParams::InitWindowInfo(&window_info, browser.get());
auto pending_popup = std::make_unique<CefBrowserInfoManager::PendingPopup>();
pending_popup->step = PendingPopup::CAN_CREATE_WINDOW;
@ -185,10 +183,12 @@ bool CefBrowserInfoManager::CanCreateWindow(
if (allow) {
CefBrowserCreateParams create_params;
create_params.MaybeSetWindowInfo(window_info);
create_params.MaybeSetWindowInfo(window_info, /*allow_alloy_style=*/true,
/*allow_chrome_style=*/true);
if (!handled) {
// Use default Browser creation if OnBeforePopup was unhandled.
// Use default Browser creation with Chrome style if OnBeforePopup was
// unhandled.
// TODO(chrome): Expose a mechanism for the client to choose default
// creation.
pending_popup->use_default_browser_creation = true;
@ -196,6 +196,10 @@ bool CefBrowserInfoManager::CanCreateWindow(
create_params.popup_with_views_hosted_opener = ShouldCreateViewsHostedPopup(
browser, pending_popup->use_default_browser_creation);
// Potentially use Alloy style with the Chrome runtime.
create_params.popup_with_alloy_style_opener = browser->IsAlloyStyle();
create_params.settings = pending_popup->settings;
create_params.client = pending_popup->client;
create_params.extra_info = pending_popup->extra_info;
@ -204,6 +208,11 @@ bool CefBrowserInfoManager::CanCreateWindow(
CefBrowserPlatformDelegate::Create(create_params);
CHECK(pending_popup->platform_delegate.get());
// Expect runtime style to match.
pending_popup->alloy_style = !create_params.IsChromeStyle();
CHECK_EQ(pending_popup->alloy_style,
pending_popup->platform_delegate->IsAlloyStyle());
// Between the calls to CanCreateWindow and GetCustomWebContentsView
// RenderViewHostImpl::CreateNewWindow() will call
// RenderProcessHostImpl::FilterURL() which, in the case of "javascript:"
@ -223,9 +232,9 @@ void CefBrowserInfoManager::GetCustomWebContentsView(
content::WebContentsView** view,
content::RenderViewHostDelegateView** delegate_view) {
CEF_REQUIRE_UIT();
REQUIRE_ALLOY_RUNTIME();
auto pending_popup = PopPendingPopup(PendingPopup::CAN_CREATE_WINDOW,
PendingPopup::CAN_CREATE_WINDOW,
opener_global_id, target_url);
DCHECK(pending_popup.get());
DCHECK(pending_popup->platform_delegate.get());
@ -249,13 +258,10 @@ void CefBrowserInfoManager::WebContentsCreated(
content::WebContents* new_contents) {
CEF_REQUIRE_UIT();
// GET_CUSTOM_WEB_CONTENTS_VIEW is only used with the alloy runtime.
const auto previous_step = cef::IsAlloyRuntimeEnabled()
? PendingPopup::GET_CUSTOM_WEB_CONTENTS_VIEW
: PendingPopup::CAN_CREATE_WINDOW;
auto pending_popup =
PopPendingPopup(previous_step, opener_global_id, target_url);
// GET_CUSTOM_WEB_CONTENTS_VIEW is only used with Alloy style.
auto pending_popup = PopPendingPopup(
PendingPopup::GET_CUSTOM_WEB_CONTENTS_VIEW,
PendingPopup::CAN_CREATE_WINDOW, opener_global_id, target_url);
DCHECK(pending_popup.get());
DCHECK(pending_popup->platform_delegate.get());
@ -264,8 +270,8 @@ void CefBrowserInfoManager::WebContentsCreated(
platform_delegate = std::move(pending_popup->platform_delegate);
extra_info = pending_popup->extra_info;
// AddWebContents (the next step) is only used with the Chrome runtime.
if (cef::IsChromeRuntimeEnabled()) {
// AddWebContents (the next step) is only used with Chrome style.
if (!pending_popup->alloy_style) {
pending_popup->step = PendingPopup::WEB_CONTENTS_CREATED;
pending_popup->new_contents = new_contents;
PushPendingPopup(std::move(pending_popup));
@ -280,8 +286,10 @@ bool CefBrowserInfoManager::AddWebContents(content::WebContents* new_contents) {
// chrome::AddWebContents is called directly from the Chrome UI (profile
// settings, etc).
auto pending_popup =
PopPendingPopup(PendingPopup::WEB_CONTENTS_CREATED, new_contents);
PopPendingPopup(PendingPopup::WEB_CONTENTS_CREATED,
PendingPopup::WEB_CONTENTS_CREATED, new_contents);
if (pending_popup) {
DCHECK(!pending_popup->alloy_style);
return !pending_popup->use_default_browser_creation;
}
@ -338,6 +346,56 @@ void CefBrowserInfoManager::OnGetNewBrowserInfo(
global_token, timeout_id),
kNewBrowserInfoResponseTimeoutMs);
}
// Check for PDF viewer or print preview frames.
CEF_POST_TASK(
CEF_UIT,
base::BindOnce(
&CefBrowserInfoManager::CheckExcludedNewBrowserInfoOnUIThread,
global_token));
}
// static
void CefBrowserInfoManager::CheckExcludedNewBrowserInfoOnUIThread(
const content::GlobalRenderFrameHostToken& global_token) {
CEF_REQUIRE_UIT();
if (!g_info_manager) {
return;
}
// May return nullptr for PDF renderer process.
auto* rfh = content::RenderFrameHost::FromFrameToken(global_token);
if (!rfh) {
return;
}
// PDF viewer and print preview create multiple renderer processes. Not all
// of those processes are currently tracked by CefBrowserInfo, so we also
// treat frames from untracked processes (like the print preview dialog) as
// guest views in the renderer process.
CefBrowserInfo* browser_info;
bool excluded_type;
GetFrameHost(rfh, /*prefer_speculative=*/true, &browser_info, &excluded_type);
if (browser_info && excluded_type) {
g_info_manager->ContinueNewBrowserInfo(global_token, browser_info,
/*is_guest_view=*/true);
}
}
void CefBrowserInfoManager::ContinueNewBrowserInfo(
const content::GlobalRenderFrameHostToken& global_token,
scoped_refptr<CefBrowserInfo> browser_info,
bool is_guest_view) {
base::AutoLock lock_scope(browser_info_lock_);
// Continue any pending NewBrowserInfo request.
auto it = pending_new_browser_info_map_.find(global_token);
if (it != pending_new_browser_info_map_.end()) {
SendNewBrowserInfoResponse(browser_info, is_guest_view,
std::move(it->second->callback),
it->second->callback_runner);
pending_new_browser_info_map_.erase(it);
}
}
void CefBrowserInfoManager::RemoveBrowserInfo(
@ -405,15 +463,14 @@ bool CefBrowserInfoManager::MaybeAllowNavigation(
CefRefPtr<CefBrowserHostBase>& browser_out) const {
CEF_REQUIRE_UIT();
bool is_guest_view = false;
auto browser = extensions::GetOwnerBrowserForHost(opener, &is_guest_view);
auto browser = CefBrowserHostBase::GetBrowserForHost(opener);
if (!browser) {
// Print preview uses a modal dialog where we don't own the WebContents.
// Allow that navigation to proceed.
return true;
}
if (!browser->MaybeAllowNavigation(opener, is_guest_view, params)) {
if (!browser->MaybeAllowNavigation(opener, params)) {
return false;
}
@ -434,6 +491,66 @@ bool CefBrowserInfoManager::ShouldCreateViewsHostedPopup(
!use_default_browser_creation;
}
// static
CefRefPtr<CefFrameHostImpl> CefBrowserInfoManager::GetFrameHost(
content::RenderFrameHost* rfh,
bool prefer_speculative,
CefBrowserInfo** browser_info,
bool* excluded_type) {
CEF_REQUIRE_UIT();
DCHECK(rfh);
const bool is_pdf_process = rfh->GetProcess()->IsPdf();
auto* web_contents = content::WebContents::FromRenderFrameHost(rfh);
const bool is_browser_process_guest =
extensions::IsBrowserPluginGuest(web_contents);
const bool is_print_preview_dialog =
extensions::IsPrintPreviewDialog(web_contents);
bool excluded =
is_pdf_process || is_browser_process_guest || is_print_preview_dialog;
bool guest_view = false;
CefRefPtr<CefFrameHostImpl> frame;
// A BrowserHost may match an excluded RFH type. Some associations are
// registered directly via CefBrowserInfo::MaybeCreateFrame and some are
// discovered indirectly via extensions::GetOwnerForGuestContents.
auto browser = CefBrowserHostBase::GetBrowserForHost(rfh);
if (browser) {
frame = browser->browser_info()->GetFrameForHost(rfh, &guest_view,
prefer_speculative);
excluded |= guest_view;
// A FrameHost should never exist for an excluded type.
DCHECK(!frame || !excluded);
}
if (browser_info) {
*browser_info = browser ? browser->browser_info().get() : nullptr;
}
if (excluded_type) {
*excluded_type = excluded;
}
if (VLOG_IS_ON(1)) {
const std::string& debug_string =
frame_util::GetFrameDebugString(rfh->GetGlobalFrameToken());
const bool is_main = rfh->GetParent() == nullptr;
VLOG(1) << "frame " << debug_string
<< " registered_guest_view=" << guest_view
<< ", pdf_process=" << is_pdf_process
<< ", browser_process_guest=" << is_browser_process_guest
<< ", print_preview_dialog=" << is_print_preview_dialog
<< ", main=" << is_main << (browser ? "" : ", has no BrowserHost")
<< (frame ? "" : ", has no FrameHost");
}
return frame;
}
CefBrowserInfoManager::BrowserInfoList
CefBrowserInfoManager::GetBrowserInfoList() {
base::AutoLock lock_scope(browser_info_lock_);
@ -490,16 +607,21 @@ void CefBrowserInfoManager::PushPendingPopup(
std::unique_ptr<CefBrowserInfoManager::PendingPopup>
CefBrowserInfoManager::PopPendingPopup(
PendingPopup::Step previous_step,
PendingPopup::Step previous_step_alloy,
PendingPopup::Step previous_step_chrome,
const content::GlobalRenderFrameHostId& opener_global_id,
const GURL& target_url) {
CEF_REQUIRE_UIT();
DCHECK(frame_util::IsValidGlobalId(opener_global_id));
DCHECK_LE(previous_step, PendingPopup::GET_CUSTOM_WEB_CONTENTS_VIEW);
DCHECK_LE(previous_step_alloy, PendingPopup::GET_CUSTOM_WEB_CONTENTS_VIEW);
DCHECK_LE(previous_step_chrome, PendingPopup::GET_CUSTOM_WEB_CONTENTS_VIEW);
PendingPopupList::iterator it = pending_popup_list_.begin();
for (; it != pending_popup_list_.end(); ++it) {
PendingPopup* popup = it->get();
const auto previous_step =
popup->alloy_style ? previous_step_alloy : previous_step_chrome;
if (popup->step == previous_step &&
popup->opener_global_id == opener_global_id &&
popup->target_url == target_url) {
@ -514,14 +636,19 @@ CefBrowserInfoManager::PopPendingPopup(
}
std::unique_ptr<CefBrowserInfoManager::PendingPopup>
CefBrowserInfoManager::PopPendingPopup(PendingPopup::Step previous_step,
CefBrowserInfoManager::PopPendingPopup(PendingPopup::Step previous_step_alloy,
PendingPopup::Step previous_step_chrome,
content::WebContents* new_contents) {
CEF_REQUIRE_UIT();
DCHECK_GE(previous_step, PendingPopup::WEB_CONTENTS_CREATED);
DCHECK_GE(previous_step_alloy, PendingPopup::WEB_CONTENTS_CREATED);
DCHECK_GE(previous_step_chrome, PendingPopup::WEB_CONTENTS_CREATED);
PendingPopupList::iterator it = pending_popup_list_.begin();
for (; it != pending_popup_list_.end(); ++it) {
PendingPopup* popup = it->get();
const auto previous_step =
popup->alloy_style ? previous_step_alloy : previous_step_chrome;
if (popup->step == previous_step && popup->new_contents == new_contents) {
// Transfer ownership of the pointer.
it->release();
@ -611,6 +738,7 @@ void CefBrowserInfoManager::SendNewBrowserInfoResponse(
params->browser_id = browser_info->browser_id();
params->is_windowless = browser_info->is_windowless();
params->is_popup = browser_info->is_popup();
params->print_preview_enabled = browser_info->print_preview_enabled();
auto extra_info = browser_info->extra_info();
if (extra_info) {
@ -655,15 +783,21 @@ void CefBrowserInfoManager::TimeoutNewBrowserInfoResponse(
return;
}
#if DCHECK_IS_ON()
// This method should never be called for a PDF renderer.
content::RenderProcessHost* process =
content::RenderProcessHost::FromID(global_token.child_id);
DCHECK(!process || !process->IsPdf());
#endif
// Cases where we expect to time out are:
// - With the Chrome runtime when chrome::AddWebContents or
// WebContents::Create are called directly from the Chrome UI (profile
// settings, etc). A RFH will exist without a matching CefBrowserHost.
// - When the PDF renderer is loaded in the print preview dialog. There will
// be no RFH in this case.
// Any additional cases should be debugged and, if possible,
// extensions::GetOwnerForGuestContents should be improved to find the
// associated CefBrowserHost.
const bool has_rfh =
!!content::RenderFrameHost::FromFrameToken(global_token);
LOG(ERROR) << "Timeout of new browser info response for frame "
<< frame_util::GetFrameDebugString(global_token);
<< frame_util::GetFrameDebugString(global_token)
<< " (has_rfh=" << has_rfh << ")";
CancelNewBrowserInfoResponse(pending_info.get());
g_info_manager->pending_new_browser_info_map_.erase(it);

View File

@ -58,6 +58,7 @@ class CefBrowserInfoManager : public content::RenderProcessHostObserver {
scoped_refptr<CefBrowserInfo> CreateBrowserInfo(
bool is_popup,
bool is_windowless,
bool print_preview_enabled,
CefRefPtr<CefDictionaryValue> extra_info);
// Called from WebContentsDelegate::WebContentsCreated when a new browser is
@ -67,6 +68,7 @@ class CefBrowserInfoManager : public content::RenderProcessHostObserver {
scoped_refptr<CefBrowserInfo> CreatePopupBrowserInfo(
content::WebContents* new_contents,
bool is_windowless,
bool print_preview_enabled,
CefRefPtr<CefDictionaryValue> extra_info);
// Called from ContentBrowserClient::CanCreateWindow. See comments on
@ -124,10 +126,10 @@ class CefBrowserInfoManager : public content::RenderProcessHostObserver {
// Returns the CefBrowserInfo matching the specified ID/token or nullptr if no
// match is found. It is allowed to add new callers of this method but
// consider using CefBrowserHostBase::GetBrowserForGlobalId/Token() or
// extensions::GetOwnerBrowserForGlobalId() instead. If |is_guest_view| is
// non-nullptr it will be set to true if the ID/token matches a guest view
// associated with the returned browser info instead of the browser itself.
// consider using CefBrowserHostBase::GetBrowserForGlobalId/Token() instead.
// If |is_guest_view| is non-nullptr it will be set to true if the ID/token
// matches a guest view associated with the returned browser info instead of
// the browser itself.
scoped_refptr<CefBrowserInfo> GetBrowserInfo(
const content::GlobalRenderFrameHostId& global_id,
bool* is_guest_view = nullptr);
@ -149,6 +151,15 @@ class CefBrowserInfoManager : public content::RenderProcessHostObserver {
static bool ShouldCreateViewsHostedPopup(CefRefPtr<CefBrowserHostBase> opener,
bool use_default_browser_creation);
// Returns the FrameHost associated with |rfh|, if any. |browser_info| and
// |excluded_type| will be populated if non-nullptr. An excluded type will not
// have a FrameHost but |browser_info| may still be populated if the
// association is known.
static CefRefPtr<CefFrameHostImpl> GetFrameHost(content::RenderFrameHost* rfh,
bool prefer_speculative,
CefBrowserInfo** browser_info,
bool* excluded_type);
private:
// RenderProcessHostObserver methods:
void RenderProcessHostDestroyed(content::RenderProcessHost* host) override;
@ -179,6 +190,9 @@ class CefBrowserInfoManager : public content::RenderProcessHostObserver {
WEB_CONTENTS_CREATED,
} step;
// True if this popup is Alloy style, otherwise Chrome style.
bool alloy_style;
// Initial state from ViewHostMsg_CreateWindow.
// |target_url| will be empty if a popup is created via window.open() and
// never navigated. For example: javascript:window.open();
@ -195,7 +209,7 @@ class CefBrowserInfoManager : public content::RenderProcessHostObserver {
std::unique_ptr<CefBrowserPlatformDelegate> platform_delegate;
// True if default Browser or tab creation should proceed from
// AddWebContents (chrome runtime only).
// AddWebContents (Chrome style only).
bool use_default_browser_creation = false;
// The newly created WebContents (set in WebContentsCreated).
@ -207,13 +221,15 @@ class CefBrowserInfoManager : public content::RenderProcessHostObserver {
// Used after CanCreateWindow is called.
std::unique_ptr<PendingPopup> PopPendingPopup(
PendingPopup::Step previous_step,
PendingPopup::Step previous_step_alloy,
PendingPopup::Step previous_step_chrome,
const content::GlobalRenderFrameHostId& opener_global_id,
const GURL& target_url);
// Used after WebContentsCreated is called.
std::unique_ptr<PendingPopup> PopPendingPopup(
PendingPopup::Step previous_step,
PendingPopup::Step previous_step_alloy,
PendingPopup::Step previous_step_chrome,
content::WebContents* new_contents);
// Retrieves the BrowserInfo matching the specified ID/token.
@ -224,6 +240,15 @@ class CefBrowserInfoManager : public content::RenderProcessHostObserver {
const content::GlobalRenderFrameHostToken& global_token,
bool* is_guest_view);
// Check for excluded frames that can be responded to immediately.
static void CheckExcludedNewBrowserInfoOnUIThread(
const content::GlobalRenderFrameHostToken& global_token);
void ContinueNewBrowserInfo(
const content::GlobalRenderFrameHostToken& global_token,
scoped_refptr<CefBrowserInfo> browser_info,
bool is_guest_view);
// Send the response for a pending OnGetNewBrowserInfo request.
static void SendNewBrowserInfoResponse(
scoped_refptr<CefBrowserInfo> browser_info,

View File

@ -4,12 +4,21 @@
#include "libcef/browser/browser_platform_delegate.h"
#include "libcef/browser/alloy/alloy_browser_host_impl.h"
#include "include/views/cef_window.h"
#include "include/views/cef_window_delegate.h"
#include "libcef/browser/browser_host_base.h"
#include "libcef/browser/thread_util.h"
#include "libcef/browser/views/browser_view_impl.h"
#include "libcef/common/cef_switches.h"
#include "base/command_line.h"
#include "base/logging.h"
#include "chrome/browser/platform_util.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/shell_integration.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "components/prefs/pref_service.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"
@ -28,6 +37,39 @@ void ExecuteExternalProtocol(const GURL& url) {
CEF_POST_TASK(TID_UI, base::BindOnce(&platform_util::OpenExternal, url));
}
// Default popup window delegate implementation.
class PopupWindowDelegate : public CefWindowDelegate {
public:
explicit PopupWindowDelegate(CefRefPtr<CefBrowserView> browser_view)
: browser_view_(browser_view) {}
PopupWindowDelegate(const PopupWindowDelegate&) = delete;
PopupWindowDelegate& operator=(const PopupWindowDelegate&) = delete;
void OnWindowCreated(CefRefPtr<CefWindow> window) override {
window->AddChildView(browser_view_);
window->Show();
browser_view_->RequestFocus();
}
void OnWindowDestroyed(CefRefPtr<CefWindow> window) override {
browser_view_ = nullptr;
}
bool CanClose(CefRefPtr<CefWindow> window) override {
CefRefPtr<CefBrowser> browser = browser_view_->GetBrowser();
if (browser) {
return browser->GetHost()->TryCloseBrowser();
}
return true;
}
private:
CefRefPtr<CefBrowserView> browser_view_;
IMPLEMENT_REFCOUNTING(PopupWindowDelegate);
};
} // namespace
CefBrowserPlatformDelegate::CefBrowserPlatformDelegate() = default;
@ -147,10 +189,14 @@ views::Widget* CefBrowserPlatformDelegate::GetWindowWidget() const {
}
CefRefPtr<CefBrowserView> CefBrowserPlatformDelegate::GetBrowserView() const {
DCHECK(false);
return nullptr;
}
void CefBrowserPlatformDelegate::SetBrowserView(
CefRefPtr<CefBrowserView> browser_view) {
DCHECK(false);
}
web_modal::WebContentsModalDialogHost*
CefBrowserPlatformDelegate::GetWebContentsModalDialogHost() const {
DCHECK(false);
@ -162,11 +208,79 @@ void CefBrowserPlatformDelegate::PopupWebContentsCreated(
CefRefPtr<CefClient> client,
content::WebContents* new_web_contents,
CefBrowserPlatformDelegate* new_platform_delegate,
bool is_devtools) {}
bool is_devtools) {
// Default popup handling may not be Views-hosted.
if (!new_platform_delegate->IsViewsHosted()) {
return;
}
CefRefPtr<CefBrowserViewDelegate> new_delegate;
CefRefPtr<CefBrowserViewDelegate> opener_delegate;
auto browser_view = GetBrowserView();
if (browser_view) {
// When |this| (the popup opener) is Views-hosted use the current delegate.
opener_delegate =
static_cast<CefBrowserViewImpl*>(browser_view.get())->delegate();
}
if (!opener_delegate) {
opener_delegate =
new_platform_delegate->GetDefaultBrowserViewDelegateForPopupOpener();
}
if (opener_delegate) {
new_delegate = opener_delegate->GetDelegateForPopupBrowserView(
browser_view, settings, client, is_devtools);
}
// Create a new BrowserView for the popup.
CefRefPtr<CefBrowserViewImpl> new_browser_view =
CefBrowserViewImpl::CreateForPopup(settings, new_delegate, is_devtools);
// Associate the PlatformDelegate with the new BrowserView.
new_platform_delegate->SetBrowserView(new_browser_view);
}
void CefBrowserPlatformDelegate::PopupBrowserCreated(
CefBrowserPlatformDelegate* new_platform_delegate,
CefBrowserHostBase* new_browser,
bool is_devtools) {}
bool is_devtools) {
// Default popup handling may not be Views-hosted.
if (!new_platform_delegate->IsViewsHosted()) {
return;
}
CefRefPtr<CefBrowserView> new_browser_view =
CefBrowserView::GetForBrowser(new_browser);
CHECK(new_browser_view);
bool popup_handled = false;
CefRefPtr<CefBrowserViewDelegate> opener_delegate;
auto browser_view = GetBrowserView();
if (browser_view) {
// When |this| (the popup opener) is Views-hosted use the current delegate.
opener_delegate =
static_cast<CefBrowserViewImpl*>(browser_view.get())->delegate();
}
if (!opener_delegate) {
opener_delegate =
new_platform_delegate->GetDefaultBrowserViewDelegateForPopupOpener();
}
if (opener_delegate) {
popup_handled = opener_delegate->OnPopupBrowserViewCreated(
browser_view, new_browser_view.get(), is_devtools);
}
if (!popup_handled) {
CefWindow::CreateTopLevelWindow(
new PopupWindowDelegate(new_browser_view.get()));
}
}
CefRefPtr<CefBrowserViewDelegate>
CefBrowserPlatformDelegate::GetDefaultBrowserViewDelegateForPopupOpener() {
return nullptr;
}
SkColor CefBrowserPlatformDelegate::GetBackgroundColor() const {
DCHECK(false);
@ -434,6 +548,34 @@ void CefBrowserPlatformDelegate::SetAccessibilityState(
}
bool CefBrowserPlatformDelegate::IsPrintPreviewSupported() const {
if (IsWindowless()) {
// Not supported with windowless rendering.
return false;
}
if (web_contents_) {
auto cef_browser_context = CefBrowserContext::FromBrowserContext(
web_contents_->GetBrowserContext());
if (cef_browser_context->AsProfile()->GetPrefs()->GetBoolean(
prefs::kPrintPreviewDisabled)) {
// Disabled on the Profile.
return false;
}
}
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
if (command_line->HasSwitch(switches::kDisablePrintPreview)) {
// Disabled explicitly via the command-line.
return false;
}
const bool default_disabled = IsAlloyStyle();
if (default_disabled &&
!command_line->HasSwitch(switches::kEnablePrintPreview)) {
// Default disabled and not enabled explicitly via the command-line.
return false;
}
return true;
}

View File

@ -88,7 +88,7 @@ class CefBrowserPlatformDelegate {
static std::unique_ptr<CefBrowserPlatformDelegate> Create(
const CefBrowserCreateParams& create_params);
// Called from AlloyBrowserHostImpl::Create.
// Called from BrowserHost::Create.
// Wait for the call to WebContentsCreated(owned=true) before taking ownership
// of the resulting WebContents object.
virtual content::WebContents* CreateWebContents(
@ -136,12 +136,12 @@ class CefBrowserPlatformDelegate {
// See WebContentsObserver documentation.
virtual void RenderViewReady();
// Called after the owning AlloyBrowserHostImpl is created. Will only be
// Called after the owning BrowserHost is created. Will only be
// called a single time per instance. Do not send any client notifications
// from this method.
virtual void BrowserCreated(CefBrowserHostBase* browser);
// Called from AlloyBrowserHostImpl::Create.
// Called from BrowserHost::Create.
virtual void CreateExtensionHost(const extensions::Extension* extension,
const GURL& url,
extensions::mojom::ViewType host_type);
@ -157,9 +157,9 @@ class CefBrowserPlatformDelegate {
// BrowserDestroyed().
virtual void NotifyBrowserDestroyed();
// Called before the owning AlloyBrowserHostImpl is destroyed. Will only be
// Called before the owning BrowserHost is destroyed. Will only be
// called a single time per instance. All references to the
// AlloyBrowserHostImpl and WebContents should be cleared when this method is
// BrowserHost and WebContents should be cleared when this method is
// called. Do not send any client notifications from this method.
virtual void BrowserDestroyed(CefBrowserHostBase* browser);
@ -182,35 +182,48 @@ class CefBrowserPlatformDelegate {
// rendering.
virtual views::Widget* GetWindowWidget() const;
// Returns the BrowserView associated with this browser. Only used with views-
// Returns the BrowserView associated with this browser. Only used with Views-
// based browsers.
virtual CefRefPtr<CefBrowserView> GetBrowserView() const;
// Sets the BrowserView associated with this browser. Only used with
// Views-based browsers.
virtual void SetBrowserView(CefRefPtr<CefBrowserView> browser_view);
// Returns the WebContentsModalDialogHost associated with this browser.
virtual web_modal::WebContentsModalDialogHost* GetWebContentsModalDialogHost()
const;
// Called after the WebContents have been created for a new popup browser
// parented to this browser but before the AlloyBrowserHostImpl is created for
// the popup. |is_devtools| will be true if the popup will host DevTools. This
// parented to this browser but before the BrowserHost is created for the
// popup. |is_devtools| will be true if the popup will host DevTools. This
// method will be called before WebContentsCreated() is called on
// |new_platform_delegate|. Do not make the new browser visible in this
// |new_platform_delegate|. Does not make the new browser visible in this
// callback.
virtual void PopupWebContentsCreated(
void PopupWebContentsCreated(
const CefBrowserSettings& settings,
CefRefPtr<CefClient> client,
content::WebContents* new_web_contents,
CefBrowserPlatformDelegate* new_platform_delegate,
bool is_devtools);
// Called after the AlloyBrowserHostImpl is created for a new popup browser
// parented to this browser. |is_devtools| will be true if the popup will host
// DevTools. This method will be called immediately after
// Called after the BrowserHost is created for a new popup browser parented to
// this browser. |is_devtools| will be true if the popup will host DevTools.
// This method will be called immediately after
// CefLifeSpanHandler::OnAfterCreated() for the popup browser. It is safe to
// make the new browser visible in this callback (for example, add the browser
// to a window and show it).
virtual void PopupBrowserCreated(CefBrowserHostBase* new_browser,
bool is_devtools);
void PopupBrowserCreated(CefBrowserPlatformDelegate* new_platform_delegate,
CefBrowserHostBase* new_browser,
bool is_devtools);
// Called from PopupWebContentsCreated/PopupBrowserCreated to retrieve the
// default BrowserViewDelegate in cases where this is a new Views-based popup
// and the opener is either not Views-based or doesn't implement the
// BrowserViewDelegate. Only implemented for specific configurations where
// special handling of new popups is required for proper functioning.
virtual CefRefPtr<CefBrowserViewDelegate>
GetDefaultBrowserViewDelegateForPopupOpener();
// Returns the background color for the browser. The alpha component will be
// either SK_AlphaTRANSPARENT or SK_AlphaOPAQUE (e.g. fully transparent or
@ -294,6 +307,11 @@ class CefBrowserPlatformDelegate {
// be called on multiple threads.
virtual bool IsViewsHosted() const;
// Returns the runtime style implemented by this delegate. May be called on
// multiple threads.
virtual bool IsAlloyStyle() const = 0;
bool IsChromeStyle() const { return !IsAlloyStyle(); }
// Returns true if this delegate implements a browser with external
// (client-provided) parent window. May be called on multiple threads.
virtual bool HasExternalParent() const;

View File

@ -18,7 +18,6 @@
#include "libcef/browser/chrome/views/chrome_child_window.h"
#include "libcef/browser/extensions/browser_platform_delegate_background.h"
#include "libcef/browser/views/browser_platform_delegate_views.h"
#include "libcef/features/runtime_checks.h"
#if BUILDFLAG(IS_WIN)
#include "libcef/browser/native/browser_platform_delegate_native_win.h"
@ -71,14 +70,11 @@ std::unique_ptr<CefBrowserPlatformDelegateOsr> CreateOSRDelegate(
// static
std::unique_ptr<CefBrowserPlatformDelegate> CefBrowserPlatformDelegate::Create(
const CefBrowserCreateParams& create_params) {
const bool is_windowless =
create_params.window_info &&
create_params.window_info->windowless_rendering_enabled &&
create_params.client && create_params.client->GetRenderHandler().get();
const bool is_windowless = create_params.IsWindowless();
const SkColor background_color = CefContext::Get()->GetBackgroundColor(
&create_params.settings, is_windowless ? STATE_ENABLED : STATE_DISABLED);
if (cef::IsChromeRuntimeEnabled()) {
if (create_params.IsChromeStyle()) {
CefWindowInfo window_info;
if (create_params.window_info) {
window_info = *create_params.window_info;
@ -124,8 +120,6 @@ std::unique_ptr<CefBrowserPlatformDelegate> CefBrowserPlatformDelegate::Create(
std::unique_ptr<CefBrowserPlatformDelegateNative> native_delegate =
CreateNativeDelegate(*create_params.window_info, background_color);
if (is_windowless) {
REQUIRE_ALLOY_RUNTIME();
const bool use_shared_texture =
create_params.window_info->shared_texture_enabled;

View File

@ -39,15 +39,16 @@ class BrowserDelegate : public content::WebContentsDelegate {
scoped_refptr<CreateParams> cef_params,
const Browser* opener);
~BrowserDelegate() override = default;
// Optionally override Browser creation in
// DevToolsWindow::CreateDevToolsBrowser. The returned Browser, if any, will
// take ownership of |devtools_contents|.
virtual Browser* CreateDevToolsBrowser(
static Browser* CreateDevToolsBrowser(
Profile* profile,
Browser* opener,
std::unique_ptr<content::WebContents>& devtools_contents) = 0;
content::WebContents* inspected_web_contents,
std::unique_ptr<content::WebContents>& devtools_contents);
~BrowserDelegate() override = default;
// Optionally override chrome::AddWebContents behavior. This is most often
// called via Browser::AddNewContents for new popup browsers and provides an

View File

@ -119,11 +119,6 @@ CefEventHandle CefBrowserPlatformDelegateChrome::GetEventHandle(
return native_delegate_->GetEventHandle(event);
}
bool CefBrowserPlatformDelegateChrome::IsPrintPreviewSupported() const {
return chrome_browser_ && !chrome_browser_->profile()->GetPrefs()->GetBoolean(
prefs::kPrintPreviewDisabled);
}
CefWindowHandle CefBrowserPlatformDelegateChrome::GetParentWindowHandle()
const {
return GetHostWindowHandle();
@ -143,6 +138,9 @@ gfx::NativeWindow CefBrowserPlatformDelegateChrome::GetNativeWindow() const {
if (chrome_browser_ && chrome_browser_->window()) {
return chrome_browser_->window()->GetNativeWindow();
}
DCHECK(false);
if (web_contents_) {
return web_contents_->GetTopLevelNativeWindow();
}
NOTIMPLEMENTED();
return gfx::NativeWindow();
}

View File

@ -42,7 +42,7 @@ class CefBrowserPlatformDelegateChrome
void ViewText(const std::string& text) override;
CefEventHandle GetEventHandle(
const content::NativeWebKeyboardEvent& event) const override;
bool IsPrintPreviewSupported() const override;
bool IsAlloyStyle() const override { return false; }
// CefBrowserPlatformDelegateNative::WindowlessHandler methods:
CefWindowHandle GetParentWindowHandle() const override;

View File

@ -11,11 +11,13 @@
#include "base/threading/thread_restrictions.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/history/history_service_factory.h"
#include "chrome/browser/prefs/session_startup_pref.h"
#include "chrome/browser/profiles/keep_alive/profile_keep_alive_types.h"
#include "chrome/browser/profiles/keep_alive/scoped_profile_keep_alive.h"
#include "chrome/browser/profiles/off_the_record_profile_impl.h"
#include "chrome/common/pref_names.h"
#include "components/history/core/browser/history_service.h"
namespace {
@ -139,6 +141,29 @@ void ChromeBrowserContext::Shutdown() {
}
}
void ChromeBrowserContext::AddVisitedURLs(
const GURL& url,
const std::vector<GURL>& redirect_chain,
ui::PageTransition transition) {
auto* profile = AsProfile();
if (profile->IsOffTheRecord()) {
// Don't persist state.
return;
}
// Called from DidFinishNavigation by Alloy style browsers. Chrome style
// browsers will handle this via HistoryTabHelper.
if (auto history_service = HistoryServiceFactory::GetForProfile(
profile, ServiceAccessType::IMPLICIT_ACCESS)) {
history::HistoryAddPageArgs add_page_args;
add_page_args.url = url;
add_page_args.redirects = redirect_chain;
add_page_args.transition = transition;
add_page_args.time = base::Time::Now();
history_service->AddPage(std::move(add_page_args));
}
}
void ChromeBrowserContext::ProfileCreated(CreateStatus status,
Profile* profile) {
Profile* parent_profile = nullptr;

View File

@ -34,6 +34,9 @@ class ChromeBrowserContext : public CefBrowserContext, public ProfileObserver {
bool IsInitialized() const override;
void StoreOrTriggerInitCallback(base::OnceClosure callback) override;
void Shutdown() override;
void AddVisitedURLs(const GURL& url,
const std::vector<GURL>& redirect_chain,
ui::PageTransition transition) override;
// ProfileObserver overrides.
void OnProfileWillBeDestroyed(Profile* profile) override;

View File

@ -12,6 +12,7 @@
#include "libcef/browser/browser_platform_delegate.h"
#include "libcef/browser/chrome/chrome_browser_context.h"
#include "libcef/browser/chrome/chrome_browser_host_impl.h"
#include "libcef/browser/chrome/chrome_devtools_window_runner.h"
#include "libcef/browser/chrome/views/chrome_browser_view.h"
#include "libcef/browser/chrome/views/chrome_child_window.h"
#include "libcef/browser/hang_monitor.h"
@ -53,23 +54,35 @@ ChromeBrowserDelegate::ChromeBrowserDelegate(
ChromeBrowserDelegate::~ChromeBrowserDelegate() = default;
// static
Browser* ChromeBrowserDelegate::CreateDevToolsBrowser(
Profile* profile,
Browser* opener,
content::WebContents* inspected_web_contents,
std::unique_ptr<content::WebContents>& devtools_contents) {
// |opener| is the same value that will be passed to the ChromeBrowserDelegate
// constructor for the new popup Browser. It may be nullptr in certain rare
// constructor for the new popup Browser. It may be nullptr in certain
// situations (e.g. if DevTools is launched for a WebContents that is not a
// Browser Tab). In that case, the popup browser host will instead be created
// via SetAsDelegate.
auto opener_browser_host =
// Browser Tab).
CefRefPtr<CefBrowserHostBase> opener_browser_host =
opener ? ChromeBrowserHostImpl::GetBrowserForBrowser(opener) : nullptr;
if (!opener_browser_host) {
return nullptr;
// |inspected_web_contents| may be an Alloy style browser.
opener_browser_host =
CefBrowserHostBase::GetBrowserForContents(inspected_web_contents);
if (!opener_browser_host) {
// The popup browser host will instead be created via SetAsDelegate.
return nullptr;
}
}
// We expect openers and popups to have the same Profile.
CHECK_EQ(opener->profile(), profile);
CHECK_EQ(
CefRequestContextImpl::GetProfile(opener_browser_host->request_context()),
profile);
if (opener) {
CHECK_EQ(opener->profile(), profile);
}
//
// 1. Get configuration settings from the user and create the new platform
@ -84,25 +97,26 @@ Browser* ChromeBrowserDelegate::CreateDevToolsBrowser(
CefBrowserCreateParams create_params;
CefWindowInfo window_info;
auto* devtools_window_runner = static_cast<ChromeDevToolsWindowRunner*>(
opener_browser_host->GetDevToolsWindowRunner());
auto pending_show_devtools_params =
devtools_window_runner->TakePendingParams();
// If |client| is empty, or if the user clears |client| in
// OnBeforeDevToolsPopup, we'll use the result of GetDefaultClient() later on
// in CreateBrowserHost().
if (pending_show_devtools_params_) {
if (pending_show_devtools_params) {
// Start with the params passed to CefBrowserHost::ShowDevTools().
create_params.client = pending_show_devtools_params_->client_;
create_params.settings = pending_show_devtools_params_->settings_;
window_info = pending_show_devtools_params_->window_info_;
// Pending params are only used a single time.
pending_show_devtools_params_.reset();
create_params.client = pending_show_devtools_params->client_;
create_params.settings = pending_show_devtools_params->settings_;
window_info = pending_show_devtools_params->window_info_;
} else {
// Start with the same client and settings as the opener.
create_params.client = opener_client;
create_params.settings = opener_browser_host->settings();
#if BUILDFLAG(IS_WIN)
window_info.SetAsPopup(nullptr, CefString());
#endif
CefBrowserCreateParams::InitWindowInfo(&window_info,
opener_browser_host.get());
}
// Start with the same extra info as the opener, for consistency with
@ -121,10 +135,14 @@ Browser* ChromeBrowserDelegate::CreateDevToolsBrowser(
create_params.settings, create_params.extra_info, &use_default_window);
}
if (opener_browser_host->platform_delegate()->HasExternalParent()) {
if (window_info.windowless_rendering_enabled) {
LOG(ERROR)
<< "Windowless rendering is not supported for this DevTools window";
} else if (opener_browser_host->platform_delegate()->HasExternalParent()) {
// A parent window handle for DevTools creation is only supported if the
// opener also has an external parent.
create_params.MaybeSetWindowInfo(window_info);
create_params.MaybeSetWindowInfo(window_info, /*allow_alloy_style=*/false,
/*allow_chrome_style=*/true);
} else if (chrome_child_window::HasParentHandle(window_info)) {
LOG(ERROR) << "Parent window handle not supported for this DevTools window";
}
@ -132,20 +150,24 @@ Browser* ChromeBrowserDelegate::CreateDevToolsBrowser(
create_params.popup_with_views_hosted_opener =
CefBrowserInfoManager::ShouldCreateViewsHostedPopup(opener_browser_host,
use_default_window);
create_params.popup_with_alloy_style_opener = false;
auto platform_delegate = CefBrowserPlatformDelegate::Create(create_params);
CHECK(platform_delegate);
// Expect runtime style to match.
CHECK(platform_delegate->IsChromeStyle());
//
// 2. Create the new browser host. Logical equivalent of WebContentsCreated()
// for normal popups.
// 2. Create the new browser host. Logical equivalent of
// WebContentsCreated() for normal popups.
//
// Create a new browser host that remains alive until the associated
// WebContents is destroyed. Associate that browser host with the WebContents
// and execute initial client callbacks. Deliver required information to the
// renderer process.
auto browser_host = CreateBrowserHostForPopup(
// WebContents is destroyed. Associate that browser host with the
// WebContents and execute initial client callbacks. Deliver required
// information to the renderer process.
auto browser_host = ChromeBrowserDelegate::CreateBrowserHostForPopup(
devtools_contents.get(), create_params.settings, create_params.client,
create_params.extra_info, std::move(platform_delegate),
/*is_devtools_popup=*/true, opener_browser_host);
@ -169,10 +191,10 @@ Browser* ChromeBrowserDelegate::CreateDevToolsBrowser(
std::move(chrome_params));
// Give the opener browser a reference to the new DevTools browser. Do this
// last because don't want the client to attempt access to the DevTools
// browser via opener browser methods (e.g. ShowDevTools, CloseDevTools, etc)
// while creation is still in progress.
opener_browser_host->SetDevToolsBrowserHost(browser_host->GetWeakPtr());
// last because we don't want the client to attempt access to the DevTools
// browser via opener browser methods (e.g. ShowDevTools, CloseDevTools,
// etc) while creation is still in progress.
devtools_window_runner->SetDevToolsBrowserHost(browser_host->GetWeakPtr());
auto browser = browser_host->browser();
CHECK(browser);
@ -203,7 +225,8 @@ std::unique_ptr<content::WebContents> ChromeBrowserDelegate::AddWebContents(
void ChromeBrowserDelegate::OnWebContentsCreated(
content::WebContents* new_contents) {
// Necessary to receive LoadingStateChanged calls during initial navigation.
// This will be called again in Browser::SetAsDelegate, which should be fine.
// This will be called again in Browser::SetAsDelegate, which should be
// fine.
new_contents->SetDelegate(browser_);
SetAsDelegate(new_contents, /*set_delegate=*/true);
@ -233,14 +256,18 @@ void ChromeBrowserDelegate::SetAsDelegate(content::WebContents* web_contents,
auto platform_delegate = CefBrowserPlatformDelegate::Create(create_params_);
CHECK(platform_delegate);
// Expect runtime style to match.
CHECK(platform_delegate->IsChromeStyle());
auto browser_info = CefBrowserInfoManager::GetInstance()->CreateBrowserInfo(
is_devtools_popup, /*is_windowless=*/false, create_params_.extra_info);
is_devtools_popup, /*is_windowless=*/false,
platform_delegate->IsPrintPreviewSupported(), create_params_.extra_info);
auto request_context_impl =
CefRequestContextImpl::GetOrCreateForRequestContext(
create_params_.request_context);
CreateBrowserHost(web_contents, create_params_.settings,
CreateBrowserHost(browser_, web_contents, create_params_.settings,
create_params_.client, std::move(platform_delegate),
browser_info, is_devtools_popup, /*opener=*/nullptr,
request_context_impl);
@ -477,9 +504,9 @@ void ChromeBrowserDelegate::WebContentsCreated(
}
// Create a new browser host that remains alive until the associated
// WebContents is destroyed. Associate that browser host with the WebContents
// and execute initial client callbacks. Deliver required information to the
// renderer process.
// WebContents is destroyed. Associate that browser host with the
// WebContents and execute initial client callbacks. Deliver required
// information to the renderer process.
CreateBrowserHostForPopup(new_contents, settings, client, extra_info,
std::move(platform_delegate),
/*is_devtools_popup=*/false, opener);
@ -592,20 +619,16 @@ bool ChromeBrowserDelegate::HandleKeyboardEvent(
return false;
}
void ChromeBrowserDelegate::SetPendingShowDevToolsParams(
std::unique_ptr<CefShowDevToolsParams> params) {
DCHECK(!pending_show_devtools_params_);
pending_show_devtools_params_ = std::move(params);
}
// static
CefRefPtr<ChromeBrowserHostImpl> ChromeBrowserDelegate::CreateBrowserHost(
Browser* browser,
content::WebContents* web_contents,
const CefBrowserSettings& settings,
CefRefPtr<CefClient> client,
std::unique_ptr<CefBrowserPlatformDelegate> platform_delegate,
scoped_refptr<CefBrowserInfo> browser_info,
bool is_devtools_popup,
CefRefPtr<ChromeBrowserHostImpl> opener,
CefRefPtr<CefBrowserHostBase> opener,
CefRefPtr<CefRequestContextImpl> request_context_impl) {
CEF_REQUIRE_UIT();
DCHECK(web_contents);
@ -615,6 +638,7 @@ CefRefPtr<ChromeBrowserHostImpl> ChromeBrowserDelegate::CreateBrowserHost(
// If |opener| is non-nullptr it must be a popup window.
DCHECK(!opener.get() || browser_info->is_popup());
DCHECK(browser || opener);
if (!client) {
if (auto app = CefAppManager::Get()->GetApplication()) {
@ -628,15 +652,20 @@ CefRefPtr<ChromeBrowserHostImpl> ChromeBrowserDelegate::CreateBrowserHost(
LOG(WARNING) << "Creating a chrome browser without a client";
}
// Get or create a ChromeBrowserContext for the browser Profile. Creation may
// be necessary when selecting a new or incognito Profile for the first time
// via the Chrome UI.
auto chrome_browser_context =
ChromeBrowserContext::GetOrCreateForProfile(browser_->profile());
Profile* profile =
browser ? browser->profile()
: Profile::FromBrowserContext(web_contents->GetBrowserContext());
// If the provided CefRequestContext matches the ChromeBrowserContext then use
// the provided one, as it will have the preferred CefRequestContextHandler.
// Otherwise, get or create a CefRequestContext that matches.
// Get or create a ChromeBrowserContext for the browser Profile. Creation
// may be necessary when selecting a new or incognito Profile for the first
// time via the Chrome UI.
auto* chrome_browser_context =
ChromeBrowserContext::GetOrCreateForProfile(profile);
// If the provided CefRequestContext matches the ChromeBrowserContext then
// use the provided one, as it will have the preferred
// CefRequestContextHandler. Otherwise, get or create a CefRequestContext
// that matches.
if (chrome_browser_context != request_context_impl->GetBrowserContext()) {
CefRefPtr<CefRequestContextHandler> handler;
if (auto app = CefAppManager::Get()->GetApplication()) {
@ -658,12 +687,13 @@ CefRefPtr<ChromeBrowserHostImpl> ChromeBrowserDelegate::CreateBrowserHost(
// The Chrome browser for a normal popup won't be created until
// AddNewContents().
if (!opener) {
browser_host->SetBrowser(browser_);
browser_host->SetBrowser(browser);
}
return browser_host;
}
// static
CefRefPtr<ChromeBrowserHostImpl>
ChromeBrowserDelegate::CreateBrowserHostForPopup(
content::WebContents* web_contents,
@ -672,10 +702,13 @@ ChromeBrowserDelegate::CreateBrowserHostForPopup(
CefRefPtr<CefDictionaryValue> extra_info,
std::unique_ptr<CefBrowserPlatformDelegate> platform_delegate,
bool is_devtools_popup,
CefRefPtr<ChromeBrowserHostImpl> opener) {
CefRefPtr<CefBrowserHostBase> opener) {
DCHECK(opener);
auto browser_info =
CefBrowserInfoManager::GetInstance()->CreatePopupBrowserInfo(
web_contents, /*is_windowless=*/false, extra_info);
web_contents, /*is_windowless=*/false,
platform_delegate->IsPrintPreviewSupported(), extra_info);
CHECK(browser_info->is_popup());
// Popups must share the same RequestContext as the parent.
@ -684,7 +717,7 @@ ChromeBrowserDelegate::CreateBrowserHostForPopup(
// We don't officially own |web_contents| until AddNewContents() is called.
// However, we need to install observers/delegates here.
return CreateBrowserHost(web_contents, settings, client,
return CreateBrowserHost(/*browser=*/nullptr, web_contents, settings, client,
std::move(platform_delegate), browser_info,
is_devtools_popup, opener, request_context_impl);
}
@ -750,4 +783,14 @@ std::unique_ptr<BrowserDelegate> BrowserDelegate::Create(
opener);
}
// static
Browser* BrowserDelegate::CreateDevToolsBrowser(
Profile* profile,
Browser* opener,
content::WebContents* inspected_web_contents,
std::unique_ptr<content::WebContents>& devtools_contents) {
return ChromeBrowserDelegate::CreateDevToolsBrowser(
profile, opener, inspected_web_contents, devtools_contents);
}
} // namespace cef

View File

@ -52,11 +52,13 @@ class ChromeBrowserDelegate : public cef::BrowserDelegate {
~ChromeBrowserDelegate() override;
// cef::BrowserDelegate methods:
Browser* CreateDevToolsBrowser(
static Browser* CreateDevToolsBrowser(
Profile* profile,
Browser* opener,
std::unique_ptr<content::WebContents>& devtools_contents) override;
content::WebContents* inspected_web_contents,
std::unique_ptr<content::WebContents>& devtools_contents);
// cef::BrowserDelegate methods:
std::unique_ptr<content::WebContents> AddWebContents(
std::unique_ptr<content::WebContents> new_contents) override;
void OnWebContentsCreated(content::WebContents* new_contents) override;
@ -121,30 +123,28 @@ class ChromeBrowserDelegate : public cef::BrowserDelegate {
content::WebContents* source,
const content::NativeWebKeyboardEvent& event) override;
void SetPendingShowDevToolsParams(
std::unique_ptr<CefShowDevToolsParams> params);
Browser* browser() const { return browser_; }
private:
CefRefPtr<ChromeBrowserHostImpl> CreateBrowserHost(
static CefRefPtr<ChromeBrowserHostImpl> CreateBrowserHost(
Browser* browser,
content::WebContents* web_contents,
const CefBrowserSettings& settings,
CefRefPtr<CefClient> client,
std::unique_ptr<CefBrowserPlatformDelegate> platform_delegate,
scoped_refptr<CefBrowserInfo> browser_info,
bool is_devtools_popup,
CefRefPtr<ChromeBrowserHostImpl> opener,
CefRefPtr<CefBrowserHostBase> opener,
CefRefPtr<CefRequestContextImpl> request_context_impl);
CefRefPtr<ChromeBrowserHostImpl> CreateBrowserHostForPopup(
static CefRefPtr<ChromeBrowserHostImpl> CreateBrowserHostForPopup(
content::WebContents* web_contents,
const CefBrowserSettings& settings,
CefRefPtr<CefClient> client,
CefRefPtr<CefDictionaryValue> extra_info,
std::unique_ptr<CefBrowserPlatformDelegate> platform_delegate,
bool is_devtools_popup,
CefRefPtr<ChromeBrowserHostImpl> opener);
CefRefPtr<CefBrowserHostBase> opener);
CefBrowserContentsDelegate* GetDelegateForWebContents(
content::WebContents* web_contents) const;
@ -166,8 +166,6 @@ class ChromeBrowserDelegate : public cef::BrowserDelegate {
std::optional<bool> show_status_bubble_;
std::optional<SkRegion> draggable_region_;
mutable std::optional<bool> frameless_pip_;
std::unique_ptr<CefShowDevToolsParams> pending_show_devtools_params_;
};
#endif // CEF_LIBCEF_BROWSER_CHROME_CHROME_BROWSER_DELEGATE_H_

View File

@ -6,7 +6,6 @@
#include "libcef/browser/browser_platform_delegate.h"
#include "libcef/browser/chrome/browser_platform_delegate_chrome.h"
#include "libcef/browser/chrome/chrome_browser_delegate.h"
#include "libcef/browser/thread_util.h"
#include "libcef/browser/views/browser_view_impl.h"
#include "libcef/common/net/url_util.h"
@ -14,7 +13,6 @@
#include "base/logging.h"
#include "base/notreached.h"
#include "chrome/browser/devtools/devtools_window.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/browser_navigator.h"
@ -57,36 +55,42 @@ CefRefPtr<ChromeBrowserHostImpl> ChromeBrowserHostImpl::Create(
return browser_host;
}
// static
CefRefPtr<ChromeBrowserHostImpl> ChromeBrowserHostImpl::FromBaseChecked(
CefRefPtr<CefBrowserHostBase> host_base) {
if (!host_base) {
return nullptr;
}
CHECK(host_base->IsChromeStyle());
return static_cast<ChromeBrowserHostImpl*>(host_base.get());
}
// static
CefRefPtr<ChromeBrowserHostImpl> ChromeBrowserHostImpl::GetBrowserForHost(
const content::RenderViewHost* host) {
REQUIRE_CHROME_RUNTIME();
auto browser = CefBrowserHostBase::GetBrowserForHost(host);
return static_cast<ChromeBrowserHostImpl*>(browser.get());
return FromBaseChecked(CefBrowserHostBase::GetBrowserForHost(host));
}
// static
CefRefPtr<ChromeBrowserHostImpl> ChromeBrowserHostImpl::GetBrowserForHost(
const content::RenderFrameHost* host) {
REQUIRE_CHROME_RUNTIME();
auto browser = CefBrowserHostBase::GetBrowserForHost(host);
return static_cast<ChromeBrowserHostImpl*>(browser.get());
return FromBaseChecked(CefBrowserHostBase::GetBrowserForHost(host));
}
// static
CefRefPtr<ChromeBrowserHostImpl> ChromeBrowserHostImpl::GetBrowserForContents(
const content::WebContents* contents) {
REQUIRE_CHROME_RUNTIME();
auto browser = CefBrowserHostBase::GetBrowserForContents(contents);
return static_cast<ChromeBrowserHostImpl*>(browser.get());
return FromBaseChecked(CefBrowserHostBase::GetBrowserForContents(contents));
}
// static
CefRefPtr<ChromeBrowserHostImpl> ChromeBrowserHostImpl::GetBrowserForGlobalId(
const content::GlobalRenderFrameHostId& global_id) {
REQUIRE_CHROME_RUNTIME();
auto browser = CefBrowserHostBase::GetBrowserForGlobalId(global_id);
return static_cast<ChromeBrowserHostImpl*>(browser.get());
return FromBaseChecked(CefBrowserHostBase::GetBrowserForGlobalId(global_id));
}
// static
@ -208,73 +212,6 @@ void ChromeBrowserHostImpl::StopFinding(bool clearSelection) {
NOTIMPLEMENTED();
}
void ChromeBrowserHostImpl::ShowDevToolsOnUIThread(
std::unique_ptr<CefShowDevToolsParams> params) {
CEF_REQUIRE_UIT();
if (!browser_) {
return;
}
auto* web_contents = GetWebContents();
if (!web_contents) {
return;
}
auto* profile = CefRequestContextImpl::GetProfile(request_context());
if (!DevToolsWindow::AllowDevToolsFor(profile, web_contents)) {
LOG(WARNING) << "DevTools is not allowed for this browser";
return;
}
auto inspect_element_at = params->inspect_element_at_;
if (!devtools_browser_host_) {
// Configure parameters for ChromeBrowserDelegate::CreateDevToolsBrowser
// which will be called indirectly to create the DevTools window.
auto chrome_browser_delegate =
static_cast<ChromeBrowserDelegate*>(browser_->cef_delegate());
chrome_browser_delegate->SetPendingShowDevToolsParams(std::move(params));
}
// Focus the existing DevTools window or create a new one.
if (!inspect_element_at.IsEmpty()) {
DevToolsWindow::InspectElement(web_contents->GetPrimaryMainFrame(),
inspect_element_at.x, inspect_element_at.y);
} else {
DevToolsWindow::OpenDevToolsWindow(web_contents, profile,
DevToolsOpenedByAction::kUnknown);
}
// The DevTools browser host should now exist.
DCHECK(devtools_browser_host_);
}
void ChromeBrowserHostImpl::CloseDevTools() {
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(CEF_UIT,
base::BindOnce(&ChromeBrowserHostImpl::CloseDevTools, this));
return;
}
if (devtools_browser_host_) {
devtools_browser_host_->TryCloseBrowser();
}
}
bool ChromeBrowserHostImpl::HasDevTools() {
if (!CEF_CURRENTLY_ON_UIT()) {
DCHECK(false) << "called on invalid thread";
return false;
}
return !!devtools_browser_host_;
}
bool ChromeBrowserHostImpl::IsWindowRenderingDisabled() {
return false;
}
void ChromeBrowserHostImpl::WasResized() {
NOTIMPLEMENTED();
}
@ -537,13 +474,13 @@ Browser* ChromeBrowserHostImpl::CreateBrowser(
void ChromeBrowserHostImpl::Attach(content::WebContents* web_contents,
bool is_devtools_popup,
CefRefPtr<ChromeBrowserHostImpl> opener) {
CefRefPtr<CefBrowserHostBase> opener) {
DCHECK(web_contents);
if (opener) {
// Give the opener browser's platform delegate an opportunity to modify the
// new browser's platform delegate.
opener->platform_delegate_->PopupWebContentsCreated(
opener->platform_delegate()->PopupWebContentsCreated(
settings_, client_, web_contents, platform_delegate_.get(),
is_devtools_popup);
}
@ -569,7 +506,8 @@ void ChromeBrowserHostImpl::Attach(content::WebContents* web_contents,
// CefBrowserHost::GetWindowHandle() will return kNullWindowHandle in
// OnAfterCreated(), which breaks client expectations (e.g. clients expect
// everything about the browser to be valid at that time).
opener->platform_delegate_->PopupBrowserCreated(this, is_devtools_popup);
opener->platform_delegate()->PopupBrowserCreated(platform_delegate_.get(),
this, is_devtools_popup);
}
// 2. Notify the browser's LifeSpanHandler. This must always be the first
@ -606,13 +544,6 @@ void ChromeBrowserHostImpl::SetBrowser(Browser* browser) {
}
}
void ChromeBrowserHostImpl::SetDevToolsBrowserHost(
base::WeakPtr<ChromeBrowserHostImpl> devtools_browser_host) {
CEF_REQUIRE_UIT();
DCHECK(!devtools_browser_host_);
devtools_browser_host_ = devtools_browser_host;
}
void ChromeBrowserHostImpl::WindowDestroyed() {
CEF_REQUIRE_UIT();
if (auto view = chrome_browser_view()) {

View File

@ -38,6 +38,11 @@ class ChromeBrowserHostImpl : public CefBrowserHostBase {
static CefRefPtr<ChromeBrowserHostImpl> Create(
const CefBrowserCreateParams& params);
// Safe (checked) conversion from CefBrowserHostBase to ChromeBrowserHostImpl.
// Use this method instead of static_cast.
static CefRefPtr<ChromeBrowserHostImpl> FromBaseChecked(
CefRefPtr<CefBrowserHostBase> host_base);
// Returns the browser associated with the specified RenderViewHost.
static CefRefPtr<ChromeBrowserHostImpl> GetBrowserForHost(
const content::RenderViewHost* host);
@ -62,6 +67,10 @@ class ChromeBrowserHostImpl : public CefBrowserHostBase {
// CefBrowserHostBase methods called from CefFrameHostImpl:
void OnSetFocus(cef_focus_source_t source) override;
// CefBrowserHostBase methods:
bool IsWindowless() const override { return false; }
bool IsAlloyStyle() const override { return false; }
// CefBrowserHost methods:
void CloseBrowser(bool force_close) override;
bool TryCloseBrowser() override;
@ -72,9 +81,7 @@ class ChromeBrowserHostImpl : public CefBrowserHostBase {
bool matchCase,
bool findNext) override;
void StopFinding(bool clearSelection) override;
void CloseDevTools() override;
bool HasDevTools() override;
bool IsWindowRenderingDisabled() override;
bool IsWindowRenderingDisabled() override { return false; }
void WasResized() override;
void WasHidden(bool hidden) override;
void NotifyScreenInfoChanged() override;
@ -124,8 +131,6 @@ class ChromeBrowserHostImpl : public CefBrowserHostBase {
protected:
bool Navigate(const content::OpenURLParams& params) override;
void ShowDevToolsOnUIThread(
std::unique_ptr<CefShowDevToolsParams> params) override;
private:
friend class ChromeBrowserDelegate;
@ -147,7 +152,7 @@ class ChromeBrowserHostImpl : public CefBrowserHostBase {
// created. Must be called on the UI thread.
void Attach(content::WebContents* web_contents,
bool is_devtools_popup,
CefRefPtr<ChromeBrowserHostImpl> opener);
CefRefPtr<CefBrowserHostBase> opener);
// Called from ChromeBrowserDelegate::AddNewContents to take ownership of a
// popup WebContents. |browser_create_params| may be empty for default Browser
@ -161,9 +166,6 @@ class ChromeBrowserHostImpl : public CefBrowserHostBase {
// before the new Browser is added. Must be called on the UI thread.
void SetBrowser(Browser* browser);
void SetDevToolsBrowserHost(
base::WeakPtr<ChromeBrowserHostImpl> devtools_browser_host);
// CefBrowserHostBase methods:
void WindowDestroyed() override;
bool WillBeDestroyed() const override;
@ -178,8 +180,6 @@ class ChromeBrowserHostImpl : public CefBrowserHostBase {
Browser* browser_ = nullptr;
CefWindowHandle host_window_handle_ = kNullWindowHandle;
base::WeakPtr<ChromeBrowserHostImpl> devtools_browser_host_;
base::WeakPtrFactory<ChromeBrowserHostImpl> weak_ptr_factory_{this};
};

View File

@ -4,6 +4,7 @@
#include "libcef/browser/chrome/chrome_browser_main_extra_parts_cef.h"
#include "libcef/browser/alloy/dialogs/alloy_constrained_window_views_client.h"
#include "libcef/browser/chrome/chrome_context_menu_handler.h"
#include "libcef/browser/chrome/chrome_startup_browser_creator.h"
#include "libcef/browser/context.h"
@ -13,6 +14,8 @@
#include "base/task/thread_pool.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/views/chrome_constrained_window_views_client.h"
#include "components/constrained_window/constrained_window_views.h"
#if BUILDFLAG(IS_LINUX)
#include "base/linux_util.h"
@ -67,7 +70,7 @@ void ChromeBrowserMainExtraPartsCef::PreMainMessageLoopRun() {
base::TaskShutdownBehavior::BLOCK_SHUTDOWN, base::MayBlock()});
scheme::RegisterWebUIControllerFactory();
context_menu::RegisterMenuCreatedCallback();
context_menu::RegisterCallbacks();
file_dialog_runner::RegisterFactory();
permission_prompt::RegisterCreateCallback();
@ -78,3 +81,9 @@ void ChromeBrowserMainExtraPartsCef::PreMainMessageLoopRun() {
}
#endif
}
void ChromeBrowserMainExtraPartsCef::ToolkitInitialized() {
// Override the default Chrome client.
SetConstrainedWindowViewsClient(CreateAlloyConstrainedWindowViewsClient(
CreateChromeConstrainedWindowViewsClient()));
}

View File

@ -44,6 +44,7 @@ class ChromeBrowserMainExtraPartsCef : public ChromeBrowserMainExtraParts {
void PostProfileInit(Profile* profile, bool is_initial_profile) override;
void PostBrowserStart() override;
void PreMainMessageLoopRun() override;
void ToolkitInitialized() override;
CefRefPtr<CefRequestContextImpl> global_request_context_;

View File

@ -8,10 +8,10 @@
#include <tuple>
#include "libcef/browser/browser_frame.h"
#include "libcef/browser/browser_host_base.h"
#include "libcef/browser/browser_info_manager.h"
#include "libcef/browser/browser_manager.h"
#include "libcef/browser/certificate_query.h"
#include "libcef/browser/chrome/chrome_browser_host_impl.h"
#include "libcef/browser/chrome/chrome_browser_main_extra_parts_cef.h"
#include "libcef/browser/context.h"
#include "libcef/browser/net/chrome_scheme_handler.h"
@ -43,6 +43,10 @@
#include "third_party/blink/public/common/web_preferences/web_preferences.h"
#include "third_party/blink/public/mojom/loader/resource_load_info.mojom-shared.h"
#if !BUILDFLAG(IS_MAC)
#include "libcef/browser/chrome/chrome_web_contents_view_delegate_cef.h"
#endif
namespace {
void HandleExternalProtocolHelper(
@ -210,7 +214,7 @@ void ChromeContentBrowserClientCef::OverrideWebkitPrefs(
ChromeContentBrowserClient::OverrideWebkitPrefs(web_contents, prefs);
SkColor base_background_color;
auto browser = ChromeBrowserHostImpl::GetBrowserForContents(web_contents);
auto browser = CefBrowserHostBase::GetBrowserForContents(web_contents);
if (browser) {
renderer_prefs::SetCefPrefs(browser->settings(), *prefs);
@ -471,6 +475,18 @@ void ChromeContentBrowserClientCef::RegisterBrowserInterfaceBindersForFrame(
map);
}
std::unique_ptr<content::WebContentsViewDelegate>
ChromeContentBrowserClientCef::GetWebContentsViewDelegate(
content::WebContents* web_contents) {
// This does more work than just creating the delegate, so we call it even
// though the result gets discarded.
ChromeContentBrowserClient::GetWebContentsViewDelegate(web_contents);
// Used to customize context menu behavior for Alloy style. Called during
// WebContents::Create() so we don't yet have an associated BrowserHost.
return CreateWebContentsViewDelegate(web_contents);
}
CefRefPtr<CefRequestContextImpl>
ChromeContentBrowserClientCef::request_context() const {
return browser_main_parts_->request_context();
@ -490,3 +506,15 @@ scoped_refptr<base::SingleThreadTaskRunner>
ChromeContentBrowserClientCef::user_blocking_task_runner() const {
return browser_main_parts_->user_blocking_task_runner();
}
#if !BUILDFLAG(IS_MAC)
// Defined in a separate .mm file on MacOS to work around
// ChromeWebContentsViewDelegateViewsMac containing ObjC references.
// static
std::unique_ptr<content::WebContentsViewDelegate>
ChromeContentBrowserClientCef::CreateWebContentsViewDelegate(
content::WebContents* web_contents) {
return std::make_unique<ChromeWebContentsViewDelegateCef>(web_contents);
}
#endif

View File

@ -11,6 +11,7 @@
#include "libcef/browser/request_context_impl.h"
#include "chrome/browser/chrome_content_browser_client.h"
#include "content/public/browser/web_contents_view_delegate.h"
class ChromeBrowserMainExtraPartsCef;
@ -126,6 +127,8 @@ class ChromeContentBrowserClientCef : public ChromeContentBrowserClient {
void RegisterBrowserInterfaceBindersForFrame(
content::RenderFrameHost* render_frame_host,
mojo::BinderMapWithContext<content::RenderFrameHost*>* map) override;
std::unique_ptr<content::WebContentsViewDelegate> GetWebContentsViewDelegate(
content::WebContents* web_contents) override;
CefRefPtr<CefRequestContextImpl> request_context() const;
@ -134,6 +137,9 @@ class ChromeContentBrowserClientCef : public ChromeContentBrowserClient {
scoped_refptr<base::SingleThreadTaskRunner> user_blocking_task_runner() const;
private:
static std::unique_ptr<content::WebContentsViewDelegate>
CreateWebContentsViewDelegate(content::WebContents* web_contents);
ChromeBrowserMainExtraPartsCef* browser_main_parts_ = nullptr;
};

View File

@ -0,0 +1,14 @@
// Copyright 2024 The Chromium Embedded Framework Authors.
// Portions copyright 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "libcef/browser/chrome/chrome_content_browser_client_cef.h"
#include "libcef/browser/chrome/chrome_web_contents_view_delegate_cef.h"
// static
std::unique_ptr<content::WebContentsViewDelegate> ChromeContentBrowserClientCef::CreateWebContentsViewDelegate(content::WebContents* web_contents) {
return std::make_unique<ChromeWebContentsViewDelegateCef>(web_contents);
}

View File

@ -4,6 +4,9 @@
#include "libcef/browser/chrome/chrome_context_menu_handler.h"
#include "base/memory/weak_ptr.h"
#include "libcef/browser/alloy/alloy_browser_host_impl.h"
#include "libcef/browser/browser_host_base.h"
#include "libcef/browser/context_menu_params_impl.h"
#include "libcef/browser/simple_menu_model_impl.h"
@ -14,6 +17,64 @@ namespace context_menu {
namespace {
constexpr int kInvalidCommandId = -1;
const cef_event_flags_t kEmptyEventFlags = static_cast<cef_event_flags_t>(0);
class CefRunContextMenuCallbackImpl : public CefRunContextMenuCallback {
public:
using Callback =
base::OnceCallback<void(int /*command_id*/, int /*event_flags*/)>;
explicit CefRunContextMenuCallbackImpl(Callback callback)
: callback_(std::move(callback)) {}
CefRunContextMenuCallbackImpl(const CefRunContextMenuCallbackImpl&) = delete;
CefRunContextMenuCallbackImpl& operator=(
const CefRunContextMenuCallbackImpl&) = delete;
~CefRunContextMenuCallbackImpl() override {
if (!callback_.is_null()) {
// The callback is still pending. Cancel it now.
if (CEF_CURRENTLY_ON_UIT()) {
RunNow(std::move(callback_), kInvalidCommandId, kEmptyEventFlags);
} else {
CEF_POST_TASK(CEF_UIT,
base::BindOnce(&CefRunContextMenuCallbackImpl::RunNow,
std::move(callback_), kInvalidCommandId,
kEmptyEventFlags));
}
}
}
void Continue(int command_id, cef_event_flags_t event_flags) override {
if (CEF_CURRENTLY_ON_UIT()) {
if (!callback_.is_null()) {
RunNow(std::move(callback_), command_id, event_flags);
callback_.Reset();
}
} else {
CEF_POST_TASK(CEF_UIT,
base::BindOnce(&CefRunContextMenuCallbackImpl::Continue,
this, command_id, event_flags));
}
}
void Cancel() override { Continue(kInvalidCommandId, kEmptyEventFlags); }
bool IsDisconnected() const { return callback_.is_null(); }
void Disconnect() { callback_.Reset(); }
private:
static void RunNow(Callback callback, int command_id, int event_flags) {
CEF_REQUIRE_UIT();
std::move(callback).Run(command_id, event_flags);
}
Callback callback_;
IMPLEMENT_REFCOUNTING(CefRunContextMenuCallbackImpl);
};
// Lifespan is controlled by RenderViewContextMenu.
class CefContextMenuObserver : public RenderViewContextMenuObserver,
public CefSimpleMenuModelImpl::StateDelegate {
@ -21,7 +82,10 @@ class CefContextMenuObserver : public RenderViewContextMenuObserver,
CefContextMenuObserver(RenderViewContextMenu* context_menu,
CefRefPtr<CefBrowserHostBase> browser,
CefRefPtr<CefContextMenuHandler> handler)
: context_menu_(context_menu), browser_(browser), handler_(handler) {}
: context_menu_(context_menu), browser_(browser), handler_(handler) {
// This remains valid until the next time a context menu is created.
browser_->set_context_menu_observer(this);
}
CefContextMenuObserver(const CefContextMenuObserver&) = delete;
CefContextMenuObserver& operator=(const CefContextMenuObserver&) = delete;
@ -130,6 +194,29 @@ class CefContextMenuObserver : public RenderViewContextMenuObserver,
}
}
bool HandleShow() {
if (model_->GetCount() == 0) {
return false;
}
CefRefPtr<CefRunContextMenuCallbackImpl> callbackImpl(
new CefRunContextMenuCallbackImpl(
base::BindOnce(&CefContextMenuObserver::ExecuteCommandCallback,
weak_ptr_factory_.GetWeakPtr())));
bool handled = handler_->RunContextMenu(browser_, GetFrame(), params_,
model_, callbackImpl.get());
if (!handled && callbackImpl->IsDisconnected()) {
LOG(ERROR) << "Should return true from RunContextMenu when executing the "
"callback";
handled = true;
}
if (!handled) {
callbackImpl->Disconnect();
}
return handled;
}
private:
struct ItemInfo {
ItemInfo() = default;
@ -169,6 +256,7 @@ class CefContextMenuObserver : public RenderViewContextMenuObserver,
// May return nullptr if the frame is destroyed while the menu is pending.
auto* rfh = context_menu_->GetRenderFrameHost();
if (rfh) {
// May return nullptr for guest views.
frame = browser_->GetFrameForHost(rfh);
}
if (!frame) {
@ -177,6 +265,14 @@ class CefContextMenuObserver : public RenderViewContextMenuObserver,
return frame;
}
void ExecuteCommandCallback(int command_id, int event_flags) {
if (command_id != kInvalidCommandId) {
context_menu_->ExecuteCommand(command_id, event_flags);
}
context_menu_->Cancel();
OnMenuClosed();
}
RenderViewContextMenu* const context_menu_;
CefRefPtr<CefBrowserHostBase> browser_;
CefRefPtr<CefContextMenuHandler> handler_;
@ -186,6 +282,8 @@ class CefContextMenuObserver : public RenderViewContextMenuObserver,
// Map of command_id to ItemInfo.
using ItemInfoMap = std::map<int, ItemInfo>;
ItemInfoMap iteminfomap_;
base::WeakPtrFactory<CefContextMenuObserver> weak_ptr_factory_{this};
};
std::unique_ptr<RenderViewContextMenuObserver> MenuCreatedCallback(
@ -199,16 +297,44 @@ std::unique_ptr<RenderViewContextMenuObserver> MenuCreatedCallback(
handler);
}
}
// Don't leave the old pointer, if any.
browser->set_context_menu_observer(nullptr);
}
return nullptr;
}
bool MenuShowHandlerCallback(RenderViewContextMenu* context_menu) {
auto browser = CefBrowserHostBase::GetBrowserForContents(
context_menu->source_web_contents());
if (browser && browser->context_menu_observer()) {
return static_cast<CefContextMenuObserver*>(
browser->context_menu_observer())
->HandleShow();
}
return false;
}
} // namespace
void RegisterMenuCreatedCallback() {
void RegisterCallbacks() {
RenderViewContextMenu::RegisterMenuCreatedCallback(
base::BindRepeating(&MenuCreatedCallback));
RenderViewContextMenu::RegisterMenuShowHandlerCallback(
base::BindRepeating(&MenuShowHandlerCallback));
}
bool HandleContextMenu(content::WebContents* opener,
const content::ContextMenuParams& params) {
auto browser = CefBrowserHostBase::GetBrowserForContents(opener);
if (browser && browser->IsAlloyStyle()) {
AlloyBrowserHostImpl::FromBaseChecked(browser)->ShowContextMenu(params);
return true;
}
// Continue with creating the RenderViewContextMenu.
return false;
}
} // namespace context_menu

View File

@ -6,10 +6,20 @@
#define CEF_LIBCEF_BROWSER_CHROME_CHROME_CONTEXT_MENU_HANDLER_H_
#pragma once
#include "content/public/browser/context_menu_params.h"
namespace content {
class WebContents;
}
namespace context_menu {
// Register the context menu created callback.
void RegisterMenuCreatedCallback();
// Register RenderViewContextMenu callbacks.
void RegisterCallbacks();
// Returns true if the menu was handled.
bool HandleContextMenu(content::WebContents* opener,
const content::ContextMenuParams& params);
} // namespace context_menu

View File

@ -0,0 +1,74 @@
// Copyright 2024 The Chromium Embedded Framework Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "libcef/browser/chrome/chrome_devtools_window_runner.h"
#include "libcef/browser/chrome/chrome_browser_host_impl.h"
#include "libcef/browser/request_context_impl.h"
#include "libcef/browser/thread_util.h"
#include "chrome/browser/devtools/devtools_window.h"
void ChromeDevToolsWindowRunner::ShowDevTools(
CefBrowserHostBase* opener,
std::unique_ptr<CefShowDevToolsParams> params) {
CEF_REQUIRE_UIT();
auto* web_contents = opener->GetWebContents();
if (!web_contents) {
return;
}
auto* profile = CefRequestContextImpl::GetProfile(opener->request_context());
if (!DevToolsWindow::AllowDevToolsFor(profile, web_contents)) {
LOG(WARNING) << "DevTools is not allowed for this browser";
return;
}
auto inspect_element_at = params->inspect_element_at_;
if (!browser_host_) {
// Configure parameters for ChromeBrowserDelegate::CreateDevToolsBrowser
// which will be called indirectly to create the DevTools window.
DCHECK(!pending_params_);
pending_params_ = std::move(params);
}
// Focus the existing DevTools window or create a new one.
if (!inspect_element_at.IsEmpty()) {
DevToolsWindow::InspectElement(web_contents->GetPrimaryMainFrame(),
inspect_element_at.x, inspect_element_at.y);
} else {
DevToolsWindow::OpenDevToolsWindow(web_contents, profile,
DevToolsOpenedByAction::kUnknown);
}
// The DevTools browser host should now exist.
DCHECK(browser_host_);
}
void ChromeDevToolsWindowRunner::CloseDevTools() {
CEF_REQUIRE_UIT();
if (browser_host_) {
browser_host_->TryCloseBrowser();
browser_host_ = nullptr;
}
}
bool ChromeDevToolsWindowRunner::HasDevTools() {
CEF_REQUIRE_UIT();
return !!browser_host_;
}
std::unique_ptr<CefShowDevToolsParams>
ChromeDevToolsWindowRunner::TakePendingParams() {
CEF_REQUIRE_UIT();
return std::move(pending_params_);
}
void ChromeDevToolsWindowRunner::SetDevToolsBrowserHost(
base::WeakPtr<ChromeBrowserHostImpl> browser_host) {
CEF_REQUIRE_UIT();
DCHECK(!browser_host_);
browser_host_ = browser_host;
}

View File

@ -0,0 +1,41 @@
// Copyright 2024 The Chromium Embedded Framework Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CEF_LIBCEF_BROWSER_CHROME_CHROME_DEVTOOLS_WINDOW_RUNNER_H_
#define CEF_LIBCEF_BROWSER_CHROME_CHROME_DEVTOOLS_WINDOW_RUNNER_H_
#pragma once
#include "libcef/browser/devtools/devtools_window_runner.h"
#include "base/memory/weak_ptr.h"
class ChromeBrowserHostImpl;
// Creates and runs a DevTools window instance. Only accessed on the UI thread.
class ChromeDevToolsWindowRunner : public CefDevToolsWindowRunner {
public:
ChromeDevToolsWindowRunner() = default;
ChromeDevToolsWindowRunner(const ChromeDevToolsWindowRunner&) = delete;
ChromeDevToolsWindowRunner& operator=(const ChromeDevToolsWindowRunner&) =
delete;
// CefDevToolsWindowRunner methods:
void ShowDevTools(CefBrowserHostBase* opener,
std::unique_ptr<CefShowDevToolsParams> params) override;
void CloseDevTools() override;
bool HasDevTools() override;
std::unique_ptr<CefShowDevToolsParams> TakePendingParams();
void SetDevToolsBrowserHost(
base::WeakPtr<ChromeBrowserHostImpl> browser_host);
private:
std::unique_ptr<CefShowDevToolsParams> pending_params_;
base::WeakPtr<ChromeBrowserHostImpl> browser_host_;
};
#endif // CEF_LIBCEF_BROWSER_CHROME_CHROME_DEVTOOLS_WINDOW_RUNNER_H_

View File

@ -0,0 +1,22 @@
// Copyright 2024 The Chromium Embedded Framework Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "libcef/browser/chrome/chrome_web_contents_view_delegate_cef.h"
#include "libcef/browser/chrome/chrome_context_menu_handler.h"
ChromeWebContentsViewDelegateCef::ChromeWebContentsViewDelegateCef(
content::WebContents* web_contents)
: ChromeWebContentsViewDelegateBase(web_contents),
web_contents_(web_contents) {}
void ChromeWebContentsViewDelegateCef::ShowContextMenu(
content::RenderFrameHost& render_frame_host,
const content::ContextMenuParams& params) {
if (context_menu::HandleContextMenu(web_contents_, params)) {
return;
}
ChromeWebContentsViewDelegateBase::ShowContextMenu(render_frame_host, params);
}

View File

@ -0,0 +1,37 @@
// Copyright 2024 The Chromium Embedded Framework Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CEF_LIBCEF_BROWSER_CHROME_CHROME_WEB_CONTENTS_VIEW_DELEGATE_CEF_H_
#define CEF_LIBCEF_BROWSER_CHROME_CHROME_WEB_CONTENTS_VIEW_DELEGATE_CEF_H_
#pragma once
#include "build/build_config.h"
#if BUILDFLAG(IS_MAC)
#include "chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views_mac.h"
using ChromeWebContentsViewDelegateBase = ChromeWebContentsViewDelegateViewsMac;
#else
#include "chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views.h"
using ChromeWebContentsViewDelegateBase = ChromeWebContentsViewDelegateViews;
#endif
class ChromeWebContentsViewDelegateCef
: public ChromeWebContentsViewDelegateBase {
public:
explicit ChromeWebContentsViewDelegateCef(content::WebContents* web_contents);
ChromeWebContentsViewDelegateCef(const ChromeWebContentsViewDelegateCef&) =
delete;
ChromeWebContentsViewDelegateCef& operator=(
const ChromeWebContentsViewDelegateCef&) = delete;
// WebContentsViewDelegate methods:
void ShowContextMenu(content::RenderFrameHost& render_frame_host,
const content::ContextMenuParams& params) override;
private:
content::WebContents* const web_contents_;
};
#endif // CEF_LIBCEF_BROWSER_CHROME_CHROME_WEB_CONTENTS_VIEW_DELEGATE_CEF_H_

View File

@ -0,0 +1,6 @@
// Copyright 2024 The Chromium Embedded Framework Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Work around ChromeWebContentsViewDelegateViewsMac containing ObjC references.
#include "libcef/browser/chrome/chrome_web_contents_view_delegate_cef.cc"

View File

@ -7,6 +7,7 @@
#include "libcef/browser/browser_host_base.h"
#include "libcef/browser/browser_info.h"
#include "libcef/browser/chrome/chrome_context_menu_handler.h"
#include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h"
@ -45,4 +46,15 @@ void ChromeMimeHandlerViewGuestDelegateCef::OnGuestDetached() {
web_contents->GetPrimaryMainFrame());
}
bool ChromeMimeHandlerViewGuestDelegateCef::HandleContextMenu(
content::RenderFrameHost& render_frame_host,
const content::ContextMenuParams& params) {
if (context_menu::HandleContextMenu(owner_web_contents_, params)) {
return true;
}
return ChromeMimeHandlerViewGuestDelegate::HandleContextMenu(
render_frame_host, params);
}
} // namespace extensions

View File

@ -26,6 +26,8 @@ class ChromeMimeHandlerViewGuestDelegateCef
// MimeHandlerViewGuestDelegate methods.
void OnGuestAttached() override;
void OnGuestDetached() override;
bool HandleContextMenu(content::RenderFrameHost& render_frame_host,
const content::ContextMenuParams& params) override;
private:
MimeHandlerViewGuest* guest_; // Owns us.

View File

@ -18,6 +18,11 @@ void CefBrowserPlatformDelegateChromeChildWindow::CloseHostWindow() {
native_delegate_->CloseHostWindow();
}
CefRefPtr<CefBrowserViewDelegate> CefBrowserPlatformDelegateChromeChildWindow::
GetDefaultBrowserViewDelegateForPopupOpener() {
return chrome_child_window::GetDefaultBrowserViewDelegateForPopupOpener();
}
void CefBrowserPlatformDelegateChromeChildWindow::SetFocus(bool focus) {
native_delegate_->SetFocus(focus);
}

View File

@ -17,6 +17,8 @@ class CefBrowserPlatformDelegateChromeChildWindow
// CefBrowserPlatformDelegate overrides.
void CloseHostWindow() override;
CefRefPtr<CefBrowserViewDelegate>
GetDefaultBrowserViewDelegateForPopupOpener() override;
void SetFocus(bool focus) override;
#if BUILDFLAG(IS_WIN) || (BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_MAC))

View File

@ -12,43 +12,6 @@
#include "components/zoom/zoom_controller.h"
#include "ui/views/widget/widget.h"
namespace {
// Default popup window delegate implementation.
class PopupWindowDelegate : public CefWindowDelegate {
public:
explicit PopupWindowDelegate(CefRefPtr<CefBrowserView> browser_view)
: browser_view_(browser_view) {}
PopupWindowDelegate(const PopupWindowDelegate&) = delete;
PopupWindowDelegate& operator=(const PopupWindowDelegate&) = delete;
void OnWindowCreated(CefRefPtr<CefWindow> window) override {
window->AddChildView(browser_view_);
window->Show();
browser_view_->RequestFocus();
}
void OnWindowDestroyed(CefRefPtr<CefWindow> window) override {
browser_view_ = nullptr;
}
bool CanClose(CefRefPtr<CefWindow> window) override {
CefRefPtr<CefBrowser> browser = browser_view_->GetBrowser();
if (browser) {
return browser->GetHost()->TryCloseBrowser();
}
return true;
}
private:
CefRefPtr<CefBrowserView> browser_view_;
IMPLEMENT_REFCOUNTING(PopupWindowDelegate);
};
} // namespace
CefBrowserPlatformDelegateChromeViews::CefBrowserPlatformDelegateChromeViews(
std::unique_ptr<CefBrowserPlatformDelegateNative> native_delegate,
CefRefPtr<CefBrowserViewImpl> browser_view)
@ -59,10 +22,10 @@ CefBrowserPlatformDelegateChromeViews::CefBrowserPlatformDelegateChromeViews(
}
void CefBrowserPlatformDelegateChromeViews::SetBrowserView(
CefRefPtr<CefBrowserViewImpl> browser_view) {
CefRefPtr<CefBrowserView> browser_view) {
DCHECK(!browser_view_);
DCHECK(browser_view);
browser_view_ = browser_view;
browser_view_ = static_cast<CefBrowserViewImpl*>(browser_view.get());
}
void CefBrowserPlatformDelegateChromeViews::WebContentsCreated(
@ -148,59 +111,6 @@ CefBrowserPlatformDelegateChromeViews::GetBrowserView() const {
return browser_view_.get();
}
void CefBrowserPlatformDelegateChromeViews::PopupWebContentsCreated(
const CefBrowserSettings& settings,
CefRefPtr<CefClient> client,
content::WebContents* new_web_contents,
CefBrowserPlatformDelegate* new_platform_delegate,
bool is_devtools) {
// Default popup handling may not be Views-hosted.
if (!new_platform_delegate->IsViewsHosted()) {
return;
}
auto* new_platform_delegate_impl =
static_cast<CefBrowserPlatformDelegateChromeViews*>(
new_platform_delegate);
CefRefPtr<CefBrowserViewDelegate> new_delegate;
if (browser_view_->delegate()) {
new_delegate = browser_view_->delegate()->GetDelegateForPopupBrowserView(
browser_view_.get(), settings, client, is_devtools);
}
// Create a new BrowserView for the popup.
CefRefPtr<CefBrowserViewImpl> new_browser_view =
CefBrowserViewImpl::CreateForPopup(settings, new_delegate);
// Associate the PlatformDelegate with the new BrowserView.
new_platform_delegate_impl->SetBrowserView(new_browser_view);
}
void CefBrowserPlatformDelegateChromeViews::PopupBrowserCreated(
CefBrowserHostBase* new_browser,
bool is_devtools) {
// Default popup handling may not be Views-hosted.
if (!new_browser->HasView()) {
return;
}
CefRefPtr<CefBrowserView> new_browser_view =
CefBrowserView::GetForBrowser(new_browser);
DCHECK(new_browser_view);
bool popup_handled = false;
if (browser_view_->delegate()) {
popup_handled = browser_view_->delegate()->OnPopupBrowserViewCreated(
browser_view_.get(), new_browser_view.get(), is_devtools);
}
if (!popup_handled) {
CefWindow::CreateTopLevelWindow(
new PopupWindowDelegate(new_browser_view.get()));
}
}
bool CefBrowserPlatformDelegateChromeViews::IsViewsHosted() const {
return true;
}

View File

@ -30,21 +30,12 @@ class CefBrowserPlatformDelegateChromeViews
CefWindowHandle GetHostWindowHandle() const override;
views::Widget* GetWindowWidget() const override;
CefRefPtr<CefBrowserView> GetBrowserView() const override;
void PopupWebContentsCreated(
const CefBrowserSettings& settings,
CefRefPtr<CefClient> client,
content::WebContents* new_web_contents,
CefBrowserPlatformDelegate* new_platform_delegate,
bool is_devtools) override;
void PopupBrowserCreated(CefBrowserHostBase* new_browser,
bool is_devtools) override;
void SetBrowserView(CefRefPtr<CefBrowserView> browser_view) override;
bool IsViewsHosted() const override;
CefRefPtr<CefBrowserViewImpl> browser_view() const { return browser_view_; }
private:
void SetBrowserView(CefRefPtr<CefBrowserViewImpl> browser_view);
CefWindowImpl* GetWindowImpl() const;
CefRefPtr<CefBrowserViewImpl> browser_view_;

View File

@ -107,6 +107,7 @@ class ChromeBrowserFrame : public BrowserFrame,
void Init(BrowserView* browser_view, std::unique_ptr<Browser> browser);
// CefWidget methods:
bool IsAlloyStyle() const override { return false; }
views::Widget* GetWidget() override { return this; }
const views::Widget* GetWidget() const override { return this; }
void Initialized() override;

View File

@ -54,9 +54,6 @@ void ChromeBrowserView::ViewHierarchyChanged(
void ChromeBrowserView::AddedToWidget() {
// Create the Browser and ChromeBrowserHostImpl.
// Results in a call to InitBrowser which calls ParentClass::AddedToWidget.
cef_browser_view_->OnBrowserViewAdded();
// Call after ChromeBrowserHostImpl creation.
cef_browser_view_->AddedToWidget();
}

View File

@ -8,6 +8,8 @@
#include "libcef/browser/views/browser_view_impl.h"
#include "libcef/browser/views/window_impl.h"
#include "ui/gfx/native_widget_types.h"
#if BUILDFLAG(IS_WIN)
#include "libcef/browser/native/browser_platform_delegate_native_win.h"
#include "ui/views/win/hwnd_util.h"
@ -15,6 +17,23 @@
namespace {
gfx::AcceleratedWidget GetParentWidget(const CefWindowInfo& window_info) {
#if !BUILDFLAG(IS_MAC)
return window_info.parent_window;
#else
// Chrome style is not supported with native parent on MacOS. See issue #3294.
return gfx::kNullAcceleratedWidget;
#endif
}
CefWindowHandle GetParentHandle(const CefWindowInfo& window_info) {
#if !BUILDFLAG(IS_MAC)
return window_info.parent_window;
#else
return window_info.parent_view;
#endif
}
class ChildWindowDelegate : public CefWindowDelegate {
public:
ChildWindowDelegate(const ChildWindowDelegate&) = delete;
@ -61,8 +80,7 @@ class ChildWindowDelegate : public CefWindowDelegate {
DCHECK(widget_hwnd);
// The native delegate needs state to perform some actions.
auto browser =
static_cast<CefBrowserHostBase*>(browser_view_->GetBrowser().get());
auto browser = CefBrowserHostBase::FromBrowser(browser_view_->GetBrowser());
auto platform_delegate = browser->platform_delegate();
DCHECK(platform_delegate->IsViewsHosted());
auto chrome_delegate =
@ -115,6 +133,8 @@ class ChildBrowserViewDelegate : public CefBrowserViewDelegate {
ChildBrowserViewDelegate(const ChildBrowserViewDelegate&) = delete;
ChildBrowserViewDelegate& operator=(const ChildBrowserViewDelegate&) = delete;
// |browser_view| will be nullptr when called for popups with non-Views-hosted
// opener.
CefRefPtr<CefBrowserViewDelegate> GetDelegateForPopupBrowserView(
CefRefPtr<CefBrowserView> browser_view,
const CefBrowserSettings& settings,
@ -123,11 +143,13 @@ class ChildBrowserViewDelegate : public CefBrowserViewDelegate {
return new ChildBrowserViewDelegate();
}
// |browser_view| will be nullptr when called for popups with non-Views-hosted
// opener.
bool OnPopupBrowserViewCreated(CefRefPtr<CefBrowserView> browser_view,
CefRefPtr<CefBrowserView> popup_browser_view,
bool is_devtools) override {
auto new_browser = static_cast<CefBrowserHostBase*>(
popup_browser_view->GetBrowser().get());
auto new_browser =
CefBrowserHostBase::FromBrowser(popup_browser_view->GetBrowser());
auto new_platform_delegate = new_browser->platform_delegate();
DCHECK(new_platform_delegate->IsViewsHosted());
auto new_platform_delegate_impl =
@ -136,8 +158,7 @@ class ChildBrowserViewDelegate : public CefBrowserViewDelegate {
const auto& window_info =
new_platform_delegate_impl->native_delegate()->window_info();
const auto parent_handle =
chrome_child_window::GetParentHandle(window_info);
const auto parent_handle = GetParentWidget(window_info);
if (parent_handle != gfx::kNullAcceleratedWidget) {
ChildWindowDelegate::Create(popup_browser_view, window_info,
parent_handle);
@ -158,15 +179,7 @@ class ChildBrowserViewDelegate : public CefBrowserViewDelegate {
namespace chrome_child_window {
bool HasParentHandle(const CefWindowInfo& window_info) {
return GetParentHandle(window_info) != gfx::kNullAcceleratedWidget;
}
gfx::AcceleratedWidget GetParentHandle(const CefWindowInfo& window_info) {
#if !BUILDFLAG(IS_MAC)
return window_info.parent_window;
#else
return gfx::kNullAcceleratedWidget;
#endif
return GetParentHandle(window_info) != kNullWindowHandle;
}
CefRefPtr<CefBrowserHostBase> MaybeCreateChildBrowser(
@ -181,7 +194,7 @@ CefRefPtr<CefBrowserHostBase> MaybeCreateChildBrowser(
return nullptr;
}
const auto parent_handle = GetParentHandle(*create_params.window_info);
const auto parent_handle = GetParentWidget(*create_params.window_info);
if (parent_handle == gfx::kNullAcceleratedWidget) {
return nullptr;
}
@ -195,7 +208,12 @@ CefRefPtr<CefBrowserHostBase> MaybeCreateChildBrowser(
ChildWindowDelegate::Create(browser_view, *create_params.window_info,
parent_handle);
return static_cast<CefBrowserHostBase*>(browser_view->GetBrowser().get());
return CefBrowserHostBase::FromBrowser(browser_view->GetBrowser());
}
CefRefPtr<CefBrowserViewDelegate>
GetDefaultBrowserViewDelegateForPopupOpener() {
return new ChildBrowserViewDelegate();
}
} // namespace chrome_child_window

View File

@ -6,19 +6,19 @@
#define CEF_LIBCEF_BROWSER_CHROME_VIEWS_CHROME_CHILD_WINDOW_H_
#pragma once
#include "include/views/cef_browser_view_delegate.h"
#include "libcef/browser/browser_host_base.h"
#include "ui/gfx/native_widget_types.h"
namespace chrome_child_window {
bool HasParentHandle(const CefWindowInfo& window_info);
gfx::AcceleratedWidget GetParentHandle(const CefWindowInfo& window_info);
// Called from CefBrowserHostBase::Create.
CefRefPtr<CefBrowserHostBase> MaybeCreateChildBrowser(
const CefBrowserCreateParams& create_params);
CefRefPtr<CefBrowserViewDelegate> GetDefaultBrowserViewDelegateForPopupOpener();
} // namespace chrome_child_window
#endif // CEF_LIBCEF_BROWSER_CHROME_VIEWS_CHROME_CHILD_WINDOW_H_

View File

@ -2,13 +2,11 @@
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
#include "libcef/browser/devtools/devtools_manager.h"
#include <memory>
#include "libcef/browser/devtools/devtools_protocol_manager.h"
#include "libcef/browser/browser_host_base.h"
#include "libcef/browser/devtools/devtools_controller.h"
#include "libcef/browser/devtools/devtools_frontend.h"
#include "libcef/features/runtime.h"
#include "libcef/browser/thread_util.h"
#include "content/public/browser/web_contents.h"
@ -99,55 +97,18 @@ class CefDevToolsRegistrationImpl : public CefRegistration,
} // namespace
CefDevToolsManager::CefDevToolsManager(CefBrowserHostBase* inspected_browser)
: inspected_browser_(inspected_browser), weak_ptr_factory_(this) {
CefDevToolsProtocolManager::CefDevToolsProtocolManager(
CefBrowserHostBase* inspected_browser)
: inspected_browser_(inspected_browser) {
CEF_REQUIRE_UIT();
}
CefDevToolsManager::~CefDevToolsManager() {
CefDevToolsProtocolManager::~CefDevToolsProtocolManager() {
CEF_REQUIRE_UIT();
}
void CefDevToolsManager::ShowDevTools(const CefWindowInfo& windowInfo,
CefRefPtr<CefClient> client,
const CefBrowserSettings& settings,
const CefPoint& inspect_element_at) {
CEF_REQUIRE_UIT();
if (devtools_frontend_) {
if (!inspect_element_at.IsEmpty()) {
devtools_frontend_->InspectElementAt(inspect_element_at.x,
inspect_element_at.y);
}
devtools_frontend_->Focus();
return;
}
if (cef::IsChromeRuntimeEnabled()) {
NOTIMPLEMENTED();
} else {
auto alloy_browser = static_cast<AlloyBrowserHostImpl*>(inspected_browser_);
devtools_frontend_ = CefDevToolsFrontend::Show(
alloy_browser, windowInfo, client, settings, inspect_element_at,
base::BindOnce(&CefDevToolsManager::OnFrontEndDestroyed,
weak_ptr_factory_.GetWeakPtr()));
}
}
void CefDevToolsManager::CloseDevTools() {
CEF_REQUIRE_UIT();
if (!devtools_frontend_) {
return;
}
devtools_frontend_->Close();
}
bool CefDevToolsManager::HasDevTools() {
CEF_REQUIRE_UIT();
return !!devtools_frontend_;
}
bool CefDevToolsManager::SendDevToolsMessage(const void* message,
size_t message_size) {
bool CefDevToolsProtocolManager::SendDevToolsMessage(const void* message,
size_t message_size) {
CEF_REQUIRE_UIT();
if (!message || message_size == 0) {
return false;
@ -161,7 +122,7 @@ bool CefDevToolsManager::SendDevToolsMessage(const void* message,
base::StringPiece(static_cast<const char*>(message), message_size));
}
int CefDevToolsManager::ExecuteDevToolsMethod(
int CefDevToolsProtocolManager::ExecuteDevToolsMethod(
int message_id,
const CefString& method,
CefRefPtr<CefDictionaryValue> params) {
@ -187,13 +148,13 @@ int CefDevToolsManager::ExecuteDevToolsMethod(
}
// static
CefRefPtr<CefRegistration> CefDevToolsManager::CreateRegistration(
CefRefPtr<CefRegistration> CefDevToolsProtocolManager::CreateRegistration(
CefRefPtr<CefDevToolsMessageObserver> observer) {
DCHECK(observer);
return new CefDevToolsRegistrationImpl(observer);
}
void CefDevToolsManager::InitializeRegistrationOnUIThread(
void CefDevToolsProtocolManager::InitializeRegistrationOnUIThread(
CefRefPtr<CefRegistration> registration) {
CEF_REQUIRE_UIT();
@ -205,11 +166,7 @@ void CefDevToolsManager::InitializeRegistrationOnUIThread(
->Initialize(inspected_browser_, devtools_controller_->GetWeakPtr());
}
void CefDevToolsManager::OnFrontEndDestroyed() {
devtools_frontend_ = nullptr;
}
bool CefDevToolsManager::EnsureController() {
bool CefDevToolsProtocolManager::EnsureController() {
if (!devtools_controller_) {
devtools_controller_ = std::make_unique<CefDevToolsController>(
inspected_browser_->contents_delegate()->web_contents());

View File

@ -2,41 +2,35 @@
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
#ifndef CEF_LIBCEF_BROWSER_DEVTOOLS_DEVTOOLS_MANAGER_H_
#define CEF_LIBCEF_BROWSER_DEVTOOLS_DEVTOOLS_MANAGER_H_
#ifndef CEF_LIBCEF_BROWSER_DEVTOOLS_DEVTOOLS_PROTOCOL_MANAGER_H_
#define CEF_LIBCEF_BROWSER_DEVTOOLS_DEVTOOLS_PROTOCOL_MANAGER_H_
#pragma once
#include <memory>
#include "include/cef_browser.h"
#include "base/memory/weak_ptr.h"
class CefBrowserHostBase;
class CefDevToolsController;
class CefDevToolsFrontend;
namespace content {
class WebContents;
}
// Manages DevTools instances. Methods must be called on the UI thread unless
// otherwise indicated.
class CefDevToolsManager {
// Manages DevTools protocol messages without an active frontend. Methods must
// be called on the UI thread unless otherwise indicated.
class CefDevToolsProtocolManager {
public:
// |inspected_browser| will outlive this object.
explicit CefDevToolsManager(CefBrowserHostBase* inspected_browser);
explicit CefDevToolsProtocolManager(CefBrowserHostBase* inspected_browser);
CefDevToolsManager(const CefDevToolsManager&) = delete;
CefDevToolsManager& operator=(const CefDevToolsManager&) = delete;
CefDevToolsProtocolManager(const CefDevToolsProtocolManager&) = delete;
CefDevToolsProtocolManager& operator=(const CefDevToolsProtocolManager&) =
delete;
~CefDevToolsManager();
~CefDevToolsProtocolManager();
// See CefBrowserHost methods of the same name for documentation.
void ShowDevTools(const CefWindowInfo& windowInfo,
CefRefPtr<CefClient> client,
const CefBrowserSettings& settings,
const CefPoint& inspect_element_at);
void CloseDevTools();
bool HasDevTools();
bool SendDevToolsMessage(const void* message, size_t message_size);
int ExecuteDevToolsMethod(int message_id,
const CefString& method,
@ -52,20 +46,11 @@ class CefDevToolsManager {
CefRefPtr<CefRegistration> registration);
private:
void OnFrontEndDestroyed();
bool EnsureController();
CefBrowserHostBase* const inspected_browser_;
// CefDevToolsFrontend will delete itself when the frontend WebContents is
// destroyed.
CefDevToolsFrontend* devtools_frontend_ = nullptr;
// Used for sending DevTools protocol messages without an active frontend.
std::unique_ptr<CefDevToolsController> devtools_controller_;
base::WeakPtrFactory<CefDevToolsManager> weak_ptr_factory_;
};
#endif // CEF_LIBCEF_BROWSER_DEVTOOLS_DEVTOOLS_MANAGER_H_
#endif // CEF_LIBCEF_BROWSER_DEVTOOLS_DEVTOOLS_PROTOCOL_MANAGER_H_

View File

@ -0,0 +1,47 @@
// Copyright 2024 The Chromium Embedded Framework Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CEF_LIBCEF_BROWSER_DEVTOOLS_DEVTOOLS_WINDOW_RUNNER_H_
#define CEF_LIBCEF_BROWSER_DEVTOOLS_DEVTOOLS_WINDOW_RUNNER_H_
#pragma once
#include <memory>
#include "include/cef_client.h"
class CefBrowserHostBase;
// Parameters passed to ShowDevTools.
struct CefShowDevToolsParams {
CefShowDevToolsParams(const CefWindowInfo& windowInfo,
CefRefPtr<CefClient> client,
const CefBrowserSettings& settings,
const CefPoint& inspect_element_at)
: window_info_(windowInfo),
client_(client),
settings_(settings),
inspect_element_at_(inspect_element_at) {}
CefWindowInfo window_info_;
CefRefPtr<CefClient> client_;
CefBrowserSettings settings_;
CefPoint inspect_element_at_;
};
// Creates and runs a DevTools window instance. Only accessed on the UI thread.
class CefDevToolsWindowRunner {
public:
// Creates the appropriate runner type based on the current runtime.
static std::unique_ptr<CefDevToolsWindowRunner> Create();
// See documentation on CefBrowserHost methods of the same name.
virtual void ShowDevTools(CefBrowserHostBase* opener,
std::unique_ptr<CefShowDevToolsParams> params) = 0;
virtual void CloseDevTools() = 0;
virtual bool HasDevTools() = 0;
virtual ~CefDevToolsWindowRunner() = default;
};
#endif // CEF_LIBCEF_BROWSER_DEVTOOLS_DEVTOOLS_WINDOW_RUNNER_H_

View File

@ -0,0 +1,17 @@
// Copyright 2024 The Chromium Embedded Framework Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "libcef/browser/devtools/devtools_window_runner.h"
#include "libcef/browser/alloy/devtools/alloy_devtools_window_runner.h"
#include "libcef/browser/chrome/chrome_devtools_window_runner.h"
#include "libcef/features/runtime.h"
// static
std::unique_ptr<CefDevToolsWindowRunner> CefDevToolsWindowRunner::Create() {
if (cef::IsChromeRuntimeEnabled()) {
return std::make_unique<ChromeDevToolsWindowRunner>();
}
return std::make_unique<AlloyDevToolsWindowRunner>();
}

View File

@ -6,11 +6,9 @@
#include "libcef/browser/alloy/alloy_browser_host_impl.h"
#include "libcef/browser/browser_context.h"
#include "libcef/browser/browser_host_base.h"
#include "libcef/browser/browser_info_manager.h"
#include "libcef/browser/thread_util.h"
#include "libcef/common/extensions/extensions_util.h"
#include "libcef/common/frame_util.h"
#include "libcef/features/runtime_checks.h"
#include "chrome/browser/browser_process.h"
@ -19,111 +17,60 @@
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_plugin_guest_manager.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_view_host.h"
#include "extensions/browser/extension_registry.h"
namespace extensions {
void GetAllGuestsForOwnerContents(content::WebContents* owner,
std::vector<content::WebContents*>* guests) {
content::BrowserPluginGuestManager* plugin_guest_manager =
owner->GetBrowserContext()->GetGuestManager();
plugin_guest_manager->ForEachGuest(
owner, [guests](content::WebContents* web_contents) {
guests->push_back(web_contents);
return false; // Continue iterating.
});
}
namespace {
content::WebContents* GetOwnerForGuestContents(content::WebContents* guest) {
content::WebContentsImpl* guest_impl =
static_cast<content::WebContentsImpl*>(guest);
content::WebContents* GetOwnerForBrowserPluginGuest(
const content::WebContents* guest) {
auto* guest_impl = static_cast<const content::WebContentsImpl*>(guest);
content::BrowserPluginGuest* plugin_guest =
guest_impl->GetBrowserPluginGuest();
if (plugin_guest) {
return plugin_guest->owner_web_contents();
}
return nullptr;
}
// Maybe it's a print preview dialog.
content::WebContents* GetInitiatorForPrintPreviewDialog(
const content::WebContents* guest) {
auto print_preview_controller =
g_browser_process->print_preview_dialog_controller();
return print_preview_controller->GetInitiator(guest);
return print_preview_controller->GetInitiator(
const_cast<content::WebContents*>(guest));
}
CefRefPtr<CefBrowserHostBase> GetOwnerBrowserForGlobalId(
const content::GlobalRenderFrameHostId& global_id,
bool* is_guest_view) {
if (CEF_CURRENTLY_ON_UIT()) {
// Use the non-thread-safe but potentially faster approach.
content::RenderFrameHost* host =
content::RenderFrameHost::FromID(global_id);
if (host) {
return GetOwnerBrowserForHost(host, is_guest_view);
}
return nullptr;
} else {
// Use the thread-safe approach.
scoped_refptr<CefBrowserInfo> info =
CefBrowserInfoManager::GetInstance()->GetBrowserInfo(global_id,
is_guest_view);
if (info.get()) {
CefRefPtr<CefBrowserHostBase> browser = info->browser();
if (!browser.get()) {
LOG(WARNING) << "Found browser id " << info->browser_id()
<< " but no browser object matching frame "
<< frame_util::GetFrameDebugString(global_id);
}
return browser;
}
return nullptr;
} // namespace
content::WebContents* GetOwnerForGuestContents(
const content::WebContents* guest) {
// Maybe it's a guest view. This occurs while loading the PDF viewer.
if (auto* owner = GetOwnerForBrowserPluginGuest(guest)) {
return owner;
}
// Maybe it's a print preview dialog. This occurs while loading the print
// preview dialog.
if (auto* initiator = GetInitiatorForPrintPreviewDialog(guest)) {
// Maybe the dialog is parented to a guest view. This occurs while loading
// the print preview dialog from inside the PDF viewer.
if (auto* owner = GetOwnerForBrowserPluginGuest(initiator)) {
return owner;
}
return initiator;
}
return nullptr;
}
CefRefPtr<CefBrowserHostBase> GetOwnerBrowserForHost(
content::RenderViewHost* host,
bool* is_guest_view) {
if (is_guest_view) {
*is_guest_view = false;
}
CefRefPtr<CefBrowserHostBase> browser =
CefBrowserHostBase::GetBrowserForHost(host);
if (!browser.get() && ExtensionsEnabled()) {
// Retrieve the owner browser, if any.
content::WebContents* owner = GetOwnerForGuestContents(
content::WebContents::FromRenderViewHost(host));
if (owner) {
browser = CefBrowserHostBase::GetBrowserForContents(owner);
if (browser.get() && is_guest_view) {
*is_guest_view = true;
}
}
}
return browser;
bool IsBrowserPluginGuest(const content::WebContents* web_contents) {
return !!GetOwnerForBrowserPluginGuest(web_contents);
}
CefRefPtr<CefBrowserHostBase> GetOwnerBrowserForHost(
content::RenderFrameHost* host,
bool* is_guest_view) {
if (is_guest_view) {
*is_guest_view = false;
}
CefRefPtr<CefBrowserHostBase> browser =
CefBrowserHostBase::GetBrowserForHost(host);
if (!browser.get() && ExtensionsEnabled()) {
// Retrieve the owner browser, if any.
content::WebContents* owner = GetOwnerForGuestContents(
content::WebContents::FromRenderFrameHost(host));
if (owner) {
browser = CefBrowserHostBase::GetBrowserForContents(owner);
if (browser.get() && is_guest_view) {
*is_guest_view = true;
}
}
}
return browser;
bool IsPrintPreviewDialog(const content::WebContents* web_contents) {
return !!GetInitiatorForPrintPreviewDialog(web_contents);
}
CefRefPtr<AlloyBrowserHostImpl> GetBrowserForTabId(
@ -141,8 +88,8 @@ CefRefPtr<AlloyBrowserHostImpl> GetBrowserForTabId(
for (const auto& browser_info :
CefBrowserInfoManager::GetInstance()->GetBrowserInfoList()) {
CefRefPtr<AlloyBrowserHostImpl> current_browser =
static_cast<AlloyBrowserHostImpl*>(browser_info->browser().get());
auto current_browser =
AlloyBrowserHostImpl::FromBaseChecked(browser_info->browser());
if (current_browser && current_browser->GetIdentifier() == tab_id) {
// Make sure we're operating in the same CefBrowserContext.
if (CefBrowserContext::FromBrowserContext(

View File

@ -13,45 +13,22 @@
namespace content {
class BrowserContext;
struct GlobalRenderFrameHostId;
class RenderFrameHost;
class RenderViewHost;
class WebContents;
} // namespace content
class CefBrowserHostBase;
class AlloyBrowserHostImpl;
namespace extensions {
class Extension;
// Populates |guests| with all guest WebContents with the specified |owner|.
void GetAllGuestsForOwnerContents(content::WebContents* owner,
std::vector<content::WebContents*>* guests);
// Returns the WebContents that owns the specified |guest|, if any.
content::WebContents* GetOwnerForGuestContents(content::WebContents* guest);
content::WebContents* GetOwnerForGuestContents(
const content::WebContents* guest);
// Returns the CefBrowserHostBase that owns the host identified by the specified
// global ID, if any. |is_guest_view| will be set to true if the ID
// matches a guest view associated with the returned browser instead of the
// browser itself.
CefRefPtr<CefBrowserHostBase> GetOwnerBrowserForGlobalId(
const content::GlobalRenderFrameHostId& global_id,
bool* is_guest_view);
// Returns the CefBrowserHostBase that owns the specified |host|, if any.
// |is_guest_view| will be set to true if the host matches a guest view
// associated with the returned browser instead of the browser itself.
// TODO(cef): Delete the RVH variant once the remaining use case
// (via AlloyContentBrowserClient::OverrideWebkitPrefs) has been removed.
CefRefPtr<CefBrowserHostBase> GetOwnerBrowserForHost(
content::RenderViewHost* host,
bool* is_guest_view);
CefRefPtr<CefBrowserHostBase> GetOwnerBrowserForHost(
content::RenderFrameHost* host,
bool* is_guest_view);
// Test for different types of guest contents.
bool IsBrowserPluginGuest(const content::WebContents* web_contents);
bool IsPrintPreviewDialog(const content::WebContents* web_contents);
// Returns the browser matching |tab_id| and |browser_context|. Returns false if
// |tab_id| is < 0 or a matching browser cannot be found within

View File

@ -28,9 +28,9 @@ bool CefBrowserPlatformDelegateBackground::CreateHostWindow() {
void CefBrowserPlatformDelegateBackground::CloseHostWindow() {
// No host window, so continue browser destruction now. Do it asynchronously
// so the call stack has a chance to unwind.
CEF_POST_TASK(CEF_UIT,
base::BindOnce(&AlloyBrowserHostImpl::WindowDestroyed,
static_cast<AlloyBrowserHostImpl*>(browser_)));
CEF_POST_TASK(
CEF_UIT, base::BindOnce(&AlloyBrowserHostImpl::WindowDestroyed,
AlloyBrowserHostImpl::FromBaseChecked(browser_)));
}
CefWindowHandle CefBrowserPlatformDelegateBackground::GetHostWindowHandle()

View File

@ -168,8 +168,8 @@ CefRefPtr<AlloyBrowserHostImpl> CefExtensionFunctionDetails::GetCurrentBrowser()
handler->GetActiveBrowser(GetCefExtension(), browser.get(),
function_->include_incognito_information());
if (active_browser && active_browser != browser) {
CefRefPtr<AlloyBrowserHostImpl> active_browser_impl =
static_cast<AlloyBrowserHostImpl*>(active_browser.get());
auto active_browser_impl = AlloyBrowserHostImpl::FromBaseChecked(
CefBrowserHostBase::FromBrowser(active_browser));
// Make sure we're operating in the same CefBrowserContext.
if (CefBrowserContext::FromBrowserContext(
@ -371,11 +371,9 @@ std::unique_ptr<api::tabs::Tab> CefExtensionFunctionDetails::OpenTab(
CefBrowserCreateParams create_params;
create_params.url = url.spec();
create_params.request_context = request_context;
create_params.window_info = std::make_unique<CefWindowInfo>();
#if BUILDFLAG(IS_WIN)
create_params.window_info->SetAsPopup(nullptr, CefString());
#endif
CefWindowInfo windowInfo;
CefBrowserCreateParams::InitWindowInfo(&windowInfo, active_browser.get());
// Start with the active browser's settings.
create_params.client = active_browser->GetClient();
@ -391,10 +389,12 @@ std::unique_ptr<api::tabs::Tab> CefExtensionFunctionDetails::OpenTab(
return nullptr;
}
create_params.MaybeSetWindowInfo(windowInfo, /*allow_alloy_style=*/true,
/*allow_chrome_style=*/false);
if (active_browser->is_views_hosted()) {
// The new browser will also be Views hosted.
create_params.popup_with_views_hosted_opener = true;
create_params.window_info.reset();
}
// Browser creation may fail under certain rare circumstances.

View File

@ -13,7 +13,7 @@
#include "libcef/browser/extensions/mime_handler_view_guest_delegate.h"
#include "base/memory/ptr_util.h"
#include "chrome/browser/printing/print_view_manager.h"
#include "chrome/browser/printing/printing_init.h"
#include "chrome/browser/ui/prefs/prefs_tab_helper.h"
#include "components/zoom/zoom_controller.h"
#include "extensions/browser/guest_view/extensions_guest_view_manager_delegate.h"
@ -47,7 +47,7 @@ CefExtensionsAPIClient::CreateMimeHandlerViewGuestDelegate(
void CefExtensionsAPIClient::AttachWebContentsHelpers(
content::WebContents* web_contents) const {
PrefsTabHelper::CreateForWebContents(web_contents);
printing::PrintViewManager::CreateForWebContents(web_contents);
printing::InitializePrintingForWebContents(web_contents);
// Used by the tabs extension API.
zoom::ZoomController::CreateForWebContents(web_contents);

View File

@ -5,11 +5,9 @@
#include "libcef/browser/file_dialog_runner.h"
#include "libcef/browser/browser_host_base.h"
#include "libcef/browser/extensions/browser_extensions_util.h"
#include "chrome/browser/file_select_helper.h"
#include "chrome/browser/ui/chrome_select_file_policy.h"
#include "libcef/browser/browser_host_base.h"
#include "ui/shell_dialogs/select_file_dialog_factory.h"
#include "ui/shell_dialogs/select_file_policy.h"
@ -69,8 +67,7 @@ class CefSelectFileDialog final : public ui::SelectFileDialog {
static_cast<ChromeSelectFilePolicy*>(select_file_policy_.get());
auto web_contents = chrome_policy->source_contents();
if (web_contents) {
browser_ = extensions::GetOwnerBrowserForHost(
web_contents->GetRenderViewHost(), nullptr);
browser_ = CefBrowserHostBase::GetBrowserForContents(web_contents);
}
if (!browser_) {
LOG(WARNING) << "No browser associated with SelectFilePolicy";

View File

@ -41,7 +41,7 @@ void ViewTextCallback(CefRefPtr<CefFrameHostImpl> frame,
std::move(response),
base::BindOnce(
[](CefRefPtr<CefBrowser> browser, const CefString& str) {
static_cast<CefBrowserHostBase*>(browser.get())->ViewText(str);
CefBrowserHostBase::FromBrowser(browser)->ViewText(str);
},
browser));
}
@ -674,7 +674,7 @@ void CefFrameHostImpl::FrameAttached(
base::BindOnce(&CefFrameHostImpl::OnRenderFrameDisconnect, this));
// Notify the renderer process that it can start sending messages.
render_frame_->FrameAttachedAck();
render_frame_->FrameAttachedAck(/*allow=*/true);
while (!queued_renderer_actions_.empty()) {
std::move(queued_renderer_actions_.front().second).Run(render_frame_);

View File

@ -10,7 +10,6 @@
#include "libcef/browser/browser_host_base.h"
#include "libcef/browser/extensions/browser_extensions_util.h"
#include "libcef/browser/thread_util.h"
#include "libcef/common/extensions/extensions_util.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
@ -72,12 +71,11 @@ javascript_dialogs::TabModalDialogManager* GetTabModalDialogManager(
// Try the owner WebContents if the dialog originates from a guest view such
// as the PDF viewer or Print Preview.
if (extensions::ExtensionsEnabled()) {
if (auto* owner_contents =
extensions::GetOwnerForGuestContents(web_contents)) {
return javascript_dialogs::TabModalDialogManager::FromWebContents(
owner_contents);
}
// This is safe to call even if Alloy extensions are disabled.
if (auto* owner_contents =
extensions::GetOwnerForGuestContents(web_contents)) {
return javascript_dialogs::TabModalDialogManager::FromWebContents(
owner_contents);
}
return nullptr;

View File

@ -50,6 +50,7 @@ class CefBrowserPlatformDelegateNativeMac
std::unique_ptr<CefJavaScriptDialogRunner> CreateJavaScriptDialogRunner()
override;
std::unique_ptr<CefMenuRunner> CreateMenuRunner() override;
bool IsPrintPreviewSupported() const override;
// CefBrowserPlatformDelegateNative methods:
content::NativeWebKeyboardEvent TranslateWebKeyEvent(

View File

@ -49,7 +49,7 @@
if (browser_) {
// Force the browser to be destroyed and release the reference added in
// PlatformCreateWindow().
static_cast<AlloyBrowserHostImpl*>(browser_)->WindowDestroyed();
AlloyBrowserHostImpl::FromBaseChecked(browser_)->WindowDestroyed();
}
}
@ -475,6 +475,13 @@ CefBrowserPlatformDelegateNativeMac::CreateMenuRunner() {
return base::WrapUnique(new CefMenuRunnerMac);
}
bool CefBrowserPlatformDelegateNativeMac::IsPrintPreviewSupported() const {
// MacOS with external parent can't support print preview because there is no
// gfx::NativeView or gfx::AcceleratedWidget. See related comments in
// AlloyWebContentsDialogHelper.
return false;
}
content::NativeWebKeyboardEvent
CefBrowserPlatformDelegateNativeMac::TranslateWebKeyEvent(
const CefKeyEvent& key_event) const {

View File

@ -573,7 +573,7 @@ LRESULT CALLBACK CefBrowserPlatformDelegateNativeWin::WndProc(HWND hwnd,
// Force the browser to be destroyed. This will result in a call to
// BrowserDestroyed() that will release the reference added in
// CreateHostWindow().
static_cast<AlloyBrowserHostImpl*>(browser)->WindowDestroyed();
AlloyBrowserHostImpl::FromBaseChecked(browser)->WindowDestroyed();
}
break;

Some files were not shown because too many files have changed in this diff Show More