Compare commits

...

47 Commits
5790 ... 4430

Author SHA1 Message Date
Marshall Greenblatt
19ba7216a0 Update to Chromium version 90.0.4430.212 2021-05-26 11:01:23 -04:00
Marshall Greenblatt
3c44b04c4e Restore support for CreateBrowserSync with NULL |request_context| (see issue #2969)
This was unintentionally lost during the Chrome runtime refactoring effort.
2021-05-20 15:17:13 -04:00
Marshall Greenblatt
7a604aacf4 Fix crash closing DevTools window (fixes issue #3111) 2021-05-05 12:50:21 -04:00
Marshall Greenblatt
f03d75a333 Fix crash in OnGuestDetached when unloading PDF (fixes issue #3121) 2021-05-04 13:34:02 -04:00
Marshall Greenblatt
c53c523f4d Restore async CreateBrowser behavior (fixes issue #3116, fixes issue #3118)
Restore the async CreateBrowser behavior that existed prior to commit 691c9c2
because executing synchronously (for example, from inside OnContextInitialized)
causes issues on MacOS and possibly other platforms.
2021-04-29 17:35:45 -04:00
Marshall Greenblatt
5c92ffb78d Update to Chromium version 90.0.4430.93 2021-04-28 21:46:42 -04:00
Marshall Greenblatt
044c82849e chrome: Support configuration of accept language (see issue #2969)
This change adds support for CEF settings configuration of accept_language_list.
If specified, this value will take precedence over the "intl.accept_languages"
preference which is controlled by chrome://settings/languages.
2021-04-28 14:32:30 -04:00
Marshall Greenblatt
02ae4597d8 chrome: Support configuration of user agent and locale (see issue #2969)
This change adds support for CefSettings and command-line configuration of
user_agent, user_agent_product (formerly product_version) and locale.
2021-04-27 12:49:17 -04:00
Marshall Greenblatt
f2f0bfbdb5 Windows: Disable iterator debugging for cef_sandbox builds (fixes issue #3109)
Iterator debugging has been disabled by default (_HAS_ITERATOR_DEBUGGING=0)
for CEF/Chromium builds using clang/LLVM since 2018. Inversely, it is enabled
by default (_ITERATOR_DEBUG_LEVEL=2) for the MSVC Debug build configuration.
In order to minimize configuration-related headaches for MSVC-based clients
we have been building the Debug cef_sandbox.lib with iterator debugging
enabled. Recently, we have identified a number of crashes that may be due to
bugs in current clang/LLVM or MSVC versions but in any case can be resolved by
disabling iterator debugging:

- Crash when loading chrome://sandbox.
- Crash if an application lists libraries that utilize iterators after
  cef_sandbox.lib in the linker order.

To resolve these crashes we will now disable iterator debugging by default
for the cef_sandbox.lib builds. Client applications that link cef_sandbox.lib
will now also need to build with iterator debugging disabled by setting
_HAS_ITERATOR_DEBUGGING=0 or _ITERATOR_DEBUG_LEVEL=0 in their project
configuration (this will be done for you if you use cef_variables.cmake from
the binary distribution).

In addition to the crash fixes mentioned above, this change also:

- Reduces the size of the Debug cef_sandbox.lib by ~10MB.
- May result in faster Debug executables (see https://crbug.com/539996).
2021-04-26 18:21:19 -04:00
Marshall Greenblatt
d330790ec6 ceftests: Add missing newline at end of file 2021-04-23 21:02:12 -04:00
Marshall Greenblatt
af832bf118 Linux: cefclient: Don't use std::make_unique which requires C++14 2021-04-23 21:02:00 -04:00
Marshall Greenblatt
cd9342c39f Update to Chromium version 90.0.4430.85 2021-04-22 21:12:14 -04:00
Marshall Greenblatt
74c66a3a43 Fix extension loading test failure 2021-04-22 13:41:29 -04:00
Marshall Greenblatt
f718c8947c Fix crash closing DevTools window (fixes issue #3111) 2021-04-20 12:18:26 -04:00
Marshall Greenblatt
c6a4331904 chrome: Support configuration of renderer prefs (see issue #2969) 2021-04-17 21:25:34 -04:00
Marshall Greenblatt
af0e86206a Update to Chromium version 90.0.4430.72 2021-04-15 17:34:45 -04:00
Marshall Greenblatt
e37ceabdf8 chrome: Don't rely on CREATE_STATUS_CREATED for disk-based profiles (see issue #2969) 2021-04-15 13:34:22 -04:00
Marshall Greenblatt
7823df5a45 cefclient: Fix slow loading of the Views image cache (see issue #2969) 2021-04-14 22:30:43 -04:00
Marshall Greenblatt
691c9c2dcc Wait for CefBrowserContext initialization (see issue #2969)
With the Chrome runtime, Profile initialization may be asynchronous. Code that
waited on CefBrowserContext creation now needs to wait on CefBrowserContext
initialization instead.
2021-04-14 21:05:50 -04:00
Marshall Greenblatt
c48a79756c Fix crash when navigating to an unregistered scheme (fixes issue #3105)
The policy->CanAccessDataForOrigin CHECK in NavigationRequest::
GetOriginForURLLoaderFactory was failing because unregistered schemes
(which are already considered non-standard schemes) didn't trigger the
registered non-standard scheme allowance that we previously added in
ChildProcessSecurityPolicyImpl::CanAccessDataForOrigin. This change
modifies GetOriginForURLLoaderFactory to always return an opaque/unique
origin for non-standard schemes resulting in unregistered and non-standard
schemes receiving the same treatment.

New test coverage has been added for this condition, and can be run with:
ceftests --gtest_filter=CorsTest.*CustomUnregistered*
2021-04-12 16:53:44 -04:00
Marshall Greenblatt
d4386da6c3 chrome: mac: Fix exception_port_.is_valid() failure (see issue #2969)
Fixes the following startup error:
FATAL:crashpad_client_mac.cc(499) Check failed: exception_port_.is_valid()
2021-04-11 21:46:35 -04:00
Marshall Greenblatt
8656f19907 mac: ceftests: Fix helper app linker errors (see issue #2969) 2021-04-11 21:45:34 -04:00
Marshall Greenblatt
df150f8ae0 chrome: Support usage of the Chrome toolbar from Views (see issue #2969) 2021-04-11 21:44:37 -04:00
Marshall Greenblatt
d98971fc9e chrome: Fix assertion when clicking the incognito profile button (see issue #2969)
Profile::IsIncognitoProfile() currently returns false for CEF incognito profiles
because they are not the primary OTR profile. At the same time, we don't
necessarily want IsIncognitoProfile() to return true for CEF profiles because,
among other things, that causes the BrowserView to apply the dark toolbar theme.
Instead, this change updates ProfileMenu expectations to support the CEF
incognito profiles without otherwise modifying the incognito behavior.

Note that the IsIncognitoProfile() implementation has recently changed in
https://crrev.com/7bf6eb2497 and the conclusions in this commit will likely need
to be revisited in an upcoming Chromium update.
2021-04-11 21:41:25 -04:00
Marshall Greenblatt
10b7a443cb chrome: Fix FrameTest and RequestHandlerTest failures (see issue #2969) 2021-04-09 22:26:09 -04:00
Marshall Greenblatt
fe5b0df2fa chrome: Fix PreferenceTest failures (see issue #2969) 2021-04-09 22:04:35 -04:00
Marshall Greenblatt
5bfcfaab73 Move cookieable scheme configuration to settings (see issue #2969)
The Chrome runtime requires that cookieable scheme information be available
at Profile initialization time because it also triggers NetworkContext creation
at the same time. To make this possible, and to avoid various race conditions
when setting state, the cookieable scheme configuration has been added as
|cookieable_schemes_list| and |cookieable_schemes_exclude_defaults| in
CefSettings and CefBrowserContextSettings. The CefCookieManager::
SetSupportedSchemes and CefBrowserProcessHandler::GetCookieableSchemes methods
are no longer required and have been removed.

This change also modifies chrome to delay OffTheRecordProfileImpl initialization
so that |ChromeBrowserContext::profile_| can be set before
ChromeContentBrowserClientCef::ConfigureNetworkContextParams calls
CefBrowserContext::FromBrowserContext to retrieve the ChromeBrowserContext
and associated cookieable scheme information. Otherwise, the
ChromeBrowserContext will not be matched and the NetworkContext will not be
configured correctly.

The CookieTest suite now passes with the Chrome runtime enabled.
2021-04-09 15:54:31 -04:00
Marshall Greenblatt
f048a5ddba Fix server thread assertion on CEF shutdown (see issue #2969)
The server thread was not guaranteed to be released in the correct scope on
CEF shutdown. This resulted in occasional thread_restrictions assertions on
ceftests shutdown after running the URLRequestTest suite with the Chrome
runtime enabled.
2021-04-09 15:53:45 -04:00
Marshall Greenblatt
9f05dc2447 chrome: Support customization of context menus (see issue #2969) 2021-04-08 19:43:21 -04:00
Marshall Greenblatt
4d20de09f3 Fix URL rewrite on browser creation (see issue #2969)
The WebUITest suite now passes with the Chrome runtime enabled.
2021-04-07 19:23:47 -04:00
Marshall Greenblatt
c04a578821 Avoid potential use-after-free of CefIOThreadState (see issue #2969)
The problem occured while executing multiple URLRequestTest with the Chrome
runtime.
2021-04-07 19:23:41 -04:00
Marshall Greenblatt
44829818b0 chrome: Support client-created request contexts (see issue #2969)
RequestContextTest and URLRequestTest suites now pass with the Chrome runtime
enabled.
2021-04-07 19:22:55 -04:00
Marshall Greenblatt
cd40496573 chrome: Fix CorsTest.RedirectPost307HttpSchemeToCustomNonStandardScheme failure (see issue #2969) 2021-04-05 15:57:07 -04:00
Marshall Greenblatt
210c1d6b4f chrome: Fix NavigationTest and ResourceRequestHandlerTest failures (see issue #2969) 2021-04-05 15:57:00 -04:00
Marshall Greenblatt
c04592e2a7 chrome: Add support for reparenting of popups with Views (see issue #2969) 2021-04-05 15:55:45 -04:00
Marshall Greenblatt
6ad29642e2 Update to Chromium version 90.0.4430.51 2021-04-01 19:48:06 -04:00
Marshall Greenblatt
1b36d3538c Customize the 'platform' crash key value for ARM builds (see issue #2981, see issue #2773) 2021-03-31 11:05:18 -04:00
Marshall Greenblatt
d399c7220a cefclient: Simplify ClientPrintHandlerGtk for single browser usage (see issue #2196) 2021-03-30 12:51:49 -04:00
Marshall Greenblatt
1cd3f8a3af Move GetPrintHandler to CefClient (see issue #2196)
This new location is preferred because we now know the associated CefBrowser
for all CefPrintHandler callbacks.
2021-03-30 12:30:04 -04:00
Marshall Greenblatt
35a360fe66 Remove CefBrowserSettings.web_security (fixes issue #3058) 2021-03-25 13:08:46 -04:00
Marshall Greenblatt
2ecefdf30b Fix crash in MediaRouterEnabled due to missing pref registration (see issue #2900) 2021-03-24 15:14:29 -04:00
Corentin Dumont
0ad85c19aa Windows: Fix out-of-sync timestamps in OSR mode (fixes issue #3102) 2021-03-23 16:14:01 -04:00
Marshall Greenblatt
1232df3646 Fix potential use-after-free of V8TrackArrayBuffer (fixes issue #3074) 2021-03-23 15:58:17 -04:00
Marshall Greenblatt
dc12a89f28 Revert "Fix potential use-after-free of V8TrackArrayBuffer (fixes issue #3074)"
This reverts commit 8d23e96edf.
2021-03-22 19:45:34 -04:00
Marshall Greenblatt
4011b1e2ab Mac: Fix "fatal error: 'include/cef_pack_resources.h' file not found"
This occurs on a clean build of the ceftests target.
2021-03-22 19:45:21 -04:00
Marshall Greenblatt
8d23e96edf Fix potential use-after-free of V8TrackArrayBuffer (fixes issue #3074) 2021-03-22 13:55:18 -04:00
Marshall Greenblatt
2e4c4750b6 Update to Chromium version 90.0.4430.30 2021-03-19 10:21:25 -04:00
208 changed files with 4934 additions and 1827 deletions

View File

@@ -461,6 +461,8 @@ static_library("libcef_static") {
"libcef/browser/chrome/chrome_browser_main_extra_parts_cef.h",
"libcef/browser/chrome/chrome_content_browser_client_cef.cc",
"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_crash_reporter_client_stub.cc",
"libcef/browser/context.cc",
"libcef/browser/context.h",
@@ -637,6 +639,8 @@ static_library("libcef_static") {
"libcef/browser/scheme_impl.cc",
"libcef/browser/server_impl.cc",
"libcef/browser/server_impl.h",
"libcef/browser/simple_menu_model_impl.cc",
"libcef/browser/simple_menu_model_impl.h",
"libcef/browser/speech_recognition_manager_delegate.cc",
"libcef/browser/speech_recognition_manager_delegate.h",
"libcef/browser/ssl_host_state_delegate.cc",
@@ -716,6 +720,8 @@ static_library("libcef_static") {
"libcef/common/net/upload_data.h",
"libcef/common/net/upload_element.cc",
"libcef/common/net/upload_element.h",
"libcef/common/net/url_util.cc",
"libcef/common/net/url_util.h",
"libcef/common/net_service/net_service_util.cc",
"libcef/common/net_service/net_service_util.h",
"libcef/common/parser_impl.cc",
@@ -1064,6 +1070,10 @@ static_library("libcef_static") {
"libcef/browser/chrome/views/chrome_browser_frame.h",
"libcef/browser/chrome/views/chrome_browser_view.cc",
"libcef/browser/chrome/views/chrome_browser_view.h",
"libcef/browser/chrome/views/toolbar_view_impl.cc",
"libcef/browser/chrome/views/toolbar_view_impl.h",
"libcef/browser/chrome/views/toolbar_view_view.cc",
"libcef/browser/chrome/views/toolbar_view_view.h",
"libcef/browser/native/window_delegate_view.cc",
"libcef/browser/native/window_delegate_view.h",
"libcef/browser/views/basic_label_button_impl.cc",
@@ -1774,6 +1784,7 @@ if (is_mac) {
public_deps = [ ":libcef_dll_wrapper" ]
deps = [
":cef_make_headers",
":libcef_dll_wrapper",
":${app_name}_framework_bundle_data",
]

View File

@@ -7,5 +7,6 @@
# https://bitbucket.org/chromiumembedded/cef/wiki/BranchesAndBuilding
{
'chromium_checkout': 'refs/tags/90.0.4430.0'
'chromium_checkout': 'refs/tags/90.0.4430.212',
'depot_tools_checkout': '9757ad5883'
}

View File

@@ -563,6 +563,7 @@
'tests/ceftests/audio_output_unittest.cc',
'tests/ceftests/client_app_delegates.cc',
'tests/ceftests/cookie_unittest.cc',
'tests/ceftests/cors_unittest.cc',
'tests/ceftests/dom_unittest.cc',
'tests/ceftests/frame_unittest.cc',
'tests/ceftests/message_router_unittest.cc',

View File

@@ -491,6 +491,9 @@ if(OS_WINDOWS)
PSAPI_VERSION=1 # Required by cef_sandbox.lib
CEF_USE_SANDBOX # Used by apps to test if the sandbox is enabled
)
list(APPEND CEF_COMPILER_DEFINES_DEBUG
_HAS_ITERATOR_DEBUGGING=0 # Disable iterator debugging
)
# Libraries required by cef_sandbox.lib.
set(CEF_SANDBOX_STANDARD_LIBS

View File

@@ -33,7 +33,7 @@
// by hand. See the translator.README.txt file in the tools directory for
// more information.
//
// $hash=f0cd169568e9ea5bcc8bf2aa891691b76c05356d$
// $hash=ade537f836add7fe0b5fd94ceba26d678abb3e43$
//
#ifndef CEF_INCLUDE_CAPI_CEF_BROWSER_PROCESS_HANDLER_CAPI_H_
@@ -43,7 +43,6 @@
#include "include/capi/cef_base_capi.h"
#include "include/capi/cef_client_capi.h"
#include "include/capi/cef_command_line_capi.h"
#include "include/capi/cef_print_handler_capi.h"
#include "include/capi/cef_values_capi.h"
#ifdef __cplusplus
@@ -61,25 +60,6 @@ typedef struct _cef_browser_process_handler_t {
///
cef_base_ref_counted_t base;
///
// Called on the browser process UI thread to retrieve the list of schemes
// that should support cookies. If |include_defaults| is true (1) the default
// schemes ("http", "https", "ws" and "wss") will also be supported. Providing
// an NULL |schemes| value and setting |include_defaults| to false (0) will
// disable all loading and saving of cookies.
//
// This state will apply to the cef_cookie_manager_t associated with the
// global cef_request_context_t. It will also be used as the initial state for
// any new cef_request_context_ts created by the client. After creating a new
// cef_request_context_t the cef_cookie_manager_t::SetSupportedSchemes
// function may be called on the associated cef_cookie_manager_t to futher
// override these values.
///
void(CEF_CALLBACK* get_cookieable_schemes)(
struct _cef_browser_process_handler_t* self,
cef_string_list_t schemes,
int* include_defaults);
///
// Called on the browser process UI thread immediately after the CEF context
// has been initialized.
@@ -98,13 +78,6 @@ typedef struct _cef_browser_process_handler_t {
struct _cef_browser_process_handler_t* self,
struct _cef_command_line_t* command_line);
///
// Return the handler for printing on Linux. If a print handler is not
// provided then printing will not be supported on the Linux platform.
///
struct _cef_print_handler_t*(CEF_CALLBACK* get_print_handler)(
struct _cef_browser_process_handler_t* self);
///
// Called from any thread when work has been scheduled for the browser process
// main (UI) thread. This callback is used in combination with CefSettings.

View File

@@ -33,7 +33,7 @@
// by hand. See the translator.README.txt file in the tools directory for
// more information.
//
// $hash=4cfcac55d2a1dee466a2a0753f30fb34a78ef3b2$
// $hash=14eca959988209ba8f95037a47192fd50d64f2f1$
//
#ifndef CEF_INCLUDE_CAPI_CEF_CLIENT_CAPI_H_
@@ -53,6 +53,7 @@
#include "include/capi/cef_keyboard_handler_capi.h"
#include "include/capi/cef_life_span_handler_capi.h"
#include "include/capi/cef_load_handler_capi.h"
#include "include/capi/cef_print_handler_capi.h"
#include "include/capi/cef_process_message_capi.h"
#include "include/capi/cef_render_handler_capi.h"
#include "include/capi/cef_request_handler_capi.h"
@@ -146,6 +147,13 @@ typedef struct _cef_client_t {
struct _cef_load_handler_t*(CEF_CALLBACK* get_load_handler)(
struct _cef_client_t* self);
///
// Return the handler for printing on Linux. If a print handler is not
// provided then printing will not be supported on the Linux platform.
///
struct _cef_print_handler_t*(CEF_CALLBACK* get_print_handler)(
struct _cef_client_t* self);
///
// Return the handler for off-screen rendering events.
///

View File

@@ -33,7 +33,7 @@
// by hand. See the translator.README.txt file in the tools directory for
// more information.
//
// $hash=20ba58ac3e861344ee738b58433869223c757e24$
// $hash=b19ef1c8a781f8d59276357609fe64370bb8a107$
//
#ifndef CEF_INCLUDE_CAPI_CEF_COOKIE_CAPI_H_
@@ -61,21 +61,6 @@ typedef struct _cef_cookie_manager_t {
///
cef_base_ref_counted_t base;
///
// Set the schemes supported by this manager. If |include_defaults| is true
// (1) the default schemes ("http", "https", "ws" and "wss") will also be
// supported. Calling this function with an NULL |schemes| value and
// |include_defaults| set to false (0) will disable all loading and saving of
// cookies for this manager. If |callback| is non-NULL it will be executed
// asnychronously on the UI thread after the change has been applied. Must be
// called before any cookies are accessed.
///
void(CEF_CALLBACK* set_supported_schemes)(
struct _cef_cookie_manager_t* self,
cef_string_list_t schemes,
int include_defaults,
struct _cef_completion_callback_t* callback);
///
// Visit all cookies on the UI thread. The returned cookies are ordered by
// longest path, then by earliest creation date. Returns false (0) if cookies

View File

@@ -33,7 +33,7 @@
// by hand. See the translator.README.txt file in the tools directory for
// more information.
//
// $hash=3767c7759578cd4abc1c2ecef504e7ed60775abb$
// $hash=79e4e38c732c0cfeef495c8a9726e105054012bb$
//
#ifndef CEF_INCLUDE_CAPI_CEF_MEDIA_ROUTER_CAPI_H_
@@ -41,6 +41,7 @@
#pragma once
#include "include/capi/cef_base_capi.h"
#include "include/capi/cef_callback_capi.h"
#include "include/capi/cef_registration_capi.h"
#ifdef __cplusplus
@@ -110,11 +111,14 @@ typedef struct _cef_media_router_t {
} cef_media_router_t;
///
// Returns the MediaRouter object associated with the global request context.
// Equivalent to calling cef_request_context_t::cef_request_context_get_global_c
// ontext()->get_media_router().
// Returns the MediaRouter object associated with the global request context. If
// |callback| is non-NULL it will be executed asnychronously on the UI thread
// after the manager's storage has been initialized. Equivalent to calling cef_r
// equest_context_t::cef_request_context_get_global_context()->get_media_router(
// ).
///
CEF_EXPORT cef_media_router_t* cef_media_router_get_global();
CEF_EXPORT cef_media_router_t* cef_media_router_get_global(
struct _cef_completion_callback_t* callback);
///
// Implemented by the client to observe MediaRouter events and registered via

View File

@@ -33,7 +33,7 @@
// by hand. See the translator.README.txt file in the tools directory for
// more information.
//
// $hash=54ed1e16c5c1d133bcd097350c5f5871228efd4f$
// $hash=84fc58b3898f25476d9cdd260553390ba5e0b30b$
//
#ifndef CEF_INCLUDE_CAPI_CEF_PRINT_HANDLER_CAPI_H_
@@ -148,6 +148,7 @@ typedef struct _cef_print_handler_t {
///
cef_size_t(CEF_CALLBACK* get_pdf_paper_size)(
struct _cef_print_handler_t* self,
struct _cef_browser_t* browser,
int device_units_per_inch);
} cef_print_handler_t;

View File

@@ -33,7 +33,7 @@
// by hand. See the translator.README.txt file in the tools directory for
// more information.
//
// $hash=d5079b6a5146ccd2085c3bbf948925c009d329ed$
// $hash=2e42334fc22050e207e5a0af6fe290a592e4105f$
//
#ifndef CEF_INCLUDE_CAPI_CEF_REQUEST_CONTEXT_CAPI_H_
@@ -132,7 +132,7 @@ typedef struct _cef_request_context_t {
///
// Returns the cookie manager for this object. If |callback| is non-NULL it
// will be executed asnychronously on the IO thread after the manager's
// will be executed asnychronously on the UI thread after the manager's
// storage has been initialized.
///
struct _cef_cookie_manager_t*(CEF_CALLBACK* get_cookie_manager)(
@@ -356,10 +356,13 @@ typedef struct _cef_request_context_t {
const cef_string_t* extension_id);
///
// Returns the MediaRouter object associated with this context.
// Returns the MediaRouter object associated with this context. If |callback|
// is non-NULL it will be executed asnychronously on the UI thread after the
// manager's context has been initialized.
///
struct _cef_media_router_t*(CEF_CALLBACK* get_media_router)(
struct _cef_request_context_t* self);
struct _cef_request_context_t* self,
struct _cef_completion_callback_t* callback);
} cef_request_context_t;
///

View File

@@ -33,7 +33,7 @@
// by hand. See the translator.README.txt file in the tools directory for
// more information.
//
// $hash=0fbd582ed5d0231550840ebf3eed2e488ac546d4$
// $hash=3e4eb9ed3a0cb28ae0459a50f20c8405c7722437$
//
#ifndef CEF_INCLUDE_CAPI_VIEWS_CEF_BROWSER_VIEW_CAPI_H_
@@ -65,6 +65,17 @@ typedef struct _cef_browser_view_t {
struct _cef_browser_t*(CEF_CALLBACK* get_browser)(
struct _cef_browser_view_t* self);
///
// Returns the Chrome toolbar associated with this BrowserView. Only supported
// when using the Chrome runtime. The cef_browser_view_delegate_t::
// get_chrome_toolbar_type() function must return a value other than
// CEF_CTT_NONE and the toolbar will not be available until after this
// BrowserView is added to a cef_window_t and
// cef_view_delegate_t::on_window_changed() has been called.
///
struct _cef_view_t*(CEF_CALLBACK* get_chrome_toolbar)(
struct _cef_browser_view_t* self);
///
// Sets whether accelerators registered with cef_window_t::SetAccelerator are
// triggered before or after the event is sent to the cef_browser_t. If

View File

@@ -33,7 +33,7 @@
// by hand. See the translator.README.txt file in the tools directory for
// more information.
//
// $hash=37bbfadf761b3a1996276885d593d27d3fed5f8d$
// $hash=220a126af3682f716f10b9019e8d1461702aa7c9$
//
#ifndef CEF_INCLUDE_CAPI_VIEWS_CEF_BROWSER_VIEW_DELEGATE_CAPI_H_
@@ -112,6 +112,14 @@ typedef struct _cef_browser_view_delegate_t {
struct _cef_browser_view_t* browser_view,
struct _cef_browser_view_t* popup_browser_view,
int is_devtools);
///
// Returns the Chrome toolbar type that will be available via
// cef_browser_view_t::get_chrome_toolbar(). See that function for related
// documentation.
///
cef_chrome_toolbar_type_t(CEF_CALLBACK* get_chrome_toolbar_type)(
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=8bd92dd03af4f5cf8c359c45a2d6d013565c2ead$
// $hash=a060cb3c53317d758e7f6b4a275288cd08f086e7$
//
#ifndef CEF_INCLUDE_CAPI_VIEWS_CEF_VIEW_DELEGATE_CAPI_H_
@@ -114,6 +114,13 @@ typedef struct _cef_view_delegate_t {
int added,
struct _cef_view_t* child);
///
// Called when |view| is added or removed from the cef_window_t.
///
void(CEF_CALLBACK* on_window_changed)(struct _cef_view_delegate_t* self,
struct _cef_view_t* view,
int added);
///
// Called when |view| gains focus.
///

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 "694bc8d68956bd174529f72fea5710929ac8bbf0"
#define CEF_API_HASH_UNIVERSAL "d026196d35d8894a836ab3a3d033b84195cdb835"
#if defined(OS_WIN)
#define CEF_API_HASH_PLATFORM "597ae4ad020de2665469e7de990d784bfda8d514"
#define CEF_API_HASH_PLATFORM "4150bd26e7bf639a9b1f3e5860af8c76eeae8570"
#elif defined(OS_MAC)
#define CEF_API_HASH_PLATFORM "fa3b4a918791bf53a4a8715ac9f0c843a3c08061"
#define CEF_API_HASH_PLATFORM "5cc32f88bd134410eff86b21095138b339d572f2"
#elif defined(OS_LINUX)
#define CEF_API_HASH_PLATFORM "83ff6d6fb2e0ac8447f68fa6141091cc9f666ca0"
#define CEF_API_HASH_PLATFORM "b227b3fdd6142a9d8ff0f2252a71425f15960800"
#endif
#ifdef __cplusplus

View File

@@ -41,7 +41,6 @@
#include "include/cef_base.h"
#include "include/cef_client.h"
#include "include/cef_command_line.h"
#include "include/cef_print_handler.h"
#include "include/cef_values.h"
///
@@ -51,23 +50,6 @@
/*--cef(source=client,no_debugct_check)--*/
class CefBrowserProcessHandler : public virtual CefBaseRefCounted {
public:
///
// Called on the browser process UI thread to retrieve the list of schemes
// that should support cookies. If |include_defaults| is true the default
// schemes ("http", "https", "ws" and "wss") will also be supported. Providing
// an empty |schemes| value and setting |include_defaults| to false will
// disable all loading and saving of cookies.
//
// This state will apply to the CefCookieManager associated with the global
// CefRequestContext. It will also be used as the initial state for any new
// CefRequestContexts created by the client. After creating a new
// CefRequestContext the CefCookieManager::SetSupportedSchemes method may be
// called on the associated CefCookieManager to futher override these values.
///
/*--cef()--*/
virtual void GetCookieableSchemes(std::vector<CefString>& schemes,
bool& include_defaults) {}
///
// Called on the browser process UI thread immediately after the CEF context
// has been initialized.
@@ -86,13 +68,6 @@ class CefBrowserProcessHandler : public virtual CefBaseRefCounted {
virtual void OnBeforeChildProcessLaunch(
CefRefPtr<CefCommandLine> command_line) {}
///
// Return the handler for printing on Linux. If a print handler is not
// provided then printing will not be supported on the Linux platform.
///
/*--cef()--*/
virtual CefRefPtr<CefPrintHandler> GetPrintHandler() { return nullptr; }
///
// Called from any thread when work has been scheduled for the browser process
// main (UI) thread. This callback is used in combination with CefSettings.

View File

@@ -51,6 +51,7 @@
#include "include/cef_keyboard_handler.h"
#include "include/cef_life_span_handler.h"
#include "include/cef_load_handler.h"
#include "include/cef_print_handler.h"
#include "include/cef_process_message.h"
#include "include/cef_render_handler.h"
#include "include/cef_request_handler.h"
@@ -139,6 +140,13 @@ class CefClient : public virtual CefBaseRefCounted {
/*--cef()--*/
virtual CefRefPtr<CefLoadHandler> GetLoadHandler() { return nullptr; }
///
// Return the handler for printing on Linux. If a print handler is not
// provided then printing will not be supported on the Linux platform.
///
/*--cef()--*/
virtual CefRefPtr<CefPrintHandler> GetPrintHandler() { return nullptr; }
///
// Return the handler for off-screen rendering events.
///

View File

@@ -64,21 +64,6 @@ class CefCookieManager : public virtual CefBaseRefCounted {
static CefRefPtr<CefCookieManager> GetGlobalManager(
CefRefPtr<CefCompletionCallback> callback);
///
// Set the schemes supported by this manager. If |include_defaults| is true
// the default schemes ("http", "https", "ws" and "wss") will also be
// supported. Calling this method with an empty |schemes| value and
// |include_defaults| set to false will disable all loading and saving of
// cookies for this manager. If |callback| is non-NULL it will be executed
// asnychronously on the UI thread after the change has been applied. Must be
// called before any cookies are accessed.
///
/*--cef(optional_param=callback)--*/
virtual void SetSupportedSchemes(
const std::vector<CefString>& schemes,
bool include_defaults,
CefRefPtr<CefCompletionCallback> callback) = 0;
///
// Visit all cookies on the UI thread. The returned cookies are ordered by
// longest path, then by earliest creation date. Returns false if cookies

View File

@@ -40,6 +40,7 @@
#include <vector>
#include "include/cef_base.h"
#include "include/cef_callback.h"
#include "include/cef_registration.h"
class CefMediaObserver;
@@ -59,11 +60,13 @@ class CefMediaRouter : public virtual CefBaseRefCounted {
public:
///
// Returns the MediaRouter object associated with the global request context.
// Equivalent to calling
// CefRequestContext::GetGlobalContext()->GetMediaRouter().
// If |callback| is non-NULL it will be executed asnychronously on the UI
// thread after the manager's storage has been initialized. Equivalent to
// calling CefRequestContext::GetGlobalContext()->GetMediaRouter().
///
/*--cef()--*/
static CefRefPtr<CefMediaRouter> GetGlobalMediaRouter();
/*--cef(optional_param=callback)--*/
static CefRefPtr<CefMediaRouter> GetGlobalMediaRouter(
CefRefPtr<CefCompletionCallback> callback);
///
// Add an observer for MediaRouter events. The observer will remain registered

View File

@@ -133,7 +133,8 @@ class CefPrintHandler : public virtual CefBaseRefCounted {
// CefBrowserHost::PrintToPDF().
///
/*--cef()--*/
virtual CefSize GetPdfPaperSize(int device_units_per_inch) {
virtual CefSize GetPdfPaperSize(CefRefPtr<CefBrowser> browser,
int device_units_per_inch) {
return CefSize();
}
};

View File

@@ -146,7 +146,7 @@ class CefRequestContext : public virtual CefBaseRefCounted {
///
// Returns the cookie manager for this object. If |callback| is non-NULL it
// will be executed asnychronously on the IO thread after the manager's
// will be executed asnychronously on the UI thread after the manager's
// storage has been initialized.
///
/*--cef(optional_param=callback)--*/
@@ -364,10 +364,13 @@ class CefRequestContext : public virtual CefBaseRefCounted {
const CefString& extension_id) = 0;
///
// Returns the MediaRouter object associated with this context.
// Returns the MediaRouter object associated with this context. If |callback|
// is non-NULL it will be executed asnychronously on the UI thread after the
// manager's context has been initialized.
///
/*--cef()--*/
virtual CefRefPtr<CefMediaRouter> GetMediaRouter() = 0;
/*--cef(optional_param=callback)--*/
virtual CefRefPtr<CefMediaRouter> GetMediaRouter(
CefRefPtr<CefCompletionCallback> callback) = 0;
};
#endif // CEF_INCLUDE_CEF_REQUEST_CONTEXT_H_

View File

@@ -242,7 +242,9 @@ typedef struct _cef_settings_t {
// in-memory caches are used for storage and no data is persisted to disk.
// HTML5 databases such as localStorage will only persist across sessions if a
// cache path is specified. Can be overridden for individual CefRequestContext
// instances via the CefRequestContextSettings.cache_path value.
// instances via the CefRequestContextSettings.cache_path value. When using
// the Chrome runtime the "default" profile will be used if |cache_path| and
// |root_cache_path| have the same value.
///
cef_string_t cache_path;
@@ -264,7 +266,8 @@ typedef struct _cef_settings_t {
// directory on Linux, "~/Library/Application Support/CEF/User Data" directory
// on Mac OS X, "Local Settings\Application Data\CEF\User Data" directory
// under the user profile directory on Windows). If this value is non-empty
// then it must be an absolute path.
// then it must be an absolute path. When using the Chrome runtime this value
// will be ignored in favor of the |root_cache_path| value.
///
cef_string_t user_data_path;
@@ -301,9 +304,9 @@ typedef struct _cef_settings_t {
// Value that will be inserted as the product portion of the default
// User-Agent string. If empty the Chromium product version will be used. If
// |userAgent| is specified this value will be ignored. Also configurable
// using the "product-version" command-line switch.
// using the "user-agent-product" command-line switch.
///
cef_string_t product_version;
cef_string_t user_agent_product;
///
// The locale string that will be passed to WebKit. If empty the default
@@ -419,6 +422,20 @@ typedef struct _cef_settings_t {
///
cef_string_t accept_language_list;
///
// Comma delimited list of schemes supported by the associated
// CefCookieManager. If |cookieable_schemes_exclude_defaults| is false (0) the
// default schemes ("http", "https", "ws" and "wss") will also be supported.
// Specifying a |cookieable_schemes_list| value and setting
// |cookieable_schemes_exclude_defaults| to true (1) will disable all loading
// and saving of cookies for this manager. Can be overridden
// for individual CefRequestContext instances via the
// CefRequestContextSettings.cookieable_schemes_list and
// CefRequestContextSettings.cookieable_schemes_exclude_defaults values.
///
cef_string_t cookieable_schemes_list;
int cookieable_schemes_exclude_defaults;
///
// GUID string used for identifying the application. This is passed to the
// system AV function for scanning downloaded files. By default, the GUID
@@ -487,6 +504,18 @@ typedef struct _cef_request_context_settings_t {
// ignored if |cache_path| matches the CefSettings.cache_path value.
///
cef_string_t accept_language_list;
///
// Comma delimited list of schemes supported by the associated
// CefCookieManager. If |cookieable_schemes_exclude_defaults| is false (0) the
// default schemes ("http", "https", "ws" and "wss") will also be supported.
// Specifying a |cookieable_schemes_list| value and setting
// |cookieable_schemes_exclude_defaults| to true (1) will disable all loading
// and saving of cookies for this manager. These values will be ignored if
// |cache_path| matches the CefSettings.cache_path value.
///
cef_string_t cookieable_schemes_list;
int cookieable_schemes_exclude_defaults;
} cef_request_context_settings_t;
///
@@ -585,14 +614,6 @@ typedef struct _cef_browser_settings_t {
///
cef_state_t file_access_from_file_urls;
///
// Controls whether web security restrictions (same-origin policy) will be
// enforced. Disabling this setting is not recommend as it will allow risky
// security behavior such as cross-site scripting (XSS). Also configurable
// using the "disable-web-security" command-line switch.
///
cef_state_t web_security;
///
// Controls whether image URLs will be loaded from the network. A cached image
// will still be rendered if requested. Also configurable using the
@@ -659,7 +680,7 @@ typedef struct _cef_browser_settings_t {
///
// Comma delimited ordered list of language codes without any whitespace that
// will be used in the "Accept-Language" HTTP header. May be set globally
// using the CefBrowserSettings.accept_language_list value. If both values are
// using the CefSettings.accept_language_list value. If both values are
// empty then "en-US,en" will be used.
///
cef_string_t accept_language_list;
@@ -3193,6 +3214,15 @@ typedef enum {
CEF_TFC_SELECT_ALL,
} cef_text_field_commands_t;
///
// Supported Chrome toolbar types.
///
typedef enum {
CEF_CTT_NONE = 1,
CEF_CTT_NORMAL,
CEF_CTT_LOCATION,
} cef_chrome_toolbar_type_t;
#ifdef __cplusplus
}
#endif

View File

@@ -548,13 +548,14 @@ struct CefSettingsTraits {
cef_string_clear(&s->root_cache_path);
cef_string_clear(&s->user_data_path);
cef_string_clear(&s->user_agent);
cef_string_clear(&s->product_version);
cef_string_clear(&s->user_agent_product);
cef_string_clear(&s->locale);
cef_string_clear(&s->log_file);
cef_string_clear(&s->javascript_flags);
cef_string_clear(&s->resources_dir_path);
cef_string_clear(&s->locales_dir_path);
cef_string_clear(&s->accept_language_list);
cef_string_clear(&s->cookieable_schemes_list);
cef_string_clear(&s->application_client_id_for_file_scanning);
}
@@ -586,8 +587,8 @@ struct CefSettingsTraits {
cef_string_set(src->user_agent.str, src->user_agent.length,
&target->user_agent, copy);
cef_string_set(src->product_version.str, src->product_version.length,
&target->product_version, copy);
cef_string_set(src->user_agent_product.str, src->user_agent_product.length,
&target->user_agent_product, copy);
cef_string_set(src->locale.str, src->locale.length, &target->locale, copy);
cef_string_set(src->log_file.str, src->log_file.length, &target->log_file,
@@ -609,6 +610,13 @@ struct CefSettingsTraits {
cef_string_set(src->accept_language_list.str,
src->accept_language_list.length,
&target->accept_language_list, copy);
cef_string_set(src->cookieable_schemes_list.str,
src->cookieable_schemes_list.length,
&target->cookieable_schemes_list, copy);
target->cookieable_schemes_exclude_defaults =
src->cookieable_schemes_exclude_defaults;
cef_string_set(src->application_client_id_for_file_scanning.str,
src->application_client_id_for_file_scanning.length,
&target->application_client_id_for_file_scanning, copy);
@@ -628,6 +636,7 @@ struct CefRequestContextSettingsTraits {
static inline void clear(struct_type* s) {
cef_string_clear(&s->cache_path);
cef_string_clear(&s->accept_language_list);
cef_string_clear(&s->cookieable_schemes_list);
}
static inline void set(const struct_type* src,
@@ -641,6 +650,12 @@ struct CefRequestContextSettingsTraits {
cef_string_set(src->accept_language_list.str,
src->accept_language_list.length,
&target->accept_language_list, copy);
cef_string_set(src->cookieable_schemes_list.str,
src->cookieable_schemes_list.length,
&target->cookieable_schemes_list, copy);
target->cookieable_schemes_exclude_defaults =
src->cookieable_schemes_exclude_defaults;
}
};
@@ -705,7 +720,6 @@ struct CefBrowserSettingsTraits {
target->universal_access_from_file_urls =
src->universal_access_from_file_urls;
target->file_access_from_file_urls = src->file_access_from_file_urls;
target->web_security = src->web_security;
target->image_loading = src->image_loading;
target->image_shrink_standalone_to_fit =
src->image_shrink_standalone_to_fit;

View File

@@ -80,6 +80,17 @@ class CefBrowserView : public CefView {
/*--cef()--*/
virtual CefRefPtr<CefBrowser> GetBrowser() = 0;
///
// Returns the Chrome toolbar associated with this BrowserView. Only supported
// when using the Chrome runtime. The CefBrowserViewDelegate::
// GetChromeToolbarType() method must return a value other than
// CEF_CTT_NONE and the toolbar will not be available until after this
// BrowserView is added to a CefWindow and CefViewDelegate::OnWindowChanged()
// has been called.
///
/*--cef()--*/
virtual CefRefPtr<CefView> GetChromeToolbar() = 0;
///
// Sets whether accelerators registered with CefWindow::SetAccelerator are
// triggered before or after the event is sent to the CefBrowser. If

View File

@@ -52,6 +52,8 @@ class CefBrowserView;
/*--cef(source=client)--*/
class CefBrowserViewDelegate : public CefViewDelegate {
public:
typedef cef_chrome_toolbar_type_t ChromeToolbarType;
///
// Called when |browser| associated with |browser_view| is created. This
// method will be called after CefLifeSpanHandler::OnAfterCreated() is called
@@ -104,6 +106,14 @@ class CefBrowserViewDelegate : public CefViewDelegate {
bool is_devtools) {
return false;
}
///
// Returns the Chrome toolbar type that will be available via
// CefBrowserView::GetChromeToolbar(). See that method for related
// documentation.
///
/*--cef(default_retval=CEF_CTT_NONE)--*/
virtual ChromeToolbarType GetChromeToolbarType() { return CEF_CTT_NONE; }
};
#endif // CEF_INCLUDE_VIEWS_CEF_BROWSER_VIEW_DELEGATE_H_

View File

@@ -105,6 +105,12 @@ class CefViewDelegate : public virtual CefBaseRefCounted {
bool added,
CefRefPtr<CefView> child) {}
///
// Called when |view| is added or removed from the CefWindow.
///
/*--cef(optional_param=window)--*/
virtual void OnWindowChanged(CefRefPtr<CefView> view, bool added) {}
///
// Called when |view| gains focus.
///

View File

@@ -113,6 +113,18 @@ AlloyBrowserContext::~AlloyBrowserContext() {
}
}
bool AlloyBrowserContext::IsInitialized() const {
CEF_REQUIRE_UIT();
return !!key_;
}
void AlloyBrowserContext::StoreOrTriggerInitCallback(
base::OnceClosure callback) {
CEF_REQUIRE_UIT();
// Initialization is always synchronous.
std::move(callback).Run();
}
void AlloyBrowserContext::Initialize() {
CefBrowserContext::Initialize();

View File

@@ -42,6 +42,8 @@ class AlloyBrowserContext : public ChromeProfileAlloy,
// CefBrowserContext overrides.
content::BrowserContext* AsBrowserContext() override { return this; }
Profile* AsProfile() override { return this; }
bool IsInitialized() const override;
void StoreOrTriggerInitCallback(base::OnceClosure callback) override;
void Initialize() override;
void Shutdown() override;
void RemoveCefRequestContext(CefRequestContextImpl* context) override;

View File

@@ -24,6 +24,7 @@
#include "libcef/common/cef_messages.h"
#include "libcef/common/cef_switches.h"
#include "libcef/common/drag_data_impl.h"
#include "libcef/common/net/url_util.h"
#include "libcef/common/request_impl.h"
#include "libcef/common/values_impl.h"
#include "libcef/features/runtime_checks.h"
@@ -175,12 +176,13 @@ CefRefPtr<AlloyBrowserHostImpl> AlloyBrowserHostImpl::Create(
if (!browser)
return nullptr;
GURL url = url_util::MakeGURL(create_params.url, /*fixup=*/true);
if (create_params.extension) {
platform_delegate_ptr->CreateExtensionHost(
create_params.extension, create_params.url,
create_params.extension_host_type);
} else if (!create_params.url.is_empty()) {
content::OpenURLParams params(create_params.url, content::Referrer(),
create_params.extension, url, create_params.extension_host_type);
} else if (!url.is_empty()) {
content::OpenURLParams params(url, content::Referrer(),
WindowOpenDisposition::CURRENT_TAB,
CefFrameHostImpl::kPageTransitionExplicit,
/*is_renderer_initiated=*/false);
@@ -810,12 +812,6 @@ bool AlloyBrowserHostImpl::MaybeAllowNavigation(
return true;
}
SkColor AlloyBrowserHostImpl::GetBackgroundColor() const {
// Don't use |platform_delegate_| because it's not thread-safe.
return CefContext::Get()->GetBackgroundColor(
&settings_, is_windowless_ ? STATE_ENABLED : STATE_DISABLED);
}
extensions::ExtensionHost* AlloyBrowserHostImpl::GetExtensionHost() const {
CEF_REQUIRE_UIT();
DCHECK(platform_delegate_);

View File

@@ -151,7 +151,7 @@ class AlloyBrowserHostImpl : public CefBrowserHostBase,
bool IsBackgroundHost() override;
// Returns true if windowless rendering is enabled.
bool IsWindowless() const;
bool IsWindowless() const override;
// Returns true if this browser supports picture-in-picture.
bool IsPictureInPictureSupported() const;
@@ -182,9 +182,6 @@ class AlloyBrowserHostImpl : public CefBrowserHostBase,
content::RenderWidgetHostImpl* source_rwh);
void UpdateDragCursor(ui::mojom::DragOperation operation);
// Thread safe accessors.
SkColor GetBackgroundColor() const;
// Accessors that must be called on the UI thread.
extensions::ExtensionHost* GetExtensionHost() const;

View File

@@ -695,9 +695,9 @@ void AlloyContentBrowserClient::AppendExtraCommandLineSwitches(
switches::kLocalesDirPath,
switches::kLogFile,
switches::kLogSeverity,
switches::kProductVersion,
switches::kResourcesDirPath,
embedder_support::kUserAgent,
switches::kUserAgentProductAndVersion,
};
command_line->CopySwitchesFrom(*browser_cmd, kSwitchNames,
base::size(kSwitchNames));

View File

@@ -12,6 +12,7 @@
#include "libcef/browser/extensions/extension_web_contents_observer.h"
#include "libcef/browser/printing/print_view_manager.h"
#include "libcef/common/extensions/extensions_util.h"
#include "libcef/common/net/url_util.h"
#include "libcef/features/runtime_checks.h"
#include "base/logging.h"
@@ -58,12 +59,13 @@ content::WebContents* CefBrowserPlatformDelegateAlloy::CreateWebContents(
}
scoped_refptr<content::SiteInstance> site_instance;
if (extensions::ExtensionsEnabled() && !create_params.url.is_empty()) {
if (extensions::ExtensionsEnabled() && !create_params.url.empty()) {
GURL gurl = url_util::MakeGURL(create_params.url, /*fixup=*/true);
if (!create_params.extension) {
// We might be loading an extension app view where the extension URL is
// provided by the client.
create_params.extension =
extensions::GetExtensionForUrl(browser_context, create_params.url);
extensions::GetExtensionForUrl(browser_context, gurl);
}
if (create_params.extension) {
if (create_params.extension_host_type == extensions::VIEW_TYPE_INVALID) {
@@ -79,7 +81,7 @@ content::WebContents* CefBrowserPlatformDelegateAlloy::CreateWebContents(
// ExtensionProtocolHandler::MaybeCreateJob will return false resulting in
// ERR_BLOCKED_BY_CLIENT).
site_instance = extensions::ProcessManager::Get(browser_context)
->GetSiteInstanceForURL(create_params.url);
->GetSiteInstanceForURL(gurl);
DCHECK(site_instance);
}
}

View File

@@ -68,9 +68,12 @@ content::WebContents* CefBrowserContentsDelegate::OpenURLFromTab(
if (auto c = client()) {
if (auto handler = c->GetRequestHandler()) {
// May return nullptr for omnibox navigations.
auto frame = browser()->GetFrame(params.frame_tree_node_id);
if (!frame)
frame = browser()->GetMainFrame();
cancel = handler->OnOpenURLFromTab(
browser(), browser()->GetFrame(params.frame_tree_node_id),
params.url.spec(),
browser(), frame, params.url.spec(),
static_cast<cef_window_open_disposition_t>(params.disposition),
params.user_gesture);
}
@@ -105,6 +108,7 @@ void CefBrowserContentsDelegate::LoadingStateChanged(
if (auto c = client()) {
if (auto handler = c->GetLoadHandler()) {
auto navigation_lock = browser_info_->CreateNavigationLock();
handler->OnLoadingStateChange(browser(), is_loading, can_go_back,
can_go_forward);
}
@@ -507,6 +511,7 @@ void CefBrowserContentsDelegate::OnLoadEnd(CefRefPtr<CefFrame> frame,
int http_status_code) {
if (auto c = client()) {
if (auto handler = c->GetLoadHandler()) {
auto navigation_lock = browser_info_->CreateNavigationLock();
handler->OnLoadEnd(browser(), frame, http_status_code);
}
}
@@ -565,6 +570,7 @@ void CefBrowserContentsDelegate::OnLoadStart(
ui::PageTransition transition_type) {
if (auto c = client()) {
if (auto handler = c->GetLoadHandler()) {
auto navigation_lock = browser_info_->CreateNavigationLock();
// On the handler that loading has started.
handler->OnLoadStart(browser(), frame,
static_cast<cef_transition_type_t>(transition_type));

View File

@@ -7,16 +7,20 @@
#include <map>
#include <utility>
#include "libcef/browser/iothread_state.h"
#include "libcef/browser/context.h"
#include "libcef/browser/media_router/media_router_manager.h"
#include "libcef/browser/request_context_impl.h"
#include "libcef/browser/thread_util.h"
#include "libcef/common/cef_switches.h"
#include "libcef/features/runtime.h"
#include "base/files/file_util.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/no_destructor.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "chrome/browser/profiles/profile.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
@@ -141,6 +145,28 @@ CefBrowserContext* GetSelf(base::WeakPtr<CefBrowserContext> self) {
return self.get();
}
CefBrowserContext::CookieableSchemes MakeSupportedSchemes(
const CefString& schemes_list,
bool include_defaults) {
std::vector<std::string> all_schemes;
if (!schemes_list.empty()) {
all_schemes =
base::SplitString(schemes_list.ToString(), std::string(","),
base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
}
if (include_defaults) {
// Add default schemes that should always support cookies.
// This list should match CookieMonster::kDefaultCookieableSchemes.
all_schemes.push_back("http");
all_schemes.push_back("https");
all_schemes.push_back("ws");
all_schemes.push_back("wss");
}
return base::make_optional(all_schemes);
}
} // namespace
CefBrowserContext::CefBrowserContext(const CefRequestContextSettings& settings)
@@ -154,13 +180,6 @@ CefBrowserContext::~CefBrowserContext() {
#if DCHECK_IS_ON()
DCHECK(is_shutdown_);
#endif
if (iothread_state_) {
// Destruction of the CefIOThreadState will trigger destruction of all
// associated network requests.
content::BrowserThread::DeleteSoon(content::BrowserThread::IO, FROM_HERE,
iothread_state_.release());
}
}
void CefBrowserContext::Initialize() {
@@ -169,7 +188,14 @@ void CefBrowserContext::Initialize() {
if (!cache_path_.empty())
g_manager.Get().SetImplPath(this, cache_path_);
iothread_state_ = std::make_unique<CefIOThreadState>();
iothread_state_ = base::MakeRefCounted<CefIOThreadState>();
if (settings_.cookieable_schemes_list.length > 0 ||
settings_.cookieable_schemes_exclude_defaults) {
cookieable_schemes_ =
MakeSupportedSchemes(CefString(&settings_.cookieable_schemes_list),
!settings_.cookieable_schemes_exclude_defaults);
}
}
void CefBrowserContext::Shutdown() {
@@ -229,6 +255,25 @@ CefBrowserContext* CefBrowserContext::FromBrowserContext(
return g_manager.Get().GetImplFromBrowserContext(context);
}
// static
CefBrowserContext* CefBrowserContext::FromProfile(const Profile* profile) {
auto* cef_context = FromBrowserContext(profile);
if (cef_context)
return cef_context;
if (cef::IsChromeRuntimeEnabled()) {
auto* original_profile = profile->GetOriginalProfile();
if (original_profile != profile) {
// With the Chrome runtime if the user launches an incognito window via
// the UI we might be associated with the original Profile instead of the
// (current) incognito profile.
return FromBrowserContext(original_profile);
}
}
return nullptr;
}
// static
std::vector<CefBrowserContext*> CefBrowserContext::GetAll() {
return g_manager.Get().GetAllImpl();
@@ -254,15 +299,10 @@ void CefBrowserContext::OnRenderFrameCreated(
handler_map_.AddHandler(render_process_id, render_frame_id,
frame_tree_node_id, handler);
if (iothread_state_) {
// Using base::Unretained() is safe because both this callback and
// possible deletion of |iothread_state_| will execute on the IO thread,
// and this callback will be executed first.
CEF_POST_TASK(CEF_IOT, base::Bind(&CefIOThreadState::AddHandler,
base::Unretained(iothread_state_.get()),
render_process_id, render_frame_id,
frame_tree_node_id, handler));
}
CEF_POST_TASK(CEF_IOT,
base::Bind(&CefIOThreadState::AddHandler, iothread_state_,
render_process_id, render_frame_id,
frame_tree_node_id, handler));
}
}
@@ -292,15 +332,9 @@ void CefBrowserContext::OnRenderFrameDeleted(
handler_map_.RemoveHandler(render_process_id, render_frame_id,
frame_tree_node_id);
if (iothread_state_) {
// Using base::Unretained() is safe because both this callback and
// possible deletion of |iothread_state_| will execute on the IO thread,
// and this callback will be executed first.
CEF_POST_TASK(CEF_IOT, base::Bind(&CefIOThreadState::RemoveHandler,
base::Unretained(iothread_state_.get()),
render_process_id, render_frame_id,
frame_tree_node_id));
}
CEF_POST_TASK(CEF_IOT, base::Bind(&CefIOThreadState::RemoveHandler,
iothread_state_, render_process_id,
render_frame_id, frame_tree_node_id));
}
if (is_main_frame) {
@@ -404,26 +438,15 @@ void CefBrowserContext::RegisterSchemeHandlerFactory(
const CefString& scheme_name,
const CefString& domain_name,
CefRefPtr<CefSchemeHandlerFactory> factory) {
if (iothread_state_) {
// Using base::Unretained() is safe because both this callback and possible
// deletion of |iothread_state_| will execute on the IO thread, and this
// callback will be executed first.
CEF_POST_TASK(CEF_IOT,
base::Bind(&CefIOThreadState::RegisterSchemeHandlerFactory,
base::Unretained(iothread_state_.get()),
scheme_name, domain_name, factory));
}
CEF_POST_TASK(CEF_IOT,
base::Bind(&CefIOThreadState::RegisterSchemeHandlerFactory,
iothread_state_, scheme_name, domain_name, factory));
}
void CefBrowserContext::ClearSchemeHandlerFactories() {
if (iothread_state_) {
// Using base::Unretained() is safe because both this callback and possible
// deletion of |iothread_state_| will execute on the IO thread, and this
// callback will be executed first.
CEF_POST_TASK(CEF_IOT,
base::Bind(&CefIOThreadState::ClearSchemeHandlerFactories,
base::Unretained(iothread_state_.get())));
}
CEF_POST_TASK(CEF_IOT,
base::Bind(&CefIOThreadState::ClearSchemeHandlerFactories,
iothread_state_));
}
void CefBrowserContext::LoadExtension(
@@ -477,5 +500,24 @@ CefBrowserContext::CookieableSchemes CefBrowserContext::GetCookieableSchemes()
if (cookieable_schemes_)
return cookieable_schemes_;
return CefCookieManagerImpl::GetGlobalCookieableSchemes();
return GetGlobalCookieableSchemes();
}
// static
CefBrowserContext::CookieableSchemes
CefBrowserContext::GetGlobalCookieableSchemes() {
CEF_REQUIRE_UIT();
static base::NoDestructor<CookieableSchemes> schemes(
[]() -> CookieableSchemes {
const auto& settings = CefContext::Get()->settings();
if (settings.cookieable_schemes_list.length > 0 ||
settings.cookieable_schemes_exclude_defaults) {
return MakeSupportedSchemes(
CefString(&settings.cookieable_schemes_list),
!settings.cookieable_schemes_exclude_defaults);
}
return base::nullopt;
}());
return *schemes;
}

View File

@@ -10,6 +10,7 @@
#include <vector>
#include "include/cef_request_context_handler.h"
#include "libcef/browser/iothread_state.h"
#include "libcef/browser/request_context_handler_map.h"
#include "base/callback.h"
@@ -80,7 +81,6 @@ class BrowserContext;
class CefMediaRouterManager;
class CefRequestContextImpl;
class CefIOThreadState;
class Profile;
// Main entry point for configuring behavior on a per-RequestContext basis. The
@@ -103,6 +103,7 @@ class CefBrowserContext {
// Returns the underlying CefBrowserContext if any.
static CefBrowserContext* FromBrowserContext(
const content::BrowserContext* context);
static CefBrowserContext* FromProfile(const Profile* profile);
// Returns all existing CefBrowserContext.
static std::vector<CefBrowserContext*> GetAll();
@@ -111,6 +112,13 @@ class CefBrowserContext {
virtual content::BrowserContext* AsBrowserContext() = 0;
virtual Profile* AsProfile() = 0;
// Returns true if the context is fully initialized.
virtual bool IsInitialized() const = 0;
// If the context is fully initialized execute |callback|, otherwise
// store it until the context is fully initialized.
virtual void StoreOrTriggerInitCallback(base::OnceClosure callback) = 0;
// Called from CefRequestContextImpl to track associated objects. This
// object will delete itself when the count reaches zero.
void AddCefRequestContext(CefRequestContextImpl* context);
@@ -197,17 +205,15 @@ class CefBrowserContext {
// Returns the schemes associated with this context specifically, or the
// global configuration if unset.
CookieableSchemes GetCookieableSchemes() const;
// Set the schemes associated with this context specifically.
void set_cookieable_schemes(const CookieableSchemes& schemes) {
cookieable_schemes_ = schemes;
}
static CookieableSchemes GetGlobalCookieableSchemes();
// These accessors are safe to call from any thread because the values don't
// change during this object's lifespan.
const CefRequestContextSettings& settings() const { return settings_; }
base::FilePath cache_path() const { return cache_path_; }
CefIOThreadState* iothread_state() const { return iothread_state_.get(); }
scoped_refptr<CefIOThreadState> iothread_state() const {
return iothread_state_;
}
// Used to hold a WeakPtr reference to this this object. The Getter returns
// nullptr if this object has already been destroyed.
@@ -230,7 +236,7 @@ class CefBrowserContext {
base::FilePath cache_path_;
private:
std::unique_ptr<CefIOThreadState> iothread_state_;
scoped_refptr<CefIOThreadState> iothread_state_;
CookieableSchemes cookieable_schemes_;
std::unique_ptr<CefMediaRouterManager> media_router_manager_;

View File

@@ -6,16 +6,17 @@
#include "libcef/browser/browser_info_manager.h"
#include "libcef/browser/browser_platform_delegate.h"
#include "libcef/browser/context.h"
#include "libcef/browser/image_impl.h"
#include "libcef/browser/navigation_entry_impl.h"
#include "libcef/browser/thread_util.h"
#include "libcef/common/net/url_util.h"
#include "base/logging.h"
#include "chrome/browser/spellchecker/spellcheck_factory.h"
#include "chrome/browser/spellchecker/spellcheck_service.h"
#include "components/favicon/core/favicon_url.h"
#include "components/spellcheck/common/spellcheck_features.h"
#include "components/url_formatter/url_fixer.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/download_manager.h"
#include "content/public/browser/download_request_utils.h"
@@ -761,16 +762,9 @@ bool CefBrowserHostBase::Navigate(const content::OpenURLParams& params) {
CEF_REQUIRE_UIT();
auto web_contents = GetWebContents();
if (web_contents) {
// Fix common problems with user-typed text. Among other things, this:
// - Converts absolute file paths to "file://" URLs.
// - Normalizes "about:" and "chrome:" to "chrome://" URLs.
// - Adds the "http://" scheme if none was specified.
GURL gurl = url_formatter::FixupURL(params.url.possibly_invalid_spec(),
std::string());
if (!gurl.is_valid()) {
LOG(ERROR) << "Invalid URL: " << params.url.possibly_invalid_spec();
GURL gurl = params.url;
if (!url_util::FixupGURL(gurl))
return false;
}
web_contents->GetController().LoadURL(
gurl, params.referrer, params.transition, params.extra_headers);
@@ -833,6 +827,16 @@ int CefBrowserHostBase::browser_id() const {
return browser_info_->browser_id();
}
SkColor CefBrowserHostBase::GetBackgroundColor() const {
// Don't use |platform_delegate_| because it's not thread-safe.
return CefContext::Get()->GetBackgroundColor(
&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();

View File

@@ -51,8 +51,13 @@ struct CefBrowserCreateParams {
#if defined(TOOLKIT_VIEWS)
// The BrowserView that will own a Views-hosted browser. Will be nullptr for
// popup browsers (the BrowserView will be created later in that case).
// popup browsers.
CefRefPtr<CefBrowserView> browser_view;
// True if this browser is a popup and has a Views-hosted opener, in which
// case the BrowserView for this browser will be created later (from
// PopupWebContentsCreated).
bool popup_with_views_hosted_opener = false;
#endif
// Client implementation. May be nullptr.
@@ -60,7 +65,7 @@ struct CefBrowserCreateParams {
// Initial URL to load. May be empty. If this is a valid extension URL then
// the browser will be created as an app view extension host.
GURL url;
CefString url;
// Browser settings.
CefBrowserSettings settings;
@@ -241,6 +246,10 @@ class CefBrowserHostBase : public CefBrowserHost,
return request_context_;
}
bool is_views_hosted() const { return is_views_hosted_; }
SkColor GetBackgroundColor() const;
// Returns true if windowless rendering is enabled.
virtual bool IsWindowless() const;
// Accessors that must be called on the UI thread.
content::WebContents* GetWebContents() const;

View File

@@ -27,6 +27,11 @@ class CreateBrowserHelper {
extra_info_(extra_info),
request_context_(request_context) {}
void Run() {
CefBrowserHost::CreateBrowserSync(window_info_, client_, url_, settings_,
extra_info_, request_context_);
}
CefWindowInfo window_info_;
CefRefPtr<CefClient> client_;
CefString url_;
@@ -71,19 +76,25 @@ bool CefBrowserHost::CreateBrowser(
"reduced performance or runtime errors.";
}
// Create the browser on the UI thread.
CreateBrowserHelper* helper = new CreateBrowserHelper(
if (!request_context) {
request_context = CefRequestContext::GetGlobalContext();
}
auto helper = std::make_unique<CreateBrowserHelper>(
windowInfo, client, url, settings, extra_info, request_context);
CEF_POST_TASK(CEF_UIT, base::BindOnce(
[](CreateBrowserHelper* helper) {
CefBrowserHost::CreateBrowserSync(
helper->window_info_, helper->client_,
helper->url_, helper->settings_,
helper->extra_info_,
helper->request_context_);
delete helper;
},
helper));
auto request_context_impl =
static_cast<CefRequestContextImpl*>(request_context.get());
// Wait for the browser context to be initialized before creating the browser.
request_context_impl->ExecuteWhenBrowserContextInitialized(base::BindOnce(
[](std::unique_ptr<CreateBrowserHelper> helper) {
// Always execute asynchronously to avoid potential issues if we're
// being called synchronously during app initialization.
CEF_POST_TASK(CEF_UIT, base::BindOnce(&CreateBrowserHelper::Run,
std::move(helper)));
},
std::move(helper)));
return true;
}
@@ -108,9 +119,14 @@ CefRefPtr<CefBrowser> CefBrowserHost::CreateBrowserSync(
return nullptr;
}
// Verify that this method is being called on the UI thread.
if (!CEF_CURRENTLY_ON_UIT()) {
NOTREACHED() << "called on invalid thread";
if (!request_context) {
request_context = CefRequestContext::GetGlobalContext();
}
// Verify that the browser context is valid.
auto request_context_impl =
static_cast<CefRequestContextImpl*>(request_context.get());
if (!request_context_impl->VerifyBrowserContext()) {
return nullptr;
}
@@ -124,12 +140,7 @@ CefRefPtr<CefBrowser> CefBrowserHost::CreateBrowserSync(
CefBrowserCreateParams create_params;
create_params.window_info.reset(new CefWindowInfo(windowInfo));
create_params.client = client;
create_params.url = GURL(url.ToString());
if (!url.empty() && !create_params.url.is_valid() &&
!create_params.url.has_scheme()) {
std::string new_url = std::string("http://") + url.ToString();
create_params.url = GURL(new_url);
}
create_params.url = url;
create_params.settings = settings;
create_params.extra_info = extra_info;
create_params.request_context = request_context;

View File

@@ -181,8 +181,11 @@ bool CefBrowserInfoManager::CanCreateWindow(
if (allow) {
CefBrowserCreateParams create_params;
if (!browser->HasView())
if (browser->HasView()) {
create_params.popup_with_views_hosted_opener = true;
} else {
create_params.window_info = std::move(window_info);
}
create_params.settings = pending_popup->settings;
create_params.client = pending_popup->client;

View File

@@ -84,7 +84,8 @@ std::unique_ptr<CefBrowserPlatformDelegate> CefBrowserPlatformDelegate::Create(
std::unique_ptr<CefBrowserPlatformDelegateNative> native_delegate =
CreateNativeDelegate(CefWindowInfo(), background_color);
#if defined(TOOLKIT_VIEWS)
if (create_params.browser_view) {
if (create_params.browser_view ||
create_params.popup_with_views_hosted_opener) {
return std::make_unique<CefBrowserPlatformDelegateChromeViews>(
std::move(native_delegate),
static_cast<CefBrowserViewImpl*>(create_params.browser_view.get()));

View File

@@ -4,13 +4,14 @@
#include "libcef/browser/chrome/chrome_browser_context.h"
#include "libcef/browser/prefs/browser_prefs.h"
#include "libcef/browser/thread_util.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/profiles/off_the_record_profile_impl.h"
ChromeBrowserContext::ChromeBrowserContext(
const CefRequestContextSettings& settings)
: CefBrowserContext(settings) {}
: CefBrowserContext(settings), weak_ptr_factory_(this) {}
ChromeBrowserContext::~ChromeBrowserContext() = default;
@@ -22,19 +23,108 @@ Profile* ChromeBrowserContext::AsProfile() {
return profile_;
}
void ChromeBrowserContext::Initialize() {
bool ChromeBrowserContext::IsInitialized() const {
CEF_REQUIRE_UIT();
return !!profile_;
}
void ChromeBrowserContext::StoreOrTriggerInitCallback(
base::OnceClosure callback) {
CEF_REQUIRE_UIT();
if (IsInitialized()) {
std::move(callback).Run();
} else {
init_callbacks_.emplace_back(std::move(callback));
}
}
void ChromeBrowserContext::InitializeAsync(base::OnceClosure initialized_cb) {
init_callbacks_.emplace_back(std::move(initialized_cb));
CefBrowserContext::Initialize();
// TODO(chrome-runtime): ProfileManager can create new profiles relative to
// the user-data-dir, but it should be done asynchronously.
// The global ProfileManager instance can be retrieved via
// |g_browser_process->profile_manager()|.
profile_ = ProfileManager::GetLastUsedProfileAllowedByPolicy();
if (!cache_path_.empty()) {
auto* profile_manager = g_browser_process->profile_manager();
const auto& user_data_dir = profile_manager->user_data_dir();
browser_prefs::SetLanguagePrefs(profile_);
if (cache_path_ == user_data_dir) {
// Use the default disk-based profile.
auto profile = profile_manager->GetPrimaryUserProfile();
ProfileCreated(profile, Profile::CreateStatus::CREATE_STATUS_INITIALIZED);
return;
} else if (cache_path_.DirName() == user_data_dir) {
// Create or load a specific disk-based profile. May continue
// synchronously or asynchronously.
profile_manager->CreateProfileAsync(
cache_path_,
base::Bind(&ChromeBrowserContext::ProfileCreated,
weak_ptr_factory_.GetWeakPtr()),
/*name=*/base::string16(), /*icon_url=*/std::string());
return;
} else {
// All profile directories must be relative to |user_data_dir|.
LOG(ERROR) << "Cannot create profile at path "
<< cache_path_.AsUTF8Unsafe();
}
}
// Default to creating a new/unique OffTheRecord profile.
ProfileCreated(nullptr, Profile::CreateStatus::CREATE_STATUS_CANCELED);
}
void ChromeBrowserContext::Shutdown() {
CefBrowserContext::Shutdown();
// |g_browser_process| may be nullptr during shutdown.
if (should_destroy_ && g_browser_process) {
g_browser_process->profile_manager()
->GetPrimaryUserProfile()
->DestroyOffTheRecordProfile(profile_);
}
profile_ = nullptr;
}
void ChromeBrowserContext::ProfileCreated(Profile* profile,
Profile::CreateStatus status) {
Profile* parent_profile = nullptr;
OffTheRecordProfileImpl* otr_profile = nullptr;
if (status != Profile::CreateStatus::CREATE_STATUS_CREATED &&
status != Profile::CreateStatus::CREATE_STATUS_INITIALIZED) {
CHECK(!profile);
CHECK(!profile_);
// Creation of a disk-based profile failed for some reason. Create a
// new/unique OffTheRecord profile instead.
const auto& profile_id = Profile::OTRProfileID::CreateUniqueForCEF();
parent_profile =
g_browser_process->profile_manager()->GetPrimaryUserProfile();
profile_ = parent_profile->GetOffTheRecordProfile(profile_id);
otr_profile = static_cast<OffTheRecordProfileImpl*>(profile_);
status = Profile::CreateStatus::CREATE_STATUS_INITIALIZED;
should_destroy_ = true;
} else if (profile && !profile_) {
// May be CREATE_STATUS_CREATED or CREATE_STATUS_INITIALIZED since
// *CREATED isn't always sent for a disk-based profile that already
// exists.
profile_ = profile;
}
if (status == Profile::CreateStatus::CREATE_STATUS_INITIALIZED) {
CHECK(profile_);
// Must set |profile_| before Init() calls
// ChromeContentBrowserClientCef::ConfigureNetworkContextParams so that
// CefBrowserContext::FromBrowserContext can find us.
if (otr_profile) {
otr_profile->Init();
parent_profile->NotifyOffTheRecordProfileCreated(otr_profile);
}
if (!init_callbacks_.empty()) {
for (auto& callback : init_callbacks_) {
std::move(callback).Run();
}
init_callbacks_.clear();
}
}
}

View File

@@ -8,22 +8,36 @@
#include "libcef/browser/browser_context.h"
#include "base/memory/weak_ptr.h"
#include "chrome/browser/profiles/profile_manager.h"
// See CefBrowserContext documentation for usage. Only accessed on the UI thread
// unless otherwise indicated.
class ChromeBrowserContext : public CefBrowserContext {
public:
explicit ChromeBrowserContext(const CefRequestContextSettings& settings);
void InitializeAsync(base::OnceClosure initialized_cb);
// CefBrowserContext overrides.
content::BrowserContext* AsBrowserContext() override;
Profile* AsProfile() override;
void Initialize() override;
bool IsInitialized() const override;
void StoreOrTriggerInitCallback(base::OnceClosure callback) override;
void Shutdown() override;
private:
~ChromeBrowserContext() override;
void ProfileCreated(Profile* profile, Profile::CreateStatus status);
base::OnceClosure initialized_cb_;
Profile* profile_ = nullptr;
bool should_destroy_ = false;
std::vector<base::OnceClosure> init_callbacks_;
base::WeakPtrFactory<ChromeBrowserContext> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(ChromeBrowserContext);
};

View File

@@ -16,6 +16,7 @@
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_tabstrip.h"
#include "content/public/browser/keyboard_event_processing_result.h"
#include "content/public/browser/native_web_keyboard_event.h"
@@ -65,7 +66,7 @@ void ChromeBrowserDelegate::SetAsDelegate(content::WebContents* web_contents,
create_params_.request_context);
CreateBrowser(web_contents, create_params_.settings, create_params_.client,
std::move(platform_delegate), browser_info,
std::move(platform_delegate), browser_info, /*opener=*/nullptr,
request_context_impl);
}
@@ -103,7 +104,28 @@ void ChromeBrowserDelegate::WebContentsCreated(
// We don't officially own |new_contents| until AddNewContents() is called.
// However, we need to install observers/delegates here.
CreateBrowser(new_contents, settings, client, std::move(platform_delegate),
browser_info, request_context_impl);
browser_info, opener, request_context_impl);
}
void ChromeBrowserDelegate::AddNewContents(
content::WebContents* source_contents,
std::unique_ptr<content::WebContents> new_contents,
const GURL& target_url,
WindowOpenDisposition disposition,
const gfx::Rect& initial_rect,
bool user_gesture,
bool* was_blocked) {
auto new_browser =
ChromeBrowserHostImpl::GetBrowserForContents(new_contents.get());
if (new_browser) {
// Create a new Browser and give it ownership of the WebContents.
new_browser->AddNewContents(std::move(new_contents));
return;
}
// Fall back to default behavior from Browser::AddNewContents.
chrome::AddWebContents(browser_, source_contents, std::move(new_contents),
target_url, disposition, initial_rect);
}
content::WebContents* ChromeBrowserDelegate::OpenURLFromTab(
@@ -195,6 +217,7 @@ void ChromeBrowserDelegate::CreateBrowser(
CefRefPtr<CefClient> client,
std::unique_ptr<CefBrowserPlatformDelegate> platform_delegate,
scoped_refptr<CefBrowserInfo> browser_info,
CefRefPtr<ChromeBrowserHostImpl> opener,
CefRefPtr<CefRequestContextImpl> request_context_impl) {
CEF_REQUIRE_UIT();
DCHECK(web_contents);
@@ -202,6 +225,9 @@ void ChromeBrowserDelegate::CreateBrowser(
DCHECK(browser_info);
DCHECK(request_context_impl);
// If |opener| is non-nullptr it must be a popup window.
DCHECK(!opener.get() || browser_info->is_popup());
if (!client) {
if (auto app = CefAppManager::Get()->GetApplication()) {
if (auto bph = app->GetBrowserProcessHandler()) {
@@ -226,7 +252,12 @@ void ChromeBrowserDelegate::CreateBrowser(
CefRefPtr<ChromeBrowserHostImpl> browser_host =
new ChromeBrowserHostImpl(settings, client, std::move(platform_delegate),
browser_info, request_context_impl);
browser_host->Attach(browser_, web_contents);
browser_host->Attach(web_contents, opener);
// The Chrome browser for a popup won't be created until AddNewContents().
if (!opener) {
browser_host->SetBrowser(browser_);
}
}
CefBrowserContentsDelegate* ChromeBrowserDelegate::GetDelegateForWebContents(

View File

@@ -55,6 +55,13 @@ class ChromeBrowserDelegate : public cef::BrowserDelegate {
const std::string& frame_name,
const GURL& target_url,
content::WebContents* new_contents) override;
void AddNewContents(content::WebContents* source_contents,
std::unique_ptr<content::WebContents> new_contents,
const GURL& target_url,
WindowOpenDisposition disposition,
const gfx::Rect& initial_rect,
bool user_gesture,
bool* was_blocked) override;
content::WebContents* OpenURLFromTab(
content::WebContents* source,
const content::OpenURLParams& params) override;
@@ -88,6 +95,7 @@ class ChromeBrowserDelegate : public cef::BrowserDelegate {
CefRefPtr<CefClient> client,
std::unique_ptr<CefBrowserPlatformDelegate> platform_delegate,
scoped_refptr<CefBrowserInfo> browser_info,
CefRefPtr<ChromeBrowserHostImpl> opener,
CefRefPtr<CefRequestContextImpl> request_context_impl);
CefBrowserContentsDelegate* GetDelegateForWebContents(

View File

@@ -8,6 +8,7 @@
#include "libcef/browser/chrome/browser_platform_delegate_chrome.h"
#include "libcef/browser/thread_util.h"
#include "libcef/browser/views/browser_view_impl.h"
#include "libcef/common/net/url_util.h"
#include "libcef/features/runtime_checks.h"
#include "base/logging.h"
@@ -21,8 +22,6 @@
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/common/pref_names.h"
#include "components/url_formatter/url_fixer.h"
#include "url/url_constants.h"
#if defined(TOOLKIT_VIEWS)
#include "libcef/browser/chrome/views/chrome_browser_frame.h"
@@ -32,62 +31,9 @@
// static
CefRefPtr<ChromeBrowserHostImpl> ChromeBrowserHostImpl::Create(
const CefBrowserCreateParams& params) {
// Get or create the request context and profile.
CefRefPtr<CefRequestContextImpl> request_context_impl =
CefRequestContextImpl::GetOrCreateForRequestContext(
params.request_context);
CHECK(request_context_impl);
auto cef_browser_context = request_context_impl->GetBrowserContext();
CHECK(cef_browser_context);
auto profile = cef_browser_context->AsProfile();
auto browser = CreateBrowser(params);
Browser::CreateParams chrome_params =
Browser::CreateParams(profile, /*user_gesture=*/false);
// Pass |params| to cef::BrowserDelegate::Create from the Browser constructor.
chrome_params.cef_params = base::MakeRefCounted<DelegateCreateParams>(params);
#if defined(TOOLKIT_VIEWS)
// Configure Browser creation to use the existing Views-based
// Widget/BrowserFrame (ChromeBrowserFrame) and BrowserView/BrowserWindow
// (ChromeBrowserView). See views/chrome_browser_frame.h for related
// documentation.
ChromeBrowserView* chrome_browser_view = nullptr;
if (params.browser_view) {
// Don't show most controls.
chrome_params.type = Browser::TYPE_POPUP;
// Don't show title bar or address.
chrome_params.trusted_source = true;
auto view_impl =
static_cast<CefBrowserViewImpl*>(params.browser_view.get());
chrome_browser_view =
static_cast<ChromeBrowserView*>(view_impl->root_view());
chrome_params.window = chrome_browser_view;
auto chrome_widget =
static_cast<ChromeBrowserFrame*>(chrome_browser_view->GetWidget());
chrome_browser_view->set_frame(chrome_widget);
}
#endif // defined(TOOLKIT_VIEWS)
// Create the Browser. This will indirectly create the ChomeBrowserDelegate.
// The same params will be used to create a new Browser if the tab is dragged
// out of the existing Browser. The returned Browser is owned by the
// associated BrowserView.
auto browser = Browser::Create(chrome_params);
#if defined(TOOLKIT_VIEWS)
if (chrome_browser_view) {
// Initialize the BrowserFrame and BrowserView and create the controls that
// require access to the Browser.
chrome_browser_view->InitBrowser(base::WrapUnique(browser),
params.browser_view);
}
#endif
GURL url = params.url;
GURL url = url_util::MakeGURL(params.url, /*fixup=*/true);
if (url.is_empty()) {
// Chrome will navigate to kChromeUINewTabURL by default. We want to keep
// the current CEF behavior of not navigating at all. Use a special URL that
@@ -98,7 +44,8 @@ CefRefPtr<ChromeBrowserHostImpl> ChromeBrowserHostImpl::Create(
// Add a new tab. This will indirectly create a new tab WebContents and
// call ChromeBrowserDelegate::OnWebContentsCreated to create the associated
// ChromeBrowserHostImpl.
chrome::AddTabAt(browser, url, /*idx=*/-1, /*foreground=*/true);
chrome::AddTabAt(browser, url, /*index=*/TabStripModel::kNoTab,
/*foreground=*/true);
// The new tab WebContents.
auto web_contents = browser->tab_strip_model()->GetActiveWebContents();
@@ -159,6 +106,34 @@ CefRefPtr<ChromeBrowserHostImpl> ChromeBrowserHostImpl::GetBrowserForFrameRoute(
ChromeBrowserHostImpl::~ChromeBrowserHostImpl() = default;
void ChromeBrowserHostImpl::AddNewContents(
std::unique_ptr<content::WebContents> contents) {
DCHECK(contents);
DCHECK(!browser_);
// We should already be associated with the WebContents.
DCHECK_EQ(GetWebContents(), contents.get());
CefBrowserCreateParams params;
params.request_context = request_context();
#if defined(TOOLKIT_VIEWS)
params.browser_view = GetBrowserView();
#endif
// Create the new Browser representation.
auto browser = CreateBrowser(params);
// Add the WebContents to the Browser.
browser->tab_strip_model()->AddWebContents(
std::move(contents), /*index=*/TabStripModel::kNoTab,
ui::PageTransition::PAGE_TRANSITION_AUTO_TOPLEVEL,
TabStripModel::ADD_ACTIVE);
SetBrowser(browser);
browser->window()->Show();
}
void ChromeBrowserHostImpl::OnWebContentsDestroyed(
content::WebContents* web_contents) {
platform_delegate_->WebContentsDestroyed(web_contents);
@@ -416,16 +391,9 @@ bool ChromeBrowserHostImpl::Navigate(const content::OpenURLParams& params) {
}
if (browser_) {
// Fix common problems with user-typed text. Among other things, this:
// - Converts absolute file paths to "file://" URLs.
// - Normalizes "about:" and "chrome:" to "chrome://" URLs.
// - Adds the "http://" scheme if none was specified.
GURL gurl = url_formatter::FixupURL(params.url.possibly_invalid_spec(),
std::string());
if (!gurl.is_valid()) {
LOG(ERROR) << "Invalid URL: " << params.url.possibly_invalid_spec();
GURL gurl = params.url;
if (!url_util::FixupGURL(gurl))
return false;
}
// This is generally equivalent to calling Browser::OpenURL, except:
// 1. It doesn't trigger a call to CefRequestHandler::OnOpenURLFromTab, and
@@ -461,17 +429,113 @@ ChromeBrowserHostImpl::ChromeBrowserHostImpl(
browser_info,
request_context) {}
void ChromeBrowserHostImpl::Attach(Browser* browser,
content::WebContents* web_contents) {
DCHECK(browser);
// static
Browser* ChromeBrowserHostImpl::CreateBrowser(
const CefBrowserCreateParams& params) {
// Get or create the request context and profile.
CefRefPtr<CefRequestContextImpl> request_context_impl =
CefRequestContextImpl::GetOrCreateForRequestContext(
params.request_context);
CHECK(request_context_impl);
auto cef_browser_context = request_context_impl->GetBrowserContext();
CHECK(cef_browser_context);
auto profile = cef_browser_context->AsProfile();
CHECK(profile);
Browser::CreateParams chrome_params =
Browser::CreateParams(profile, /*user_gesture=*/false);
// Pass |params| to cef::BrowserDelegate::Create from the Browser constructor.
chrome_params.cef_params = base::MakeRefCounted<DelegateCreateParams>(params);
#if defined(TOOLKIT_VIEWS)
// Configure Browser creation to use the existing Views-based
// Widget/BrowserFrame (ChromeBrowserFrame) and BrowserView/BrowserWindow
// (ChromeBrowserView). See views/chrome_browser_frame.h for related
// documentation.
ChromeBrowserView* chrome_browser_view = nullptr;
if (params.browser_view) {
// Don't show most controls.
chrome_params.type = Browser::TYPE_POPUP;
// Don't show title bar or address.
chrome_params.trusted_source = true;
auto view_impl =
static_cast<CefBrowserViewImpl*>(params.browser_view.get());
chrome_browser_view =
static_cast<ChromeBrowserView*>(view_impl->root_view());
chrome_params.window = chrome_browser_view;
auto chrome_widget =
static_cast<ChromeBrowserFrame*>(chrome_browser_view->GetWidget());
chrome_browser_view->set_frame(chrome_widget);
}
#endif // defined(TOOLKIT_VIEWS)
// Create the Browser. This will indirectly create the ChomeBrowserDelegate.
// The same params will be used to create a new Browser if the tab is dragged
// out of the existing Browser. The returned Browser is owned by the
// associated BrowserView.
auto browser = Browser::Create(chrome_params);
#if defined(TOOLKIT_VIEWS)
if (chrome_browser_view) {
// Initialize the BrowserFrame and BrowserView and create the controls that
// require access to the Browser.
chrome_browser_view->InitBrowser(base::WrapUnique(browser),
params.browser_view);
}
#endif
return browser;
}
void ChromeBrowserHostImpl::Attach(content::WebContents* web_contents,
CefRefPtr<ChromeBrowserHostImpl> opener) {
DCHECK(web_contents);
SetBrowser(browser);
if (opener) {
// Give the opener browser's platform delegate an opportunity to modify the
// new browser's platform delegate.
opener->platform_delegate_->PopupWebContentsCreated(
settings_, client_, web_contents, platform_delegate_.get(),
/*is_devtools_popup=*/false);
}
platform_delegate_->WebContentsCreated(web_contents,
/*own_web_contents=*/false);
contents_delegate_->ObserveWebContents(web_contents);
// Associate the platform delegate with this browser.
platform_delegate_->BrowserCreated(this);
// Associate the base class with the WebContents.
InitializeBrowser();
// Notify that the browser has been created. These must be delivered in the
// expected order.
// 1. Notify the browser's LifeSpanHandler. This must always be the first
// notification for the browser.
{
// The WebContents won't be added to the Browser's TabStripModel until later
// in the current call stack. Block navigation until that time.
auto navigation_lock = browser_info_->CreateNavigationLock();
OnAfterCreated();
}
// 2. Notify the platform delegate. With Views this will result in a call to
// CefBrowserViewDelegate::OnBrowserCreated().
platform_delegate_->NotifyBrowserCreated();
if (opener && opener->platform_delegate_) {
// 3. Notify the opener browser's platform delegate. With Views this will
// result in a call to CefBrowserViewDelegate::OnPopupBrowserViewCreated().
opener->platform_delegate_->PopupBrowserCreated(
this,
/*is_devtools_popup=*/false);
}
}
void ChromeBrowserHostImpl::SetBrowser(Browser* browser) {
@@ -481,21 +545,6 @@ void ChromeBrowserHostImpl::SetBrowser(Browser* browser) {
->set_chrome_browser(browser);
}
void ChromeBrowserHostImpl::InitializeBrowser() {
CEF_REQUIRE_UIT();
DCHECK(browser_);
// Associate the platform delegate with this browser.
platform_delegate_->BrowserCreated(this);
CefBrowserHostBase::InitializeBrowser();
// The WebContents won't be added to the Browser's TabStripModel until later
// in the current call stack. Block navigation until that time.
auto navigation_lock = browser_info_->CreateNavigationLock();
OnAfterCreated();
}
void ChromeBrowserHostImpl::WindowDestroyed() {
CEF_REQUIRE_UIT();
#if defined(TOOLKIT_VIEWS)

View File

@@ -142,17 +142,24 @@ class ChromeBrowserHostImpl : public CefBrowserHostBase {
scoped_refptr<CefBrowserInfo> browser_info,
CefRefPtr<CefRequestContextImpl> request_context);
// Called from ChromeBrowserDelegate::SetAsDelegate when this object is first
// created. Must be called on the UI thread.
void Attach(Browser* browser, content::WebContents* web_contents);
// Create a new Browser without initializing the WebContents.
static Browser* CreateBrowser(const CefBrowserCreateParams& params);
// Called from ChromeBrowserDelegate::SetAsDelegate when this object changes
// Browser ownership (e.g. dragging between windows). The old Browser will be
// cleared before the new Browser is added. Must be called on the UI thread.
// Called from ChromeBrowserDelegate::CreateBrowser when this object is first
// created. Must be called on the UI thread.
void Attach(content::WebContents* web_contents,
CefRefPtr<ChromeBrowserHostImpl> opener);
// Called from ChromeBrowserDelegate::AddNewContents to take ownership of a
// popup WebContents.
void AddNewContents(std::unique_ptr<content::WebContents> contents);
// Called when this object changes Browser ownership (e.g. initially created,
// dragging between windows, etc). The old Browser, if any, will be cleared
// before the new Browser is added. Must be called on the UI thread.
void SetBrowser(Browser* browser);
// CefBrowserHostBase methods:
void InitializeBrowser() override;
void WindowDestroyed() override;
void DestroyBrowser() override;

View File

@@ -4,6 +4,7 @@
#include "libcef/browser/chrome/chrome_browser_main_extra_parts_cef.h"
#include "libcef/browser/chrome/chrome_context_menu_handler.h"
#include "libcef/browser/context.h"
#include "libcef/browser/net/chrome_scheme_handler.h"
@@ -34,4 +35,5 @@ void ChromeBrowserMainExtraPartsCef::PreMainMessageLoopRun() {
base::TaskShutdownBehavior::BLOCK_SHUTDOWN, base::MayBlock()});
scheme::RegisterWebUIControllerFactory();
context_menu::RegisterMenuCreatedCallback();
}

View File

@@ -7,13 +7,17 @@
#include "libcef/browser/browser_info_manager.h"
#include "libcef/browser/browser_message_filter.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"
#include "libcef/browser/net/throttle_handler.h"
#include "libcef/browser/net_service/cookie_manager_impl.h"
#include "libcef/browser/net_service/login_delegate.h"
#include "libcef/browser/net_service/proxy_url_loader_factory.h"
#include "libcef/browser/net_service/resource_request_handler_wrapper.h"
#include "libcef/browser/prefs/browser_prefs.h"
#include "libcef/browser/prefs/renderer_prefs.h"
#include "libcef/common/app_manager.h"
#include "libcef/common/cef_switches.h"
#include "libcef/common/command_line_impl.h"
@@ -25,7 +29,11 @@
#include "chrome/common/chrome_switches.h"
#include "content/public/browser/navigation_throttle.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_widget_host.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/common/content_switches.h"
#include "third_party/blink/public/common/web_preferences/web_preferences.h"
#include "third_party/blink/public/mojom/loader/resource_load_info.mojom-shared.h"
namespace {
@@ -82,6 +90,16 @@ void ChromeContentBrowserClientCef::AppendExtraCommandLineSwitches(
const base::CommandLine* browser_cmd = base::CommandLine::ForCurrentProcess();
{
// Propagate the following switches to all command lines (along with any
// associated values) if present in the browser command line.
static const char* const kSwitchNames[] = {
switches::kUserAgentProductAndVersion,
};
command_line->CopySwitchesFrom(*browser_cmd, kSwitchNames,
base::size(kSwitchNames));
}
const std::string& process_type =
command_line->GetSwitchValueASCII(switches::kProcessType);
if (process_type == switches::kRendererProcess) {
@@ -148,6 +166,33 @@ bool ChromeContentBrowserClientCef::CanCreateWindow(
user_gesture, opener_suppressed, no_javascript_access);
}
void ChromeContentBrowserClientCef::OverrideWebkitPrefs(
content::WebContents* web_contents,
blink::web_pref::WebPreferences* prefs) {
renderer_prefs::SetDefaultPrefs(*prefs);
ChromeContentBrowserClient::OverrideWebkitPrefs(web_contents, prefs);
auto browser = ChromeBrowserHostImpl::GetBrowserForContents(web_contents);
if (browser) {
renderer_prefs::SetCefPrefs(browser->settings(), *prefs);
// Set the background color for the WebView.
prefs->base_background_color = browser->GetBackgroundColor();
} else {
// We don't know for sure that the browser will be windowless but assume
// that the global windowless state is likely to be accurate.
prefs->base_background_color =
CefContext::Get()->GetBackgroundColor(nullptr, STATE_DEFAULT);
}
auto rvh = web_contents->GetRenderViewHost();
if (rvh->GetWidget()->GetView()) {
rvh->GetWidget()->GetView()->SetBackgroundColor(
prefs->base_background_color);
}
}
bool ChromeContentBrowserClientCef::WillCreateURLLoaderFactory(
content::BrowserContext* browser_context,
content::RenderFrameHost* frame,
@@ -175,7 +220,7 @@ bool ChromeContentBrowserClientCef::WillCreateURLLoaderFactory(
// For example, the User Manager profile created via
// profiles::CreateSystemProfileForUserManager.
auto profile = Profile::FromBrowserContext(browser_context);
if (!CefBrowserContext::FromBrowserContext(profile->GetOriginalProfile()))
if (!CefBrowserContext::FromProfile(profile))
return false;
auto request_handler = net_service::CreateInterceptedRequestHandler(
@@ -258,7 +303,18 @@ void ChromeContentBrowserClientCef::ConfigureNetworkContextParams(
auto cef_context = CefBrowserContext::FromBrowserContext(context);
network_context_params->cookieable_schemes =
cef_context ? cef_context->GetCookieableSchemes()
: CefCookieManagerImpl::GetGlobalCookieableSchemes();
: CefBrowserContext::GetGlobalCookieableSchemes();
// Prefer the CEF settings configuration, if specified, instead of the
// kAcceptLanguages preference which is controlled by the
// chrome://settings/languages configuration.
const std::string& accept_language_list =
browser_prefs::GetAcceptLanguageList(cef_context, /*browser=*/nullptr,
/*expand=*/true);
if (!accept_language_list.empty() &&
accept_language_list != network_context_params->accept_language) {
network_context_params->accept_language = accept_language_list;
}
}
std::unique_ptr<content::LoginDelegate>

View File

@@ -40,6 +40,8 @@ class ChromeContentBrowserClientCef : public ChromeContentBrowserClient {
bool user_gesture,
bool opener_suppressed,
bool* no_javascript_access) override;
void OverrideWebkitPrefs(content::WebContents* web_contents,
blink::web_pref::WebPreferences* prefs) override;
bool WillCreateURLLoaderFactory(
content::BrowserContext* browser_context,
content::RenderFrameHost* frame,

View File

@@ -0,0 +1,207 @@
// Copyright (c) 2021 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that can
// be found in the LICENSE file.
#include "libcef/browser/chrome/chrome_context_menu_handler.h"
#include "libcef/browser/browser_host_base.h"
#include "libcef/browser/context_menu_params_impl.h"
#include "libcef/browser/simple_menu_model_impl.h"
#include "chrome/browser/renderer_context_menu/render_view_context_menu.h"
namespace context_menu {
namespace {
// Lifespan is controlled by RenderViewContextMenu.
class CefContextMenuObserver : public RenderViewContextMenuObserver,
public CefSimpleMenuModelImpl::StateDelegate {
public:
CefContextMenuObserver(RenderViewContextMenu* context_menu,
CefRefPtr<CefBrowserHostBase> browser,
CefRefPtr<CefContextMenuHandler> handler)
: context_menu_(context_menu), browser_(browser), handler_(handler) {}
// RenderViewContextMenuObserver methods:
void InitMenu(const content::ContextMenuParams& params) override {
params_ = new CefContextMenuParamsImpl(
const_cast<content::ContextMenuParams*>(&context_menu_->params()));
model_ = new CefSimpleMenuModelImpl(
const_cast<ui::SimpleMenuModel*>(&context_menu_->menu_model()),
context_menu_, this, /*is_owned=*/false, /*is_popup=*/false);
handler_->OnBeforeContextMenu(browser_, GetFrame(), params_, model_);
}
bool IsCommandIdSupported(int command_id) override {
// Always claim support for the reserved user ID range.
if (command_id >= MENU_ID_USER_FIRST && command_id <= MENU_ID_USER_LAST)
return true;
// Also claim support in specific cases where an ItemInfo exists.
return GetItemInfo(command_id) != nullptr;
}
// Only called if IsCommandIdSupported() returns true.
bool IsCommandIdEnabled(int command_id) override {
// Always return true to use the SimpleMenuModel state.
return true;
}
// Only called if IsCommandIdSupported() returns true.
bool IsCommandIdChecked(int command_id) override {
auto* info = GetItemInfo(command_id);
return info ? info->checked : false;
}
// Only called if IsCommandIdSupported() returns true.
bool GetAccelerator(int command_id, ui::Accelerator* accel) override {
auto* info = GetItemInfo(command_id);
if (info && info->accel) {
*accel = *info->accel;
return true;
}
return false;
}
void CommandWillBeExecuted(int command_id) override {
if (handler_->OnContextMenuCommand(browser_, GetFrame(), params_,
command_id, EVENTFLAG_NONE)) {
// Create an ItemInfo so that we get the ExecuteCommand() callback
// instead of the default handler.
GetOrCreateItemInfo(command_id);
}
}
// Only called if IsCommandIdSupported() returns true.
void ExecuteCommand(int command_id) override {
auto* info = GetItemInfo(command_id);
if (info) {
// In case it was added in CommandWillBeExecuted().
MaybeDeleteItemInfo(command_id, info);
}
}
void OnMenuClosed() override {
handler_->OnContextMenuDismissed(browser_, GetFrame());
model_->Detach();
// Clear stored state because this object won't be deleted until a new
// context menu is created or the associated browser is destroyed.
browser_ = nullptr;
handler_ = nullptr;
params_ = nullptr;
model_ = nullptr;
iteminfomap_.clear();
}
// CefSimpleMenuModelImpl::StateDelegate methods:
void SetChecked(int command_id, bool checked) override {
// No-op if already at the default state.
if (!checked && !GetItemInfo(command_id))
return;
auto* info = GetOrCreateItemInfo(command_id);
info->checked = checked;
if (!checked)
MaybeDeleteItemInfo(command_id, info);
}
void SetAccelerator(int command_id,
base::Optional<ui::Accelerator> accel) override {
// No-op if already at the default state.
if (!accel && !GetItemInfo(command_id))
return;
auto* info = GetOrCreateItemInfo(command_id);
info->accel = accel;
if (!accel)
MaybeDeleteItemInfo(command_id, info);
}
private:
struct ItemInfo {
ItemInfo() {}
bool checked = false;
base::Optional<ui::Accelerator> accel;
};
ItemInfo* GetItemInfo(int command_id) {
auto it = iteminfomap_.find(command_id);
if (it != iteminfomap_.end()) {
return &it->second;
}
return nullptr;
}
ItemInfo* GetOrCreateItemInfo(int command_id) {
if (auto info = GetItemInfo(command_id))
return info;
auto result = iteminfomap_.insert(std::make_pair(command_id, ItemInfo()));
return &result.first->second;
}
void MaybeDeleteItemInfo(int command_id, ItemInfo* info) {
// Remove if all info has reverted to the default state.
if (!info->checked && !info->accel) {
auto it = iteminfomap_.find(command_id);
iteminfomap_.erase(it);
}
}
CefRefPtr<CefFrame> GetFrame() const {
CefRefPtr<CefFrame> frame;
// May return nullptr if the frame is destroyed while the menu is pending.
auto* rfh = context_menu_->GetRenderFrameHost();
if (rfh) {
frame = browser_->GetFrameForHost(rfh);
}
if (!frame) {
frame = browser_->GetMainFrame();
}
return frame;
}
RenderViewContextMenu* const context_menu_;
CefRefPtr<CefBrowserHostBase> browser_;
CefRefPtr<CefContextMenuHandler> handler_;
CefRefPtr<CefContextMenuParams> params_;
CefRefPtr<CefSimpleMenuModelImpl> model_;
// Map of command_id to ItemInfo.
using ItemInfoMap = std::map<int, ItemInfo>;
ItemInfoMap iteminfomap_;
DISALLOW_COPY_AND_ASSIGN(CefContextMenuObserver);
};
std::unique_ptr<RenderViewContextMenuObserver> MenuCreatedCallback(
RenderViewContextMenu* context_menu) {
auto browser = CefBrowserHostBase::GetBrowserForContents(
context_menu->source_web_contents());
if (browser) {
if (auto client = browser->GetClient()) {
if (auto handler = client->GetContextMenuHandler()) {
return std::make_unique<CefContextMenuObserver>(context_menu, browser,
handler);
}
}
}
return nullptr;
}
} // namespace
void RegisterMenuCreatedCallback() {
RenderViewContextMenu::RegisterMenuCreatedCallback(
base::BindRepeating(&MenuCreatedCallback));
}
} // namespace context_menu

View File

@@ -0,0 +1,16 @@
// Copyright (c) 2021 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that can
// be found in the LICENSE file.
#ifndef CEF_LIBCEF_BROWSER_CHROME_CHROME_CONTEXT_MENU_HANDLER_H_
#define CEF_LIBCEF_BROWSER_CHROME_CHROME_CONTEXT_MENU_HANDLER_H_
#pragma once
namespace context_menu {
// Register the context menu created callback.
void RegisterMenuCreatedCallback();
} // namespace context_menu
#endif // CEF_LIBCEF_BROWSER_CHROME_CHROME_CONTEXT_MENU_HANDLER_H_

View File

@@ -4,14 +4,59 @@
#include "libcef/browser/chrome/views/browser_platform_delegate_chrome_views.h"
#include "include/views/cef_window.h"
#include "chrome/browser/ui/browser.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) {}
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);
DISALLOW_COPY_AND_ASSIGN(PopupWindowDelegate);
};
} // namespace
CefBrowserPlatformDelegateChromeViews::CefBrowserPlatformDelegateChromeViews(
std::unique_ptr<CefBrowserPlatformDelegateNative> native_delegate,
CefRefPtr<CefBrowserViewImpl> browser_view)
: CefBrowserPlatformDelegateChrome(std::move(native_delegate)),
browser_view_(browser_view) {}
: CefBrowserPlatformDelegateChrome(std::move(native_delegate)) {
if (browser_view)
SetBrowserView(browser_view);
}
void CefBrowserPlatformDelegateChromeViews::SetBrowserView(
CefRefPtr<CefBrowserViewImpl> browser_view) {
DCHECK(!browser_view_);
DCHECK(browser_view);
browser_view_ = browser_view;
}
void CefBrowserPlatformDelegateChromeViews::WebContentsCreated(
content::WebContents* web_contents,
@@ -59,6 +104,50 @@ 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) {
DCHECK(new_platform_delegate->IsViewsHosted());
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) {
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

@@ -26,9 +26,19 @@ class CefBrowserPlatformDelegateChromeViews
void CloseHostWindow() 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;
bool IsViewsHosted() const override;
private:
void SetBrowserView(CefRefPtr<CefBrowserViewImpl> browser_view);
CefRefPtr<CefBrowserViewImpl> browser_view_;
};

View File

@@ -68,3 +68,31 @@ void ChromeBrowserView::OnBoundsChanged(const gfx::Rect& previous_bounds) {
ParentClass::OnBoundsChanged(previous_bounds);
browser_view_delegate_->OnBoundsChanged();
}
ToolbarView* ChromeBrowserView::OverrideCreateToolbar(
Browser* browser,
BrowserView* browser_view) {
if (cef_delegate()) {
auto toolbar_type = cef_delegate()->GetChromeToolbarType();
base::Optional<ToolbarView::DisplayMode> display_mode;
switch (toolbar_type) {
case CEF_CTT_NORMAL:
display_mode = ToolbarView::DisplayMode::NORMAL;
break;
case CEF_CTT_LOCATION:
display_mode = ToolbarView::DisplayMode::LOCATION;
break;
default:
break;
}
if (display_mode) {
cef_toolbar_ = CefToolbarViewImpl::Create(nullptr, browser, browser_view,
display_mode);
// Ownership will be taken by BrowserView.
view_util::PassOwnership(cef_toolbar_).release();
return cef_toolbar_->root_view();
}
}
return nullptr;
}

View File

@@ -8,6 +8,7 @@
#include "include/views/cef_browser_view.h"
#include "include/views/cef_browser_view_delegate.h"
#include "libcef/browser/chrome/views/toolbar_view_impl.h"
#include "libcef/browser/views/browser_view_view.h"
#include "libcef/browser/views/view_view.h"
@@ -42,6 +43,12 @@ class ChromeBrowserView
void AddedToWidget() override;
void OnBoundsChanged(const gfx::Rect& previous_bounds) override;
// BrowserView methods:
ToolbarView* OverrideCreateToolbar(Browser* browser,
BrowserView* browser_view) override;
CefRefPtr<CefToolbarViewImpl> cef_toolbar() const { return cef_toolbar_; }
private:
// Not owned by this object.
Delegate* browser_view_delegate_;
@@ -51,6 +58,8 @@ class ChromeBrowserView
bool destroyed_ = false;
CefRefPtr<CefToolbarViewImpl> cef_toolbar_;
DISALLOW_COPY_AND_ASSIGN(ChromeBrowserView);
};

View File

@@ -0,0 +1,40 @@
// Copyright 2021 The Chromium Embedded Framework Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be found
// in the LICENSE file.
#include "libcef/browser/chrome/views/toolbar_view_impl.h"
// static
CefRefPtr<CefToolbarViewImpl> CefToolbarViewImpl::Create(
CefRefPtr<CefViewDelegate> delegate,
Browser* browser,
BrowserView* browser_view,
base::Optional<ToolbarView::DisplayMode> display_mode) {
CEF_REQUIRE_UIT_RETURN(nullptr);
CefRefPtr<CefToolbarViewImpl> view =
new CefToolbarViewImpl(delegate, browser, browser_view, display_mode);
view->Initialize();
return view;
}
// static
const char* const CefToolbarViewImpl::kTypeString = "ToolbarView";
CefToolbarViewImpl::CefToolbarViewImpl(
CefRefPtr<CefViewDelegate> delegate,
Browser* browser,
BrowserView* browser_view,
base::Optional<ToolbarView::DisplayMode> display_mode)
: ParentClass(delegate),
browser_(browser),
browser_view_(browser_view),
display_mode_(display_mode) {}
CefToolbarViewView* CefToolbarViewImpl::CreateRootView() {
return new CefToolbarViewView(delegate(), browser_, browser_view_,
display_mode_);
}
void CefToolbarViewImpl::InitializeRootView() {
static_cast<CefToolbarViewView*>(root_view())->Initialize();
}

View File

@@ -0,0 +1,55 @@
// Copyright 2021 The Chromium Embedded Framework Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be found
// in the LICENSE file.
#ifndef CEF_LIBCEF_BROWSER_CHROME_VIEWS_TOOLBAR_VIEW_IMPL_H_
#define CEF_LIBCEF_BROWSER_CHROME_VIEWS_TOOLBAR_VIEW_IMPL_H_
#pragma once
#include "include/views/cef_view_delegate.h"
#include "libcef/browser/chrome/views/toolbar_view_view.h"
#include "libcef/browser/views/view_impl.h"
class Browser;
class BrowserView;
class CefToolbarViewImpl
: public CefViewImpl<CefToolbarViewView, CefView, CefViewDelegate> {
public:
typedef CefViewImpl<CefToolbarViewView, CefView, CefViewDelegate> ParentClass;
// Create a new CefToolbarViewImpl instance. |delegate| may be nullptr.
static CefRefPtr<CefToolbarViewImpl> Create(
CefRefPtr<CefViewDelegate> delegate,
Browser* browser,
BrowserView* browser_view,
base::Optional<ToolbarView::DisplayMode> display_mode);
static const char* const kTypeString;
// CefViewAdapter methods:
std::string GetDebugType() override { return kTypeString; }
private:
// Create a new implementation object.
// Always call Initialize() after creation.
// |delegate| may be nullptr.
CefToolbarViewImpl(CefRefPtr<CefViewDelegate> delegate,
Browser* browser,
BrowserView* browser_view,
base::Optional<ToolbarView::DisplayMode> display_mode);
// CefViewImpl methods:
CefToolbarViewView* CreateRootView() override;
void InitializeRootView() override;
Browser* const browser_;
BrowserView* const browser_view_;
base::Optional<ToolbarView::DisplayMode> const display_mode_;
IMPLEMENT_REFCOUNTING_DELETE_ON_UIT(CefToolbarViewImpl);
DISALLOW_COPY_AND_ASSIGN(CefToolbarViewImpl);
};
#endif // CEF_LIBCEF_BROWSER_VIEWS_SCROLL_VIEW_IMPL_H_

View File

@@ -0,0 +1,11 @@
// Copyright 2021 The Chromium Embedded Framework Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be found
// in the LICENSE file.
#include "libcef/browser/chrome/views/toolbar_view_view.h"
CefToolbarViewView::CefToolbarViewView(CefViewDelegate* cef_delegate,
Browser* browser,
BrowserView* browser_view,
base::Optional<DisplayMode> display_mode)
: ParentClass(cef_delegate, browser, browser_view, display_mode) {}

View File

@@ -0,0 +1,27 @@
// Copyright 2021 The Chromium Embedded Framework Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be found
// in the LICENSE file.
#ifndef CEF_LIBCEF_BROWSER_CHROME_VIEWS_TOOLBAR_VIEW_VIEW_H_
#define CEF_LIBCEF_BROWSER_CHROME_VIEWS_TOOLBAR_VIEW_VIEW_H_
#pragma once
#include "libcef/browser/views/view_view.h"
#include "chrome/browser/ui/views/toolbar/toolbar_view.h"
class CefToolbarViewView : public CefViewView<ToolbarView, CefViewDelegate> {
public:
typedef CefViewView<ToolbarView, CefViewDelegate> ParentClass;
// |cef_delegate| may be nullptr.
explicit CefToolbarViewView(CefViewDelegate* cef_delegate,
Browser* browser,
BrowserView* browser_view,
base::Optional<DisplayMode> display_mode);
private:
DISALLOW_COPY_AND_ASSIGN(CefToolbarViewView);
};
#endif // CEF_LIBCEF_BROWSER_CHROME_VIEWS_TOOLBAR_VIEW_VIEW_H_

View File

@@ -5,6 +5,7 @@
#include "libcef/browser/context.h"
#include "libcef/browser/browser_info_manager.h"
#include "libcef/browser/request_context_impl.h"
#include "libcef/browser/thread_util.h"
#include "libcef/browser/trace_subscriber.h"
#include "libcef/common/cef_switches.h"
@@ -434,8 +435,11 @@ void CefContext::PopulateGlobalRequestContextSettings(
settings->ignore_certificate_errors =
settings_.ignore_certificate_errors ||
command_line->HasSwitch(switches::kIgnoreCertificateErrors);
CefString(&settings->accept_language_list) =
CefString(&settings_.accept_language_list);
CefString(&settings->cookieable_schemes_list) =
CefString(&settings_.cookieable_schemes_list);
settings->cookieable_schemes_exclude_defaults =
settings_.cookieable_schemes_exclude_defaults;
}
void CefContext::NormalizeRequestContextSettings(
@@ -443,12 +447,6 @@ void CefContext::NormalizeRequestContextSettings(
// The |root_cache_path| value was already normalized in Initialize.
const base::FilePath& root_cache_path = CefString(&settings_.root_cache_path);
NormalizeCachePathAndSet(settings->cache_path, root_cache_path);
if (settings->accept_language_list.length == 0) {
// Use the global language list setting.
CefString(&settings->accept_language_list) =
CefString(&settings_.accept_language_list);
}
}
void CefContext::AddObserver(Observer* observer) {
@@ -469,12 +467,19 @@ bool CefContext::HasObserver(Observer* observer) const {
void CefContext::OnContextInitialized() {
CEF_REQUIRE_UIT();
// Notify the handler.
if (application_) {
CefRefPtr<CefBrowserProcessHandler> handler =
application_->GetBrowserProcessHandler();
if (handler)
handler->OnContextInitialized();
// Notify the handler after the global browser context has initialized.
CefRefPtr<CefRequestContext> request_context =
CefRequestContext::GetGlobalContext();
auto impl = static_cast<CefRequestContextImpl*>(request_context.get());
impl->ExecuteWhenBrowserContextInitialized(base::BindOnce(
[](CefRefPtr<CefApp> app) {
CefRefPtr<CefBrowserProcessHandler> handler =
app->GetBrowserProcessHandler();
if (handler)
handler->OnContextInitialized();
},
application_));
}
}

View File

@@ -533,6 +533,11 @@ void CefDevToolsFrontend::HandleMessageFromDevToolsFrontend(
void CefDevToolsFrontend::DispatchProtocolMessage(
content::DevToolsAgentHost* agent_host,
base::span<const uint8_t> message) {
if (!frontend_browser_->GetWebContents() ||
frontend_browser_->GetWebContents()->IsBeingDestroyed()) {
return;
}
base::StringPiece str_message(reinterpret_cast<const char*>(message.data()),
message.size());
if (ProtocolLoggingEnabled()) {

View File

@@ -366,7 +366,7 @@ base::DictionaryValue* CefExtensionFunctionDetails::OpenTab(
return nullptr;
CefBrowserCreateParams create_params;
create_params.url = url;
create_params.url = url.spec();
create_params.request_context = request_context;
create_params.window_info.reset(new CefWindowInfo);
@@ -381,9 +381,9 @@ base::DictionaryValue* CefExtensionFunctionDetails::OpenTab(
CefRefPtr<CefExtensionHandler> handler = cef_extension->GetHandler();
if (handler.get() &&
handler->OnBeforeBrowser(cef_extension, sender_browser.get(),
active_browser.get(), index, url.spec(), active,
*create_params.window_info, create_params.client,
create_params.settings)) {
active_browser.get(), index, create_params.url,
active, *create_params.window_info,
create_params.client, create_params.settings)) {
// Cancel the browser creation.
return nullptr;
}

View File

@@ -576,12 +576,12 @@ const Extension* CefExtensionSystem::LoadExtension(
// Insert first so that callbacks can retrieve the loaded extension.
extension_map_.insert(std::make_pair(extension->id(), cef_extension));
cef_extension->OnExtensionLoaded();
// This may trigger additional callbacks.
registry_->AddEnabled(extension.get());
NotifyExtensionLoaded(extension.get());
cef_extension->OnExtensionLoaded();
return extension.get();
}

View File

@@ -251,13 +251,13 @@ bool CefExtensionsBrowserClient::CreateBackgroundExtensionHost(
}
CefBrowserCreateParams create_params;
create_params.url = url;
create_params.url = url.spec();
create_params.request_context = request_context;
CefRefPtr<CefExtensionHandler> handler = cef_extension->GetHandler();
if (handler.get() && handler->OnBeforeBackgroundBrowser(
cef_extension, url.spec(), create_params.client,
create_params.settings)) {
cef_extension, create_params.url,
create_params.client, create_params.settings)) {
// Cancel the background host creation.
return true;
}

View File

@@ -12,12 +12,12 @@
#include "libcef/browser/navigate_params.h"
#include "libcef/browser/net_service/browser_urlrequest_impl.h"
#include "libcef/common/cef_messages.h"
#include "libcef/common/frame_util.h"
#include "libcef/common/frame_util.h"
#include "libcef/common/net/url_util.h"
#include "libcef/common/process_message_impl.h"
#include "libcef/common/request_impl.h"
#include "libcef/common/task_runner_impl.h"
#include "components/url_formatter/url_fixer.h"
#include "content/browser/renderer_host/frame_tree_node.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
@@ -310,16 +310,9 @@ void CefFrameHostImpl::NotifyMoveOrResizeStarted() {
void CefFrameHostImpl::Navigate(const CefNavigateParams& params) {
CefMsg_LoadRequest_Params request;
// Fix common problems with user-typed text. Among other things, this:
// - Converts absolute file paths to "file://" URLs.
// - Normalizes "about:" and "chrome:" to "chrome://" URLs.
// - Adds the "http://" scheme if none was specified.
request.url = url_formatter::FixupURL(params.url.possibly_invalid_spec(),
std::string());
if (!request.url.is_valid()) {
LOG(ERROR) << "Invalid URL: " << params.url.possibly_invalid_spec();
request.url = params.url;
if (!url_util::FixupGURL(request.url))
return;
}
request.method = params.method;
request.referrer = params.referrer.url;
@@ -347,16 +340,8 @@ void CefFrameHostImpl::LoadURLWithExtras(const std::string& url,
if (frame_id < CefFrameHostImpl::kMainFrameId)
return;
// Any necessary fixup of the URL will occur in
// [CefBrowserHostBase|CefFrameHostImpl]::Navigate().
GURL gurl(url);
if (!url.empty() && !gurl.is_valid() && !gurl.has_scheme()) {
std::string fixed_scheme(url::kHttpScheme);
fixed_scheme.append(url::kStandardSchemeSeparator);
std::string new_url = url;
new_url.insert(0, fixed_scheme);
gurl = GURL(new_url);
}
// Any necessary fixup will occur in Navigate.
GURL gurl = url_util::MakeGURL(url, /*fixup=*/false);
if (frame_id == CefFrameHostImpl::kMainFrameId) {
// Load via the browser using NavigationController.

View File

@@ -23,7 +23,9 @@ CefIOThreadState::CefIOThreadState() {
base::Unretained(this)));
}
CefIOThreadState::~CefIOThreadState() {}
CefIOThreadState::~CefIOThreadState() {
CEF_REQUIRE_IOT();
}
void CefIOThreadState::AddHandler(int render_process_id,
int render_frame_id,

View File

@@ -12,15 +12,18 @@
#include "libcef/browser/request_context_handler_map.h"
#include "content/public/browser/browser_thread.h"
class GURL;
// Stores state that will be accessed on the IO thread. Life span is controlled
// by CefBrowserContext. Created on the UI thread but accessed and destroyed on
// the IO thread. See browser_context.h for an object relationship diagram.
class CefIOThreadState {
class CefIOThreadState : public base::RefCountedThreadSafe<
CefIOThreadState,
content::BrowserThread::DeleteOnIOThread> {
public:
CefIOThreadState();
virtual ~CefIOThreadState();
// See comments in CefRequestContextHandlerMap.
void AddHandler(int render_process_id,
@@ -44,6 +47,12 @@ class CefIOThreadState {
CefRefPtr<CefSchemeHandlerFactory> GetSchemeHandlerFactory(const GURL& url);
private:
friend struct content::BrowserThread::DeleteOnThread<
content::BrowserThread::IO>;
friend class base::DeleteHelper<CefIOThreadState>;
~CefIOThreadState();
void InitOnIOThread();
// Map IDs to CefRequestContextHandler objects.

View File

@@ -144,11 +144,27 @@ CefMediaRouterImpl::CefMediaRouterImpl() {
}
void CefMediaRouterImpl::Initialize(
const CefBrowserContext::Getter& browser_context_getter) {
const CefBrowserContext::Getter& browser_context_getter,
CefRefPtr<CefCompletionCallback> callback) {
CEF_REQUIRE_UIT();
DCHECK(!initialized_);
DCHECK(!browser_context_getter.is_null());
DCHECK(browser_context_getter_.is_null());
browser_context_getter_ = browser_context_getter;
initialized_ = true;
if (!init_callbacks_.empty()) {
for (auto& callback : init_callbacks_) {
std::move(callback).Run();
}
init_callbacks_.clear();
}
if (callback) {
// Execute client callback asynchronously for consistency.
CEF_POST_TASK(CEF_UIT, base::Bind(&CefCompletionCallback::OnComplete,
callback.get()));
}
}
CefRefPtr<CefRegistration> CefMediaRouterImpl::AddObserver(
@@ -157,7 +173,8 @@ CefRefPtr<CefRegistration> CefMediaRouterImpl::AddObserver(
return nullptr;
CefRefPtr<CefRegistrationImpl> registration =
new CefRegistrationImpl(observer);
InitializeRegistrationOnUIThread(registration);
StoreOrTriggerInitCallback(base::BindOnce(
&CefMediaRouterImpl::InitializeRegistrationInternal, this, registration));
return registration.get();
}
@@ -181,11 +198,32 @@ CefRefPtr<CefMediaSource> CefMediaRouterImpl::GetSource(const CefString& urn) {
}
void CefMediaRouterImpl::NotifyCurrentSinks() {
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(
CEF_UIT, base::BindOnce(&CefMediaRouterImpl::NotifyCurrentSinks, this));
return;
}
StoreOrTriggerInitCallback(
base::BindOnce(&CefMediaRouterImpl::NotifyCurrentSinksInternal, this));
}
void CefMediaRouterImpl::CreateRoute(
CefRefPtr<CefMediaSource> source,
CefRefPtr<CefMediaSink> sink,
CefRefPtr<CefMediaRouteCreateCallback> callback) {
StoreOrTriggerInitCallback(base::BindOnce(
&CefMediaRouterImpl::CreateRouteInternal, this, source, sink, callback));
}
void CefMediaRouterImpl::NotifyCurrentRoutes() {
StoreOrTriggerInitCallback(
base::BindOnce(&CefMediaRouterImpl::NotifyCurrentRoutesInternal, this));
}
void CefMediaRouterImpl::InitializeRegistrationInternal(
CefRefPtr<CefRegistrationImpl> registration) {
DCHECK(ValidContext());
registration->Initialize(browser_context_getter_);
}
void CefMediaRouterImpl::NotifyCurrentSinksInternal() {
DCHECK(ValidContext());
auto browser_context = GetBrowserContext(browser_context_getter_);
if (!browser_context)
@@ -194,21 +232,17 @@ void CefMediaRouterImpl::NotifyCurrentSinks() {
browser_context->GetMediaRouterManager()->NotifyCurrentSinks();
}
void CefMediaRouterImpl::CreateRoute(
void CefMediaRouterImpl::CreateRouteInternal(
CefRefPtr<CefMediaSource> source,
CefRefPtr<CefMediaSink> sink,
CefRefPtr<CefMediaRouteCreateCallback> callback) {
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(CEF_UIT, base::BindOnce(&CefMediaRouterImpl::CreateRoute,
this, source, sink, callback));
return;
}
DCHECK(ValidContext());
std::string error;
auto browser_context = GetBrowserContext(browser_context_getter_);
if (!browser_context) {
error = "Context has already been destroyed";
error = "Context is not valid";
} else if (!source) {
error = "Source is empty or invalid";
} else if (!sink) {
@@ -234,12 +268,8 @@ void CefMediaRouterImpl::CreateRoute(
base::BindOnce(&CefMediaRouterImpl::CreateRouteCallback, this, callback));
}
void CefMediaRouterImpl::NotifyCurrentRoutes() {
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(CEF_UIT, base::BindOnce(
&CefMediaRouterImpl::NotifyCurrentRoutes, this));
return;
}
void CefMediaRouterImpl::NotifyCurrentRoutesInternal() {
DCHECK(ValidContext());
auto browser_context = GetBrowserContext(browser_context_getter_);
if (!browser_context)
@@ -248,22 +278,10 @@ void CefMediaRouterImpl::NotifyCurrentRoutes() {
browser_context->GetMediaRouterManager()->NotifyCurrentRoutes();
}
void CefMediaRouterImpl::InitializeRegistrationOnUIThread(
CefRefPtr<CefRegistrationImpl> registration) {
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(
CEF_UIT,
base::BindOnce(&CefMediaRouterImpl::InitializeRegistrationOnUIThread,
this, registration));
return;
}
registration->Initialize(browser_context_getter_);
}
void CefMediaRouterImpl::CreateRouteCallback(
CefRefPtr<CefMediaRouteCreateCallback> callback,
const media_router::RouteRequestResult& result) {
CEF_REQUIRE_UIT();
DCHECK(ValidContext());
if (result.result_code() != media_router::RouteRequestResult::OK) {
LOG(WARNING) << "Media route creation failed: " << result.error() << " ("
@@ -284,7 +302,30 @@ void CefMediaRouterImpl::CreateRouteCallback(
result.error(), route);
}
// static
CefRefPtr<CefMediaRouter> CefMediaRouter::GetGlobalMediaRouter() {
return CefRequestContext::GetGlobalContext()->GetMediaRouter();
void CefMediaRouterImpl::StoreOrTriggerInitCallback(
base::OnceClosure callback) {
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(
CEF_UIT, base::BindOnce(&CefMediaRouterImpl::StoreOrTriggerInitCallback,
this, std::move(callback)));
return;
}
if (initialized_) {
std::move(callback).Run();
} else {
init_callbacks_.emplace_back(std::move(callback));
}
}
bool CefMediaRouterImpl::ValidContext() const {
return CEF_CURRENTLY_ON_UIT() && initialized_;
}
// CefMediaRouter methods ------------------------------------------------------
// static
CefRefPtr<CefMediaRouter> CefMediaRouter::GetGlobalMediaRouter(
CefRefPtr<CefCompletionCallback> callback) {
return CefRequestContext::GetGlobalContext()->GetMediaRouter(callback);
}

View File

@@ -20,7 +20,8 @@ class CefMediaRouterImpl : public CefMediaRouter {
// Called on the UI thread after object creation and before any other object
// methods are executed on the UI thread.
void Initialize(const CefBrowserContext::Getter& browser_context_getter);
void Initialize(const CefBrowserContext::Getter& browser_context_getter,
CefRefPtr<CefCompletionCallback> callback);
// CefMediaRouter methods.
CefRefPtr<CefRegistration> AddObserver(
@@ -33,15 +34,29 @@ class CefMediaRouterImpl : public CefMediaRouter {
void NotifyCurrentRoutes() override;
private:
void InitializeRegistrationOnUIThread(
void InitializeRegistrationInternal(
CefRefPtr<CefRegistrationImpl> registration);
void NotifyCurrentSinksInternal();
void CreateRouteInternal(CefRefPtr<CefMediaSource> source,
CefRefPtr<CefMediaSink> sink,
CefRefPtr<CefMediaRouteCreateCallback> callback);
void NotifyCurrentRoutesInternal();
void CreateRouteCallback(CefRefPtr<CefMediaRouteCreateCallback> callback,
const media_router::RouteRequestResult& result);
// If the context is fully initialized execute |callback|, otherwise
// store it until the context is fully initialized.
void StoreOrTriggerInitCallback(base::OnceClosure callback);
bool ValidContext() const;
// Only accessed on the UI thread. Will be non-null after Initialize().
CefBrowserContext::Getter browser_context_getter_;
bool initialized_ = false;
std::vector<base::OnceClosure> init_callbacks_;
IMPLEMENT_REFCOUNTING(CefMediaRouterImpl);
DISALLOW_COPY_AND_ASSIGN(CefMediaRouterImpl);
};

View File

@@ -487,8 +487,7 @@ gfx::Vector2d CefBrowserPlatformDelegateNativeWin::GetUiWheelEventOffset(
}
base::TimeTicks CefBrowserPlatformDelegateNativeWin::GetEventTimeStamp() const {
return base::TimeTicks() +
base::TimeDelta::FromMilliseconds(GetMessageTime());
return base::TimeTicks::Now();
}
// static

View File

@@ -144,12 +144,18 @@ class CefBrowserURLRequest::Context
if (!url.is_valid())
return false;
CEF_POST_TASK(
CEF_UIT,
base::BindOnce(
&CefBrowserURLRequest::Context::GetURLLoaderFactoryGetterOnUIThread,
frame_, request_context_, weak_ptr_factory_.GetWeakPtr(),
task_runner_));
if (!request_context_) {
request_context_ = CefRequestContext::GetGlobalContext();
}
auto request_context_impl =
static_cast<CefRequestContextImpl*>(request_context_.get());
// Wait for the browser context to be initialized before continuing.
request_context_impl->ExecuteWhenBrowserContextInitialized(base::BindOnce(
&CefBrowserURLRequest::Context::GetURLLoaderFactoryGetterOnUIThread,
frame_, request_context_, weak_ptr_factory_.GetWeakPtr(),
task_runner_));
return true;
}
@@ -193,11 +199,12 @@ class CefBrowserURLRequest::Context
// Get or create the request context and browser context.
CefRefPtr<CefRequestContextImpl> request_context_impl =
CefRequestContextImpl::GetOrCreateForRequestContext(request_context);
DCHECK(request_context_impl);
CHECK(request_context_impl);
CefBrowserContext* cef_browser_context =
request_context_impl->GetBrowserContext();
DCHECK(cef_browser_context);
CHECK(cef_browser_context);
auto browser_context = cef_browser_context->AsBrowserContext();
CHECK(browser_context);
int render_frame_id = MSG_ROUTING_NONE;
scoped_refptr<net_service::URLLoaderFactoryGetter> loader_factory_getter;

View File

@@ -4,13 +4,11 @@
#include "libcef/browser/net_service/cookie_manager_impl.h"
#include "libcef/common/app_manager.h"
#include "libcef/common/net_service/net_service_util.h"
#include "libcef/common/time_util.h"
#include "base/bind.h"
#include "base/logging.h"
#include "base/no_destructor.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/storage_partition.h"
#include "services/network/public/mojom/cookie_manager.mojom.h"
@@ -117,25 +115,6 @@ void GetCookiesCallbackImpl(
GetAllCookiesCallbackImpl(visitor, browser_context_getter, cookies);
}
CefCookieManagerImpl::CookieableSchemes MakeSupportedSchemes(
const std::vector<CefString>& schemes,
bool include_defaults) {
std::vector<std::string> all_schemes;
for (const auto& scheme : schemes)
all_schemes.push_back(scheme);
if (include_defaults) {
// Add default schemes that should always support cookies.
// This list should match CookieMonster::kDefaultCookieableSchemes.
all_schemes.push_back("http");
all_schemes.push_back("https");
all_schemes.push_back("ws");
all_schemes.push_back("wss");
}
return base::make_optional(all_schemes);
}
} // namespace
CefCookieManagerImpl::CefCookieManagerImpl() {}
@@ -144,32 +123,19 @@ void CefCookieManagerImpl::Initialize(
CefBrowserContext::Getter browser_context_getter,
CefRefPtr<CefCompletionCallback> callback) {
CEF_REQUIRE_UIT();
DCHECK(!initialized_);
DCHECK(!browser_context_getter.is_null());
DCHECK(browser_context_getter_.is_null());
browser_context_getter_ = browser_context_getter;
RunAsyncCompletionOnUIThread(callback);
}
void CefCookieManagerImpl::SetSupportedSchemes(
const std::vector<CefString>& schemes,
bool include_defaults,
CefRefPtr<CefCompletionCallback> callback) {
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(CEF_UIT,
base::Bind(&CefCookieManagerImpl::SetSupportedSchemes, this,
schemes, include_defaults, callback));
return;
initialized_ = true;
if (!init_callbacks_.empty()) {
for (auto& callback : init_callbacks_) {
std::move(callback).Run();
}
init_callbacks_.clear();
}
auto browser_context = GetBrowserContext(browser_context_getter_);
if (!browser_context)
return;
// This will be forwarded to the CookieMonster that lives in the
// NetworkService process when the NetworkContext is created via
// AlloyContentBrowserClient::CreateNetworkContext.
browser_context->set_cookieable_schemes(
MakeSupportedSchemes(schemes, include_defaults));
RunAsyncCompletionOnUIThread(callback);
}
@@ -178,22 +144,14 @@ bool CefCookieManagerImpl::VisitAllCookies(
if (!visitor.get())
return false;
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(
CEF_UIT,
base::Bind(base::IgnoreResult(&CefCookieManagerImpl::VisitAllCookies),
this, visitor));
if (!ValidContext()) {
StoreOrTriggerInitCallback(base::BindOnce(
base::IgnoreResult(&CefCookieManagerImpl::VisitAllCookiesInternal),
this, visitor));
return true;
}
auto browser_context = GetBrowserContext(browser_context_getter_);
if (!browser_context)
return false;
GetCookieManager(browser_context)
->GetAllCookies(base::Bind(&GetAllCookiesCallbackImpl, visitor,
browser_context_getter_));
return true;
return VisitAllCookiesInternal(visitor);
}
bool CefCookieManagerImpl::VisitUrlCookies(
@@ -207,14 +165,87 @@ bool CefCookieManagerImpl::VisitUrlCookies(
if (!gurl.is_valid())
return false;
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(
CEF_UIT,
base::Bind(base::IgnoreResult(&CefCookieManagerImpl::VisitUrlCookies),
this, url, includeHttpOnly, visitor));
if (!ValidContext()) {
StoreOrTriggerInitCallback(base::BindOnce(
base::IgnoreResult(&CefCookieManagerImpl::VisitUrlCookiesInternal),
this, gurl, includeHttpOnly, visitor));
return true;
}
return VisitUrlCookiesInternal(gurl, includeHttpOnly, visitor);
}
bool CefCookieManagerImpl::SetCookie(const CefString& url,
const CefCookie& cookie,
CefRefPtr<CefSetCookieCallback> callback) {
GURL gurl = GURL(url.ToString());
if (!gurl.is_valid())
return false;
if (!ValidContext()) {
StoreOrTriggerInitCallback(base::BindOnce(
base::IgnoreResult(&CefCookieManagerImpl::SetCookieInternal), this,
gurl, cookie, callback));
return true;
}
return SetCookieInternal(gurl, cookie, callback);
}
bool CefCookieManagerImpl::DeleteCookies(
const CefString& url,
const CefString& cookie_name,
CefRefPtr<CefDeleteCookiesCallback> callback) {
// Empty URLs are allowed but not invalid URLs.
GURL gurl = GURL(url.ToString());
if (!gurl.is_empty() && !gurl.is_valid())
return false;
if (!ValidContext()) {
StoreOrTriggerInitCallback(base::BindOnce(
base::IgnoreResult(&CefCookieManagerImpl::DeleteCookiesInternal), this,
gurl, cookie_name, callback));
return true;
}
return DeleteCookiesInternal(gurl, cookie_name, callback);
}
bool CefCookieManagerImpl::FlushStore(
CefRefPtr<CefCompletionCallback> callback) {
if (!ValidContext()) {
StoreOrTriggerInitCallback(base::BindOnce(
base::IgnoreResult(&CefCookieManagerImpl::FlushStoreInternal), this,
callback));
return true;
}
return FlushStoreInternal(callback);
}
bool CefCookieManagerImpl::VisitAllCookiesInternal(
CefRefPtr<CefCookieVisitor> visitor) {
DCHECK(ValidContext());
DCHECK(visitor);
auto browser_context = GetBrowserContext(browser_context_getter_);
if (!browser_context)
return false;
GetCookieManager(browser_context)
->GetAllCookies(base::Bind(&GetAllCookiesCallbackImpl, visitor,
browser_context_getter_));
return true;
}
bool CefCookieManagerImpl::VisitUrlCookiesInternal(
const GURL& url,
bool includeHttpOnly,
CefRefPtr<CefCookieVisitor> visitor) {
DCHECK(ValidContext());
DCHECK(visitor);
DCHECK(url.is_valid());
net::CookieOptions options;
if (includeHttpOnly)
options.set_include_httponly();
@@ -226,26 +257,18 @@ bool CefCookieManagerImpl::VisitUrlCookies(
return false;
GetCookieManager(browser_context)
->GetCookieList(gurl, options,
->GetCookieList(url, options,
base::Bind(&GetCookiesCallbackImpl, visitor,
browser_context_getter_));
return true;
}
bool CefCookieManagerImpl::SetCookie(const CefString& url,
const CefCookie& cookie,
CefRefPtr<CefSetCookieCallback> callback) {
GURL gurl = GURL(url.ToString());
if (!gurl.is_valid())
return false;
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(
CEF_UIT,
base::Bind(base::IgnoreResult(&CefCookieManagerImpl::SetCookie), this,
url, cookie, callback));
return true;
}
bool CefCookieManagerImpl::SetCookieInternal(
const GURL& url,
const CefCookie& cookie,
CefRefPtr<CefSetCookieCallback> callback) {
DCHECK(ValidContext());
DCHECK(url.is_valid());
std::string name = CefString(&cookie.name).ToString();
std::string value = CefString(&cookie.value).ToString();
@@ -262,7 +285,7 @@ bool CefCookieManagerImpl::SetCookie(const CefString& url,
net_service::MakeCookiePriority(cookie.priority);
auto canonical_cookie = net::CanonicalCookie::CreateSanitizedCookie(
gurl, name, value, domain, path,
url, name, value, domain, path,
base::Time(), // Creation time.
expiration_time,
base::Time(), // Last access time.
@@ -287,39 +310,29 @@ bool CefCookieManagerImpl::SetCookie(const CefString& url,
return false;
GetCookieManager(browser_context)
->SetCanonicalCookie(*canonical_cookie, gurl, options,
->SetCanonicalCookie(*canonical_cookie, url, options,
base::Bind(SetCookieCallbackImpl, callback));
return true;
}
bool CefCookieManagerImpl::DeleteCookies(
const CefString& url,
bool CefCookieManagerImpl::DeleteCookiesInternal(
const GURL& url,
const CefString& cookie_name,
CefRefPtr<CefDeleteCookiesCallback> callback) {
// Empty URLs are allowed but not invalid URLs.
GURL gurl = GURL(url.ToString());
if (!gurl.is_empty() && !gurl.is_valid())
return false;
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(
CEF_UIT,
base::Bind(base::IgnoreResult(&CefCookieManagerImpl::DeleteCookies),
this, url, cookie_name, callback));
return true;
}
DCHECK(ValidContext());
DCHECK(url.is_empty() || url.is_valid());
network::mojom::CookieDeletionFilterPtr deletion_filter =
network::mojom::CookieDeletionFilter::New();
if (gurl.is_empty()) {
if (url.is_empty()) {
// Delete all cookies.
} else if (cookie_name.empty()) {
// Delete all matching host cookies.
deletion_filter->host_name = gurl.host();
deletion_filter->host_name = url.host();
} else {
// Delete all matching host and domain cookies.
deletion_filter->url = gurl;
deletion_filter->url = url;
deletion_filter->cookie_name = cookie_name;
}
@@ -333,15 +346,9 @@ bool CefCookieManagerImpl::DeleteCookies(
return true;
}
bool CefCookieManagerImpl::FlushStore(
bool CefCookieManagerImpl::FlushStoreInternal(
CefRefPtr<CefCompletionCallback> callback) {
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(
CEF_UIT,
base::Bind(base::IgnoreResult(&CefCookieManagerImpl::FlushStore), this,
callback));
return true;
}
DCHECK(ValidContext());
auto browser_context = GetBrowserContext(browser_context_getter_);
if (!browser_context)
@@ -352,24 +359,25 @@ bool CefCookieManagerImpl::FlushStore(
return true;
}
// static
CefCookieManagerImpl::CookieableSchemes
CefCookieManagerImpl::GetGlobalCookieableSchemes() {
CEF_REQUIRE_UIT();
void CefCookieManagerImpl::StoreOrTriggerInitCallback(
base::OnceClosure callback) {
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(
CEF_UIT,
base::BindOnce(&CefCookieManagerImpl::StoreOrTriggerInitCallback, this,
std::move(callback)));
return;
}
static base::NoDestructor<CookieableSchemes> schemes(
[]() -> CefCookieManagerImpl::CookieableSchemes {
if (auto application = CefAppManager::Get()->GetApplication()) {
if (auto handler = application->GetBrowserProcessHandler()) {
std::vector<CefString> schemes;
bool include_defaults = true;
handler->GetCookieableSchemes(schemes, include_defaults);
return MakeSupportedSchemes(schemes, include_defaults);
}
}
return base::nullopt;
}());
return *schemes;
if (initialized_) {
std::move(callback).Run();
} else {
init_callbacks_.emplace_back(std::move(callback));
}
}
bool CefCookieManagerImpl::ValidContext() const {
return CEF_CURRENTLY_ON_UIT() && initialized_;
}
// CefCookieManager methods ----------------------------------------------------

View File

@@ -23,9 +23,6 @@ class CefCookieManagerImpl : public CefCookieManager {
CefRefPtr<CefCompletionCallback> callback);
// CefCookieManager methods.
void SetSupportedSchemes(const std::vector<CefString>& schemes,
bool include_defaults,
CefRefPtr<CefCompletionCallback> callback) override;
bool VisitAllCookies(CefRefPtr<CefCookieVisitor> visitor) override;
bool VisitUrlCookies(const CefString& url,
bool includeHttpOnly,
@@ -38,13 +35,31 @@ class CefCookieManagerImpl : public CefCookieManager {
CefRefPtr<CefDeleteCookiesCallback> callback) override;
bool FlushStore(CefRefPtr<CefCompletionCallback> callback) override;
using CookieableSchemes = base::Optional<std::vector<std::string>>;
static CookieableSchemes GetGlobalCookieableSchemes();
private:
bool VisitAllCookiesInternal(CefRefPtr<CefCookieVisitor> visitor);
bool VisitUrlCookiesInternal(const GURL& url,
bool includeHttpOnly,
CefRefPtr<CefCookieVisitor> visitor);
bool SetCookieInternal(const GURL& url,
const CefCookie& cookie,
CefRefPtr<CefSetCookieCallback> callback);
bool DeleteCookiesInternal(const GURL& url,
const CefString& cookie_name,
CefRefPtr<CefDeleteCookiesCallback> callback);
bool FlushStoreInternal(CefRefPtr<CefCompletionCallback> callback);
// If the context is fully initialized execute |callback|, otherwise
// store it until the context is fully initialized.
void StoreOrTriggerInitCallback(base::OnceClosure callback);
bool ValidContext() const;
// Only accessed on the UI thread. Will be non-null after Initialize().
CefBrowserContext::Getter browser_context_getter_;
bool initialized_ = false;
std::vector<base::OnceClosure> init_callbacks_;
IMPLEMENT_REFCOUNTING(CefCookieManagerImpl);
DISALLOW_COPY_AND_ASSIGN(CefCookieManagerImpl);
};

View File

@@ -1302,16 +1302,19 @@ void ProxyURLLoaderFactory::CreateLoaderAndStart(
bool pass_through = false;
if (pass_through) {
// This is the so-called pass-through, no-op option.
target_factory_->CreateLoaderAndStart(
std::move(receiver), routing_id, request_id, options, request,
std::move(client), traffic_annotation);
if (target_factory_) {
target_factory_->CreateLoaderAndStart(
std::move(receiver), routing_id, request_id, options, request,
std::move(client), traffic_annotation);
}
return;
}
mojo::PendingRemote<network::mojom::URLLoaderFactory> target_factory_clone;
if (target_factory_)
if (target_factory_) {
target_factory_->Clone(
target_factory_clone.InitWithNewPipeAndPassReceiver());
}
InterceptedRequest* req = new InterceptedRequest(
this, RequestId(request_id, routing_id), options, request,

View File

@@ -11,6 +11,7 @@
#include "libcef/browser/net_service/proxy_url_loader_factory.h"
#include "libcef/browser/net_service/resource_handler_wrapper.h"
#include "libcef/browser/net_service/response_filter_wrapper.h"
#include "libcef/browser/prefs/browser_prefs.h"
#include "libcef/browser/thread_util.h"
#include "libcef/common/app_manager.h"
#include "libcef/common/net/scheme_registration.h"
@@ -28,7 +29,6 @@
#include "content/public/browser/web_contents.h"
#include "net/base/load_flags.h"
#include "net/http/http_status_code.h"
#include "net/http/http_util.h"
#include "third_party/blink/public/mojom/loader/resource_load_info.mojom-shared.h"
#include "ui/base/page_transition_types.h"
#include "url/origin.h"
@@ -78,28 +78,6 @@ class RequestCallbackWrapper : public CefRequestCallback {
DISALLOW_COPY_AND_ASSIGN(RequestCallbackWrapper);
};
std::string GetAcceptLanguageList(content::BrowserContext* browser_context,
CefRefPtr<CefBrowserHostBase> browser) {
if (browser) {
const CefBrowserSettings& browser_settings = browser->settings();
if (browser_settings.accept_language_list.length > 0) {
return CefString(&browser_settings.accept_language_list);
}
}
// This defaults to the value from CefRequestContextSettings via
// browser_prefs::CreatePrefService().
auto prefs = Profile::FromBrowserContext(browser_context)->GetPrefs();
return prefs->GetString(language::prefs::kAcceptLanguages);
}
// Match the logic in chrome/browser/net/profile_network_context_service.cc.
std::string ComputeAcceptLanguageFromPref(const std::string& language_pref) {
std::string accept_languages_str =
net::HttpUtil::ExpandLanguageList(language_pref);
return net::HttpUtil::GenerateAcceptLanguageHeader(accept_languages_str);
}
class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
public:
struct RequestState {
@@ -262,10 +240,9 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
browser_context_ = browser_context;
auto profile = Profile::FromBrowserContext(browser_context);
auto cef_browser_context =
CefBrowserContext::FromBrowserContext(profile->GetOriginalProfile());
auto cef_browser_context = CefBrowserContext::FromProfile(profile);
iothread_state_ = cef_browser_context->iothread_state();
DCHECK(iothread_state_);
CHECK(iothread_state_);
cookieable_schemes_ = cef_browser_context->GetCookieableSchemes();
// We register to be notified of CEF context or browser destruction so
@@ -289,8 +266,8 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
unhandled_request_callback_ = unhandled_request_callback;
// Default values for standard headers.
accept_language_ = ComputeAcceptLanguageFromPref(
GetAcceptLanguageList(browser_context, browser));
accept_language_ = browser_prefs::GetAcceptLanguageList(
cef_browser_context, browser.get(), /*expand=*/true);
DCHECK(!accept_language_.empty());
user_agent_ =
CefAppManager::Get()->GetContentClient()->browser()->GetUserAgent();
@@ -315,7 +292,7 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
CefRefPtr<CefBrowserHostBase> browser_;
CefRefPtr<CefFrame> frame_;
CefIOThreadState* iothread_state_ = nullptr;
scoped_refptr<CefIOThreadState> iothread_state_;
CefBrowserContext::CookieableSchemes cookieable_schemes_;
int render_process_id_ = 0;
int render_frame_id_ = -1;

View File

@@ -5,6 +5,8 @@
#include "libcef/browser/prefs/browser_prefs.h"
#include "libcef/browser/browser_context.h"
#include "libcef/browser/browser_host_base.h"
#include "libcef/browser/context.h"
#include "libcef/browser/media_capture_devices_dispatcher.h"
#include "libcef/browser/prefs/pref_store.h"
#include "libcef/browser/prefs/renderer_prefs.h"
@@ -57,6 +59,7 @@
#include "content/public/browser/browser_thread.h"
#include "extensions/browser/extension_prefs.h"
#include "extensions/buildflags/buildflags.h"
#include "net/http/http_util.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/ui_base_switches.h"
@@ -74,12 +77,35 @@ namespace browser_prefs {
namespace {
std::string GetAcceptLanguageList(Profile* profile) {
const CefRequestContextSettings& context_settings =
CefBrowserContext::FromBrowserContext(profile)->settings();
if (context_settings.accept_language_list.length > 0) {
return CefString(&context_settings.accept_language_list);
// Match the logic in chrome/browser/net/profile_network_context_service.cc.
std::string ComputeAcceptLanguageFromPref(const std::string& language_pref) {
std::string accept_languages_str =
net::HttpUtil::ExpandLanguageList(language_pref);
return net::HttpUtil::GenerateAcceptLanguageHeader(accept_languages_str);
}
// Return the most relevant setting based on |browser_context| and |browser|.
std::string GetAcceptLanguageListSetting(CefBrowserContext* browser_context,
CefBrowserHostBase* browser) {
if (browser) {
const auto& settings = browser->settings();
if (settings.accept_language_list.length > 0) {
return CefString(&settings.accept_language_list);
}
}
if (browser_context) {
const auto& settings = browser_context->settings();
if (settings.accept_language_list.length > 0) {
return CefString(&settings.accept_language_list);
}
}
const auto& settings = CefContext::Get()->settings();
if (settings.accept_language_list.length > 0) {
return CefString(&settings.accept_language_list);
}
return std::string();
}
@@ -88,6 +114,20 @@ std::string GetAcceptLanguageList(Profile* profile) {
const char kUserPrefsFileName[] = "UserPrefs.json";
const char kLocalPrefsFileName[] = "LocalPrefs.json";
void RegisterProfilePrefs(PrefRegistrySimple* registry) {
const base::CommandLine* command_line =
base::CommandLine::ForCurrentProcess();
if (command_line->HasSwitch(switches::kEnablePreferenceTesting)) {
// Preferences used with unit tests.
registry->RegisterBooleanPref("test.bool", true);
registry->RegisterIntegerPref("test.int", 2);
registry->RegisterDoublePref("test.double", 5.0);
registry->RegisterStringPref("test.string", "default");
registry->RegisterListPref("test.list");
registry->RegisterDictionaryPref("test.dict");
}
}
std::unique_ptr<PrefService> CreatePrefService(Profile* profile,
const base::FilePath& cache_path,
bool persist_user_preferences) {
@@ -209,16 +249,6 @@ std::unique_ptr<PrefService> CreatePrefService(Profile* profile,
false);
registry->RegisterBooleanPref(prefs::kWebRTCAllowLegacyTLSProtocols, false);
if (command_line->HasSwitch(switches::kEnablePreferenceTesting)) {
// Preferences used with unit tests.
registry->RegisterBooleanPref("test.bool", true);
registry->RegisterIntegerPref("test.int", 2);
registry->RegisterDoublePref("test.double", 5.0);
registry->RegisterStringPref("test.string", "default");
registry->RegisterListPref("test.list");
registry->RegisterDictionaryPref("test.dict");
}
if (profile) {
// Call RegisterProfilePrefs() for all services listed by
// EnsureBrowserContextKeyedServiceFactoriesBuilt().
@@ -235,6 +265,7 @@ std::unique_ptr<PrefService> CreatePrefService(Profile* profile,
MediaDeviceIDSalt::RegisterProfilePrefs(registry.get());
ProfileNetworkContextService::RegisterProfilePrefs(registry.get());
safe_browsing::RegisterProfilePrefs(registry.get());
RegisterProfilePrefs(registry.get());
const std::string& locale =
command_line->GetSwitchValueASCII(switches::kLang);
@@ -253,6 +284,7 @@ std::unique_ptr<PrefService> CreatePrefService(Profile* profile,
registry->RegisterStringPref(
prefs::kPrintPreviewDefaultDestinationSelectionRules, std::string());
registry->RegisterBooleanPref(prefs::kCloudPrintSubmitEnabled, false);
registry->RegisterBooleanPref(prefs::kEnableMediaRouter, true);
printing::PolicySettings::RegisterProfilePrefs(registry.get());
printing::PrintPreviewStickySettings::RegisterProfilePrefs(registry.get());
DownloadPrefs::RegisterProfilePrefs(registry.get());
@@ -289,7 +321,8 @@ std::unique_ptr<PrefService> CreatePrefService(Profile* profile,
// Language preferences. Used by ProfileNetworkContextService and
// InterceptedRequestHandlerWrapper.
const std::string& accept_language_list = GetAcceptLanguageList(profile);
const std::string& accept_language_list = GetAcceptLanguageListSetting(
CefBrowserContext::FromProfile(profile), /*browser=*/nullptr);
if (!accept_language_list.empty()) {
registry->SetDefaultPrefValue(language::prefs::kAcceptLanguages,
base::Value(accept_language_list));
@@ -301,12 +334,26 @@ std::unique_ptr<PrefService> CreatePrefService(Profile* profile,
return factory.CreateSyncable(registry.get());
}
void SetLanguagePrefs(Profile* profile) {
const std::string& accept_language_list = GetAcceptLanguageList(profile);
if (!accept_language_list.empty()) {
profile->GetPrefs()->SetString(language::prefs::kAcceptLanguages,
accept_language_list);
std::string GetAcceptLanguageList(CefBrowserContext* browser_context,
CefBrowserHostBase* browser,
bool expand) {
// Always prefer to the CEF settings configuration, if specified.
std::string accept_language_list =
GetAcceptLanguageListSetting(browser_context, browser);
if (accept_language_list.empty() && browser_context) {
// Fall back to the preference value. For the Alloy runtime the default
// value comes from browser_prefs::CreatePrefService() above. For the Chrome
// runtime the default value comes from the configured locale
// (IDS_ACCEPT_LANGUAGES) which is then overridden by the user preference in
// chrome://settings/languages, all managed by language::LanguagePrefs.
auto prefs = browser_context->AsProfile()->GetPrefs();
accept_language_list = prefs->GetString(language::prefs::kAcceptLanguages);
}
if (!accept_language_list.empty() && expand) {
return ComputeAcceptLanguageFromPref(accept_language_list);
}
return std::string();
}
} // namespace browser_prefs

View File

@@ -11,6 +11,9 @@ namespace base {
class FilePath;
}
class CefBrowserContext;
class CefBrowserHostBase;
class PrefRegistrySimple;
class PrefService;
class Profile;
@@ -19,14 +22,21 @@ namespace browser_prefs {
// Name for the user prefs JSON file.
extern const char kUserPrefsFileName[];
// Register preferences specific to CEF.
void RegisterProfilePrefs(PrefRegistrySimple* registry);
// Create the PrefService used to manage pref registration and storage.
// |profile| will be nullptr for the system-level PrefService.
std::unique_ptr<PrefService> CreatePrefService(Profile* profile,
const base::FilePath& cache_path,
bool persist_user_preferences);
// Set language preferences on |profile|.
void SetLanguagePrefs(Profile* profile);
// Returns the value for populating the accept-language HTTP request header.
// |browser_context| and/or |browser| may be nullptr. If |expand| is true then
// base languages and Q values may be added.
std::string GetAcceptLanguageList(CefBrowserContext* browser_context,
CefBrowserHostBase* browser,
bool expand);
} // namespace browser_prefs

View File

@@ -47,27 +47,6 @@ namespace renderer_prefs {
namespace {
// Set default values based on CEF command-line flags for preferences that are
// not available via the PrefService. Chromium command-line flags should not
// exist for these preferences.
void SetDefaultPrefs(blink::web_pref::WebPreferences& web) {
const base::CommandLine* command_line =
base::CommandLine::ForCurrentProcess();
web.javascript_enabled =
!command_line->HasSwitch(switches::kDisableJavascript);
web.allow_scripts_to_close_windows =
!command_line->HasSwitch(switches::kDisableJavascriptCloseWindows);
web.javascript_can_access_clipboard =
!command_line->HasSwitch(switches::kDisableJavascriptAccessClipboard);
web.allow_universal_access_from_file_urls =
command_line->HasSwitch(switches::kAllowUniversalAccessFromFileUrls);
web.shrinks_standalone_images_to_fit =
command_line->HasSwitch(switches::kImageShrinkStandaloneToFit);
web.text_areas_are_resizable =
!command_line->HasSwitch(switches::kDisableTextAreaResize);
}
// Chrome preferences.
// Should match ChromeContentBrowserClient::OverrideWebkitPrefs.
void SetChromePrefs(Profile* profile, blink::web_pref::WebPreferences& web) {
@@ -194,83 +173,6 @@ void SetExtensionPrefs(content::RenderViewHost* rvh,
extension_webkit_preferences::SetPreferences(extension, view_type, &web);
}
// Helper macro for setting a WebPreferences variable based on the value of a
// CefBrowserSettings variable.
#define SET_STATE(cef_var, web_var) \
if (cef_var == STATE_ENABLED) \
web_var = true; \
else if (cef_var == STATE_DISABLED) \
web_var = false;
// Set preferences based on CefBrowserSettings.
void SetCefPrefs(const CefBrowserSettings& cef,
blink::web_pref::WebPreferences& web) {
if (cef.standard_font_family.length > 0) {
web.standard_font_family_map[blink::web_pref::kCommonScript] =
CefString(&cef.standard_font_family);
}
if (cef.fixed_font_family.length > 0) {
web.fixed_font_family_map[blink::web_pref::kCommonScript] =
CefString(&cef.fixed_font_family);
}
if (cef.serif_font_family.length > 0) {
web.serif_font_family_map[blink::web_pref::kCommonScript] =
CefString(&cef.serif_font_family);
}
if (cef.sans_serif_font_family.length > 0) {
web.sans_serif_font_family_map[blink::web_pref::kCommonScript] =
CefString(&cef.sans_serif_font_family);
}
if (cef.cursive_font_family.length > 0) {
web.cursive_font_family_map[blink::web_pref::kCommonScript] =
CefString(&cef.cursive_font_family);
}
if (cef.fantasy_font_family.length > 0) {
web.fantasy_font_family_map[blink::web_pref::kCommonScript] =
CefString(&cef.fantasy_font_family);
}
if (cef.default_font_size > 0)
web.default_font_size = cef.default_font_size;
if (cef.default_fixed_font_size > 0)
web.default_fixed_font_size = cef.default_fixed_font_size;
if (cef.minimum_font_size > 0)
web.minimum_font_size = cef.minimum_font_size;
if (cef.minimum_logical_font_size > 0)
web.minimum_logical_font_size = cef.minimum_logical_font_size;
if (cef.default_encoding.length > 0)
web.default_encoding = CefString(&cef.default_encoding);
SET_STATE(cef.remote_fonts, web.remote_fonts_enabled);
SET_STATE(cef.javascript, web.javascript_enabled);
SET_STATE(cef.javascript_close_windows, web.allow_scripts_to_close_windows);
SET_STATE(cef.javascript_access_clipboard,
web.javascript_can_access_clipboard);
SET_STATE(cef.javascript_dom_paste, web.dom_paste_enabled);
SET_STATE(cef.plugins, web.plugins_enabled);
SET_STATE(cef.universal_access_from_file_urls,
web.allow_universal_access_from_file_urls);
SET_STATE(cef.file_access_from_file_urls,
web.allow_file_access_from_file_urls);
SET_STATE(cef.web_security, web.web_security_enabled);
SET_STATE(cef.image_loading, web.loads_images_automatically);
SET_STATE(cef.image_shrink_standalone_to_fit,
web.shrinks_standalone_images_to_fit);
SET_STATE(cef.text_area_resize, web.text_areas_are_resizable);
SET_STATE(cef.tab_to_links, web.tabs_to_links);
SET_STATE(cef.local_storage, web.local_storage_enabled);
SET_STATE(cef.databases, web.databases_enabled);
SET_STATE(cef.application_cache, web.application_cache_enabled);
// Never explicitly enable GPU-related functions in this method because the
// GPU blacklist is not being checked here.
if (cef.webgl == STATE_DISABLED) {
web.webgl1_enabled = false;
web.webgl2_enabled = false;
}
}
void SetString(CommandLinePrefStore* prefs,
const std::string& key,
const std::string& value) {
@@ -348,6 +250,99 @@ void SetCommandLinePrefDefaults(CommandLinePrefStore* prefs) {
SetBool(prefs, prefs::kWebKitPluginsEnabled, false);
}
void SetDefaultPrefs(blink::web_pref::WebPreferences& web) {
const base::CommandLine* command_line =
base::CommandLine::ForCurrentProcess();
web.javascript_enabled =
!command_line->HasSwitch(switches::kDisableJavascript);
web.allow_scripts_to_close_windows =
!command_line->HasSwitch(switches::kDisableJavascriptCloseWindows);
web.javascript_can_access_clipboard =
!command_line->HasSwitch(switches::kDisableJavascriptAccessClipboard);
web.allow_universal_access_from_file_urls =
command_line->HasSwitch(switches::kAllowUniversalAccessFromFileUrls);
web.shrinks_standalone_images_to_fit =
command_line->HasSwitch(switches::kImageShrinkStandaloneToFit);
web.text_areas_are_resizable =
!command_line->HasSwitch(switches::kDisableTextAreaResize);
}
// Helper macro for setting a WebPreferences variable based on the value of a
// CefBrowserSettings variable.
#define SET_STATE(cef_var, web_var) \
if (cef_var == STATE_ENABLED) \
web_var = true; \
else if (cef_var == STATE_DISABLED) \
web_var = false;
void SetCefPrefs(const CefBrowserSettings& cef,
blink::web_pref::WebPreferences& web) {
if (cef.standard_font_family.length > 0) {
web.standard_font_family_map[blink::web_pref::kCommonScript] =
CefString(&cef.standard_font_family);
}
if (cef.fixed_font_family.length > 0) {
web.fixed_font_family_map[blink::web_pref::kCommonScript] =
CefString(&cef.fixed_font_family);
}
if (cef.serif_font_family.length > 0) {
web.serif_font_family_map[blink::web_pref::kCommonScript] =
CefString(&cef.serif_font_family);
}
if (cef.sans_serif_font_family.length > 0) {
web.sans_serif_font_family_map[blink::web_pref::kCommonScript] =
CefString(&cef.sans_serif_font_family);
}
if (cef.cursive_font_family.length > 0) {
web.cursive_font_family_map[blink::web_pref::kCommonScript] =
CefString(&cef.cursive_font_family);
}
if (cef.fantasy_font_family.length > 0) {
web.fantasy_font_family_map[blink::web_pref::kCommonScript] =
CefString(&cef.fantasy_font_family);
}
if (cef.default_font_size > 0)
web.default_font_size = cef.default_font_size;
if (cef.default_fixed_font_size > 0)
web.default_fixed_font_size = cef.default_fixed_font_size;
if (cef.minimum_font_size > 0)
web.minimum_font_size = cef.minimum_font_size;
if (cef.minimum_logical_font_size > 0)
web.minimum_logical_font_size = cef.minimum_logical_font_size;
if (cef.default_encoding.length > 0)
web.default_encoding = CefString(&cef.default_encoding);
SET_STATE(cef.remote_fonts, web.remote_fonts_enabled);
SET_STATE(cef.javascript, web.javascript_enabled);
SET_STATE(cef.javascript_close_windows, web.allow_scripts_to_close_windows);
SET_STATE(cef.javascript_access_clipboard,
web.javascript_can_access_clipboard);
SET_STATE(cef.javascript_dom_paste, web.dom_paste_enabled);
SET_STATE(cef.plugins, web.plugins_enabled);
SET_STATE(cef.universal_access_from_file_urls,
web.allow_universal_access_from_file_urls);
SET_STATE(cef.file_access_from_file_urls,
web.allow_file_access_from_file_urls);
SET_STATE(cef.image_loading, web.loads_images_automatically);
SET_STATE(cef.image_shrink_standalone_to_fit,
web.shrinks_standalone_images_to_fit);
SET_STATE(cef.text_area_resize, web.text_areas_are_resizable);
SET_STATE(cef.tab_to_links, web.tabs_to_links);
SET_STATE(cef.local_storage, web.local_storage_enabled);
SET_STATE(cef.databases, web.databases_enabled);
SET_STATE(cef.application_cache, web.application_cache_enabled);
// Never explicitly enable GPU-related functions in this method because the
// GPU blacklist is not being checked here.
if (cef.webgl == STATE_DISABLED) {
web.webgl1_enabled = false;
web.webgl2_enabled = false;
}
}
void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry,
const std::string& locale) {
PrefsTabHelper::RegisterProfilePrefs(registry, locale);

View File

@@ -36,6 +36,15 @@ void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry,
// for these preferences.
void SetCommandLinePrefDefaults(CommandLinePrefStore* prefs);
// Set default values based on CEF command-line flags for preferences that are
// not available via the PrefService. Chromium command-line flags should not
// exist for these preferences.
void SetDefaultPrefs(blink::web_pref::WebPreferences& web);
// Set preferences based on CefBrowserSettings.
void SetCefPrefs(const CefBrowserSettings& cef,
blink::web_pref::WebPreferences& web);
// Populate WebPreferences based on a combination of command-line values,
// PrefService and CefBrowserSettings.
void PopulateWebPreferences(content::RenderViewHost* rvh,

View File

@@ -105,18 +105,15 @@ gfx::Size CefPrintDialogLinux::GetPdfPaperSize(
gfx::Size size;
CefRefPtr<CefApp> app = CefAppManager::Get()->GetApplication();
if (app.get()) {
CefRefPtr<CefBrowserProcessHandler> browser_handler =
app->GetBrowserProcessHandler();
if (browser_handler.get()) {
CefRefPtr<CefPrintHandler> handler = browser_handler->GetPrintHandler();
if (handler.get()) {
const printing::PrintSettings& settings = context->settings();
CefSize cef_size =
handler->GetPdfPaperSize(settings.device_units_per_inch());
size.SetSize(cef_size.width, cef_size.height);
}
auto browser = extensions::GetOwnerBrowserForFrameRoute(
context->render_process_id(), context->render_frame_id(), nullptr);
DCHECK(browser);
if (browser && browser->GetClient()) {
if (auto handler = browser->GetClient()->GetPrintHandler()) {
const printing::PrintSettings& settings = context->settings();
CefSize cef_size = handler->GetPdfPaperSize(
browser.get(), settings.device_units_per_inch());
size.SetSize(cef_size.width, cef_size.height);
}
}
@@ -131,11 +128,9 @@ gfx::Size CefPrintDialogLinux::GetPdfPaperSize(
void CefPrintDialogLinux::OnPrintStart(CefRefPtr<CefBrowserHostBase> browser) {
CEF_REQUIRE_UIT();
DCHECK(browser);
if (auto app = CefAppManager::Get()->GetApplication()) {
if (auto browser_handler = app->GetBrowserProcessHandler()) {
if (auto print_handler = browser_handler->GetPrintHandler()) {
print_handler->OnPrintStart(browser.get());
}
if (browser && browser->GetClient()) {
if (auto handler = browser->GetClient()->GetPrintHandler()) {
handler->OnPrintStart(browser.get());
}
}
}
@@ -235,12 +230,8 @@ void CefPrintDialogLinux::SetHandler() {
if (handler_.get())
return;
CefRefPtr<CefApp> app = CefAppManager::Get()->GetApplication();
if (app.get()) {
CefRefPtr<CefBrowserProcessHandler> browser_handler =
app->GetBrowserProcessHandler();
if (browser_handler.get())
handler_ = browser_handler->GetPrintHandler();
if (browser_ && browser_->GetClient()) {
handler_ = browser_->GetClient()->GetPrintHandler();
}
}

View File

@@ -228,17 +228,67 @@ CefRequestContextImpl::GetOrCreateForRequestContext(
return CefRequestContextImpl::GetOrCreateRequestContext(config);
}
bool CefRequestContextImpl::VerifyBrowserContext() const {
if (!CEF_CURRENTLY_ON_UIT()) {
NOTREACHED() << "called on invalid thread";
return false;
}
if (!browser_context() || !browser_context()->IsInitialized()) {
NOTREACHED() << "Uninitialized context";
return false;
}
return true;
}
CefBrowserContext* CefRequestContextImpl::GetBrowserContext() {
EnsureBrowserContext();
CHECK(VerifyBrowserContext());
return browser_context();
}
void CefRequestContextImpl::ExecuteWhenBrowserContextInitialized(
base::OnceClosure callback) {
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(
CEF_UIT,
base::BindOnce(
&CefRequestContextImpl::ExecuteWhenBrowserContextInitialized, this,
std::move(callback)));
return;
}
EnsureBrowserContext();
browser_context()->StoreOrTriggerInitCallback(std::move(callback));
}
void CefRequestContextImpl::GetBrowserContext(
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
const BrowserContextCallback& callback) {
BrowserContextCallback callback) {
if (!task_runner.get())
task_runner = CefTaskRunnerImpl::GetCurrentTaskRunner();
GetBrowserContextOnUIThread(task_runner, callback);
ExecuteWhenBrowserContextInitialized(base::BindOnce(
[](CefRefPtr<CefRequestContextImpl> context,
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
BrowserContextCallback callback) {
CEF_REQUIRE_UIT();
auto browser_context = context->browser_context();
DCHECK(browser_context->IsInitialized());
if (task_runner->BelongsToCurrentThread()) {
// Execute the callback immediately.
std::move(callback).Run(browser_context->getter());
} else {
// Execute the callback on the target thread.
task_runner->PostTask(
FROM_HERE,
base::BindOnce(std::move(callback), browser_context->getter()));
}
},
CefRefPtr<CefRequestContextImpl>(this), task_runner,
std::move(callback)));
}
bool CefRequestContextImpl::IsSame(CefRefPtr<CefRequestContext> other) {
@@ -312,7 +362,7 @@ CefString CefRequestContextImpl::GetCachePath() {
CefRefPtr<CefCookieManager> CefRequestContextImpl::GetCookieManager(
CefRefPtr<CefCompletionCallback> callback) {
CefRefPtr<CefCookieManagerImpl> cookie_manager = new CefCookieManagerImpl();
InitializeCookieManagerOnUIThread(cookie_manager, callback);
InitializeCookieManagerInternal(cookie_manager, callback);
return cookie_manager.get();
}
@@ -320,56 +370,45 @@ bool CefRequestContextImpl::RegisterSchemeHandlerFactory(
const CefString& scheme_name,
const CefString& domain_name,
CefRefPtr<CefSchemeHandlerFactory> factory) {
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(CEF_UIT,
base::BindOnce(
base::IgnoreResult(
&CefRequestContextImpl::RegisterSchemeHandlerFactory),
this, scheme_name, domain_name, factory));
return true;
}
GetBrowserContext(
content::GetUIThreadTaskRunner({}),
base::BindOnce(
[](const CefString& scheme_name, const CefString& domain_name,
CefRefPtr<CefSchemeHandlerFactory> factory,
CefBrowserContext::Getter browser_context_getter) {
auto browser_context = browser_context_getter.Run();
if (browser_context) {
browser_context->RegisterSchemeHandlerFactory(
scheme_name, domain_name, factory);
}
},
scheme_name, domain_name, factory));
// Make sure the browser context exists.
EnsureBrowserContext();
browser_context()->RegisterSchemeHandlerFactory(scheme_name, domain_name,
factory);
return true;
}
bool CefRequestContextImpl::ClearSchemeHandlerFactories() {
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(
CEF_UIT,
base::BindOnce(base::IgnoreResult(
&CefRequestContextImpl::ClearSchemeHandlerFactories),
this));
return true;
}
GetBrowserContext(
content::GetUIThreadTaskRunner({}),
base::BindOnce([](CefBrowserContext::Getter browser_context_getter) {
auto browser_context = browser_context_getter.Run();
if (browser_context)
browser_context->ClearSchemeHandlerFactories();
}));
// Make sure the browser context exists.
EnsureBrowserContext();
browser_context()->ClearSchemeHandlerFactories();
return true;
}
void CefRequestContextImpl::PurgePluginListCache(bool reload_pages) {
GetBrowserContext(
content::GetUIThreadTaskRunner({}),
base::Bind(&CefRequestContextImpl::PurgePluginListCacheInternal, this,
reload_pages));
base::BindOnce(&CefRequestContextImpl::PurgePluginListCacheInternal, this,
reload_pages));
}
bool CefRequestContextImpl::HasPreference(const CefString& name) {
// Verify that this method is being called on the UI thread.
if (!CEF_CURRENTLY_ON_UIT()) {
NOTREACHED() << "called on invalid thread";
if (!VerifyBrowserContext())
return false;
}
// Make sure the browser context exists.
EnsureBrowserContext();
PrefService* pref_service = browser_context()->AsProfile()->GetPrefs();
return (pref_service->FindPreference(name) != nullptr);
@@ -377,14 +416,8 @@ bool CefRequestContextImpl::HasPreference(const CefString& name) {
CefRefPtr<CefValue> CefRequestContextImpl::GetPreference(
const CefString& name) {
// Verify that this method is being called on the UI thread.
if (!CEF_CURRENTLY_ON_UIT()) {
NOTREACHED() << "called on invalid thread";
if (!VerifyBrowserContext())
return nullptr;
}
// Make sure the browser context exists.
EnsureBrowserContext();
PrefService* pref_service = browser_context()->AsProfile()->GetPrefs();
const PrefService::Preference* pref = pref_service->FindPreference(name);
@@ -395,14 +428,8 @@ CefRefPtr<CefValue> CefRequestContextImpl::GetPreference(
CefRefPtr<CefDictionaryValue> CefRequestContextImpl::GetAllPreferences(
bool include_defaults) {
// Verify that this method is being called on the UI thread.
if (!CEF_CURRENTLY_ON_UIT()) {
NOTREACHED() << "called on invalid thread";
if (!VerifyBrowserContext())
return nullptr;
}
// Make sure the browser context exists.
EnsureBrowserContext();
PrefService* pref_service = browser_context()->AsProfile()->GetPrefs();
@@ -419,14 +446,8 @@ CefRefPtr<CefDictionaryValue> CefRequestContextImpl::GetAllPreferences(
}
bool CefRequestContextImpl::CanSetPreference(const CefString& name) {
// Verify that this method is being called on the UI thread.
if (!CEF_CURRENTLY_ON_UIT()) {
NOTREACHED() << "called on invalid thread";
if (!VerifyBrowserContext())
return false;
}
// Make sure the browser context exists.
EnsureBrowserContext();
PrefService* pref_service = browser_context()->AsProfile()->GetPrefs();
const PrefService::Preference* pref = pref_service->FindPreference(name);
@@ -436,14 +457,8 @@ bool CefRequestContextImpl::CanSetPreference(const CefString& name) {
bool CefRequestContextImpl::SetPreference(const CefString& name,
CefRefPtr<CefValue> value,
CefString& error) {
// Verify that this method is being called on the UI thread.
if (!CEF_CURRENTLY_ON_UIT()) {
NOTREACHED() << "called on invalid thread";
if (!VerifyBrowserContext())
return false;
}
// Make sure the browser context exists.
EnsureBrowserContext();
PrefService* pref_service = browser_context()->AsProfile()->GetPrefs();
@@ -492,49 +507,53 @@ void CefRequestContextImpl::ClearCertificateExceptions(
CefRefPtr<CefCompletionCallback> callback) {
GetBrowserContext(
content::GetUIThreadTaskRunner({}),
base::Bind(&CefRequestContextImpl::ClearCertificateExceptionsInternal,
this, callback));
base::BindOnce(&CefRequestContextImpl::ClearCertificateExceptionsInternal,
this, callback));
}
void CefRequestContextImpl::ClearHttpAuthCredentials(
CefRefPtr<CefCompletionCallback> callback) {
GetBrowserContext(
content::GetUIThreadTaskRunner({}),
base::Bind(&CefRequestContextImpl::ClearHttpAuthCredentialsInternal, this,
callback));
base::BindOnce(&CefRequestContextImpl::ClearHttpAuthCredentialsInternal,
this, callback));
}
void CefRequestContextImpl::CloseAllConnections(
CefRefPtr<CefCompletionCallback> callback) {
GetBrowserContext(
content::GetUIThreadTaskRunner({}),
base::Bind(&CefRequestContextImpl::CloseAllConnectionsInternal, this,
callback));
base::BindOnce(&CefRequestContextImpl::CloseAllConnectionsInternal, this,
callback));
}
void CefRequestContextImpl::ResolveHost(
const CefString& origin,
CefRefPtr<CefResolveCallback> callback) {
GetBrowserContext(content::GetUIThreadTaskRunner({}),
base::Bind(&CefRequestContextImpl::ResolveHostInternal,
this, origin, callback));
base::BindOnce(&CefRequestContextImpl::ResolveHostInternal,
this, origin, callback));
}
void CefRequestContextImpl::LoadExtension(
const CefString& root_directory,
CefRefPtr<CefDictionaryValue> manifest,
CefRefPtr<CefExtensionHandler> handler) {
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(CEF_UIT,
base::BindOnce(&CefRequestContextImpl::LoadExtension, this,
root_directory, manifest, handler));
return;
}
// Make sure the browser context exists.
EnsureBrowserContext();
browser_context()->LoadExtension(root_directory, manifest, handler, this);
GetBrowserContext(content::GetUIThreadTaskRunner({}),
base::BindOnce(
[](const CefString& root_directory,
CefRefPtr<CefDictionaryValue> manifest,
CefRefPtr<CefExtensionHandler> handler,
CefRefPtr<CefRequestContextImpl> self,
CefBrowserContext::Getter browser_context_getter) {
auto browser_context = browser_context_getter.Run();
if (browser_context) {
browser_context->LoadExtension(
root_directory, manifest, handler, self);
}
},
root_directory, manifest, handler,
CefRefPtr<CefRequestContextImpl>(this)));
}
bool CefRequestContextImpl::DidLoadExtension(const CefString& extension_id) {
@@ -551,33 +570,24 @@ bool CefRequestContextImpl::GetExtensions(
std::vector<CefString>& extension_ids) {
extension_ids.clear();
if (!CEF_CURRENTLY_ON_UIT()) {
NOTREACHED() << "called on invalid thread";
if (!VerifyBrowserContext())
return false;
}
// Make sure the browser context exists.
EnsureBrowserContext();
return browser_context()->GetExtensions(extension_ids);
}
CefRefPtr<CefExtension> CefRequestContextImpl::GetExtension(
const CefString& extension_id) {
if (!CEF_CURRENTLY_ON_UIT()) {
NOTREACHED() << "called on invalid thread";
if (!VerifyBrowserContext())
return nullptr;
}
// Make sure the browser context exists.
EnsureBrowserContext();
return browser_context()->GetExtension(extension_id);
}
CefRefPtr<CefMediaRouter> CefRequestContextImpl::GetMediaRouter() {
CefRefPtr<CefMediaRouter> CefRequestContextImpl::GetMediaRouter(
CefRefPtr<CefCompletionCallback> callback) {
CefRefPtr<CefMediaRouterImpl> media_router = new CefMediaRouterImpl();
InitializeMediaRouterOnUIThread(media_router);
InitializeMediaRouterInternal(media_router, callback);
return media_router.get();
}
@@ -612,7 +622,17 @@ CefRequestContextImpl::GetOrCreateRequestContext(const Config& config) {
}
// The new context will be initialized later by EnsureBrowserContext().
return new CefRequestContextImpl(config);
CefRefPtr<CefRequestContextImpl> context = new CefRequestContextImpl(config);
// Initialize ASAP so that any tasks blocked on initialization will execute.
if (CEF_CURRENTLY_ON_UIT()) {
context->Initialize();
} else {
CEF_POST_TASK(CEF_UIT,
base::BindOnce(&CefRequestContextImpl::Initialize, context));
}
return context;
}
CefRequestContextImpl::CefRequestContextImpl(
@@ -626,8 +646,8 @@ void CefRequestContextImpl::Initialize() {
if (config_.other) {
// Share storage with |config_.other|.
browser_context_ = config_.other->GetBrowserContext();
DCHECK(browser_context_);
browser_context_ = config_.other->browser_context();
CHECK(browser_context_);
}
if (!browser_context_) {
@@ -645,16 +665,20 @@ void CefRequestContextImpl::Initialize() {
}
}
auto initialized_cb =
base::BindOnce(&CefRequestContextImpl::BrowserContextInitialized, this);
if (!browser_context_) {
// Create a new CefBrowserContext instance. If the cache path is non-
// empty then this new instance will become the globally registered
// CefBrowserContext for that path. Otherwise, this new instance will
// be a completely isolated "incognito mode" context.
browser_context_ =
CefAppManager::Get()->CreateNewBrowserContext(config_.settings);
browser_context_ = CefAppManager::Get()->CreateNewBrowserContext(
config_.settings, std::move(initialized_cb));
} else {
// Share the same settings as the existing context.
config_.settings = browser_context_->settings();
browser_context_->StoreOrTriggerInitCallback(std::move(initialized_cb));
}
// We'll disassociate from |browser_context_| on destruction.
@@ -666,9 +690,16 @@ void CefRequestContextImpl::Initialize() {
// IsSharedWith().
config_.other = nullptr;
}
}
if (config_.handler)
config_.handler->OnRequestContextInitialized(this);
void CefRequestContextImpl::BrowserContextInitialized() {
if (config_.handler) {
// Always execute asynchronously so the current call stack can unwind.
CEF_POST_TASK(
CEF_UIT,
base::BindOnce(&CefRequestContextHandler::OnRequestContextInitialized,
config_.handler, CefRefPtr<CefRequestContext>(this)));
}
}
void CefRequestContextImpl::EnsureBrowserContext() {
@@ -678,32 +709,13 @@ void CefRequestContextImpl::EnsureBrowserContext() {
DCHECK(browser_context());
}
void CefRequestContextImpl::GetBrowserContextOnUIThread(
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
const BrowserContextCallback& callback) {
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(
CEF_UIT, base::Bind(&CefRequestContextImpl::GetBrowserContextOnUIThread,
this, task_runner, callback));
return;
}
// Make sure the browser context exists.
EnsureBrowserContext();
if (task_runner->BelongsToCurrentThread()) {
// Execute the callback immediately.
callback.Run(browser_context());
} else {
// Execute the callback on the target thread.
task_runner->PostTask(FROM_HERE, base::Bind(callback, browser_context()));
}
}
void CefRequestContextImpl::PurgePluginListCacheInternal(
bool reload_pages,
CefBrowserContext* browser_context) {
CEF_REQUIRE_UIT();
CefBrowserContext::Getter browser_context_getter) {
auto browser_context = browser_context_getter.Run();
if (!browser_context)
return;
browser_context->ClearPluginLoadDecision(-1);
content::PluginService::GetInstance()->PurgePluginListCache(
browser_context->AsBrowserContext(), false);
@@ -711,8 +723,10 @@ void CefRequestContextImpl::PurgePluginListCacheInternal(
void CefRequestContextImpl::ClearCertificateExceptionsInternal(
CefRefPtr<CefCompletionCallback> callback,
CefBrowserContext* browser_context) {
CEF_REQUIRE_UIT();
CefBrowserContext::Getter browser_context_getter) {
auto browser_context = browser_context_getter.Run();
if (!browser_context)
return;
content::SSLHostStateDelegate* ssl_delegate =
browser_context->AsBrowserContext()->GetSSLHostStateDelegate();
@@ -727,8 +741,10 @@ void CefRequestContextImpl::ClearCertificateExceptionsInternal(
void CefRequestContextImpl::ClearHttpAuthCredentialsInternal(
CefRefPtr<CefCompletionCallback> callback,
CefBrowserContext* browser_context) {
CEF_REQUIRE_UIT();
CefBrowserContext::Getter browser_context_getter) {
auto browser_context = browser_context_getter.Run();
if (!browser_context)
return;
browser_context->GetNetworkContext()->ClearHttpAuthCache(
/*start_time=*/base::Time(), /*end_time=*/base::Time::Max(),
@@ -737,8 +753,10 @@ void CefRequestContextImpl::ClearHttpAuthCredentialsInternal(
void CefRequestContextImpl::CloseAllConnectionsInternal(
CefRefPtr<CefCompletionCallback> callback,
CefBrowserContext* browser_context) {
CEF_REQUIRE_UIT();
CefBrowserContext::Getter browser_context_getter) {
auto browser_context = browser_context_getter.Run();
if (!browser_context)
return;
browser_context->GetNetworkContext()->CloseAllConnections(
base::Bind(&CefCompletionCallback::OnComplete, callback));
@@ -747,41 +765,42 @@ void CefRequestContextImpl::CloseAllConnectionsInternal(
void CefRequestContextImpl::ResolveHostInternal(
const CefString& origin,
CefRefPtr<CefResolveCallback> callback,
CefBrowserContext* browser_context) {
CEF_REQUIRE_UIT();
CefBrowserContext::Getter browser_context_getter) {
auto browser_context = browser_context_getter.Run();
if (!browser_context)
return;
// |helper| will be deleted in ResolveHostHelper::OnComplete().
ResolveHostHelper* helper = new ResolveHostHelper(callback);
helper->Start(browser_context, origin);
}
void CefRequestContextImpl::InitializeCookieManagerOnUIThread(
void CefRequestContextImpl::InitializeCookieManagerInternal(
CefRefPtr<CefCookieManagerImpl> cookie_manager,
CefRefPtr<CefCompletionCallback> callback) {
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(
CEF_UIT,
base::Bind(&CefRequestContextImpl::InitializeCookieManagerOnUIThread,
this, cookie_manager, callback));
return;
}
auto browser_context = GetBrowserContext();
cookie_manager->Initialize(browser_context->getter(), callback);
GetBrowserContext(content::GetUIThreadTaskRunner({}),
base::BindOnce(
[](CefRefPtr<CefCookieManagerImpl> cookie_manager,
CefRefPtr<CefCompletionCallback> callback,
CefBrowserContext::Getter browser_context_getter) {
cookie_manager->Initialize(browser_context_getter,
callback);
},
cookie_manager, callback));
}
void CefRequestContextImpl::InitializeMediaRouterOnUIThread(
CefRefPtr<CefMediaRouterImpl> media_router) {
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(
CEF_UIT,
base::Bind(&CefRequestContextImpl::InitializeMediaRouterOnUIThread,
this, media_router));
return;
}
auto browser_context = GetBrowserContext();
media_router->Initialize(browser_context->getter());
void CefRequestContextImpl::InitializeMediaRouterInternal(
CefRefPtr<CefMediaRouterImpl> media_router,
CefRefPtr<CefCompletionCallback> callback) {
GetBrowserContext(content::GetUIThreadTaskRunner({}),
base::BindOnce(
[](CefRefPtr<CefMediaRouterImpl> media_router,
CefRefPtr<CefCompletionCallback> callback,
CefBrowserContext::Getter browser_context_getter) {
media_router->Initialize(browser_context_getter,
callback);
},
media_router, callback));
}
CefBrowserContext* CefRequestContextImpl::browser_context() const {

View File

@@ -30,17 +30,27 @@ class CefRequestContextImpl : public CefRequestContext {
static CefRefPtr<CefRequestContextImpl> GetOrCreateForRequestContext(
CefRefPtr<CefRequestContext> request_context);
// Returns the browser context object. Can only be called on the UI thread.
// Verify that the browser context can be directly accessed (e.g. on the UI
// thread and initialized).
bool VerifyBrowserContext() const;
// Returns the browser context object. Can only be called on the UI thread
// after the browser context has been initialized.
CefBrowserContext* GetBrowserContext();
// Executes |callback| either synchronously or asynchronously with the browser
// context object when it's available. If |task_runner| is NULL the callback
// will be executed on the originating thread. The resulting context object
// can only be accessed on the UI thread.
typedef base::Callback<void(CefBrowserContext*)> BrowserContextCallback;
// If the context is fully initialized execute |callback|, otherwise
// store it until the context is fully initialized.
void ExecuteWhenBrowserContextInitialized(base::OnceClosure callback);
// Executes |callback| either synchronously or asynchronously after the
// browser context object has been initialized. If |task_runner| is NULL the
// callback will be executed on the originating thread. The resulting getter
// can only be executed on the UI thread.
using BrowserContextCallback =
base::OnceCallback<void(CefBrowserContext::Getter)>;
void GetBrowserContext(
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
const BrowserContextCallback& callback);
BrowserContextCallback callback);
bool IsSame(CefRefPtr<CefRequestContext> other) override;
bool IsSharingWith(CefRefPtr<CefRequestContext> other) override;
@@ -77,7 +87,8 @@ class CefRequestContextImpl : public CefRequestContext {
bool HasExtension(const CefString& extension_id) override;
bool GetExtensions(std::vector<CefString>& extension_ids) override;
CefRefPtr<CefExtension> GetExtension(const CefString& extension_id) override;
CefRefPtr<CefMediaRouter> GetMediaRouter() override;
CefRefPtr<CefMediaRouter> GetMediaRouter(
CefRefPtr<CefCompletionCallback> callback) override;
const CefRequestContextSettings& settings() const { return config_.settings; }
@@ -128,33 +139,32 @@ class CefRequestContextImpl : public CefRequestContext {
explicit CefRequestContextImpl(const Config& config);
void Initialize();
void BrowserContextInitialized();
// Make sure the browser context exists. Only called on the UI thread.
void EnsureBrowserContext();
void GetBrowserContextOnUIThread(
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
const BrowserContextCallback& callback);
void PurgePluginListCacheInternal(bool reload_pages,
CefBrowserContext* browser_context);
void PurgePluginListCacheInternal(
bool reload_pages,
CefBrowserContext::Getter browser_context_getter);
void ClearCertificateExceptionsInternal(
CefRefPtr<CefCompletionCallback> callback,
CefBrowserContext* browser_context);
CefBrowserContext::Getter browser_context_getter);
void ClearHttpAuthCredentialsInternal(
CefRefPtr<CefCompletionCallback> callback,
CefBrowserContext* browser_context);
void CloseAllConnectionsInternal(CefRefPtr<CefCompletionCallback> callback,
CefBrowserContext* browser_context);
CefBrowserContext::Getter browser_context_getter);
void CloseAllConnectionsInternal(
CefRefPtr<CefCompletionCallback> callback,
CefBrowserContext::Getter browser_context_getter);
void ResolveHostInternal(const CefString& origin,
CefRefPtr<CefResolveCallback> callback,
CefBrowserContext* browser_context);
CefBrowserContext::Getter browser_context_getter);
void InitializeCookieManagerOnUIThread(
void InitializeCookieManagerInternal(
CefRefPtr<CefCookieManagerImpl> cookie_manager,
CefRefPtr<CefCompletionCallback> callback);
void InitializeMediaRouterOnUIThread(
CefRefPtr<CefMediaRouterImpl> media_router);
void InitializeMediaRouterInternal(CefRefPtr<CefMediaRouterImpl> media_router,
CefRefPtr<CefCompletionCallback> callback);
CefBrowserContext* browser_context() const;

View File

@@ -595,7 +595,7 @@ void CefServerImpl::ShutdownOnUIThread() {
if (thread_) {
// Stop the handler thread as a background task so the UI thread isn't
// blocked.
CEF_POST_BACKGROUND_TASK(BindOnce(
auto task = base::BindOnce(
[](std::unique_ptr<base::Thread> thread) {
// Calling PlatformThread::Join() on the UI thread is otherwise
// disallowed.
@@ -603,7 +603,15 @@ void CefServerImpl::ShutdownOnUIThread() {
scoped_allow_sync_primitives;
thread.reset();
},
std::move(thread_)));
std::move(thread_));
// Make sure the task is executed on shutdown. Otherwise, |thread| might
// be released outside of the correct scope.
base::PostTask(
FROM_HERE,
{base::ThreadPool(), base::TaskPriority::BEST_EFFORT,
base::TaskShutdownBehavior::BLOCK_SHUTDOWN, base::MayBlock()},
std::move(task));
// Release the reference that was added in StartupOnUIThread().
Release();

View File

@@ -0,0 +1,529 @@
// Copyright (c) 2021 The Chromium Embedded Framework Authors.
// Portions copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "libcef/browser/simple_menu_model_impl.h"
#include <vector>
#include "libcef/browser/thread_util.h"
#include "libcef/common/task_runner_impl.h"
namespace {
// Value based on the documentation on SimpleMenuModel::GetIndexOfCommandId().
const int kInvalidIndex = -1;
const int kInvalidCommandId = -1;
const int kInvalidGroupId = -1;
cef_menu_item_type_t GetCefItemType(ui::MenuModel::ItemType type) {
switch (type) {
case ui::MenuModel::TYPE_COMMAND:
return MENUITEMTYPE_COMMAND;
case ui::MenuModel::TYPE_CHECK:
return MENUITEMTYPE_CHECK;
case ui::MenuModel::TYPE_RADIO:
return MENUITEMTYPE_RADIO;
case ui::MenuModel::TYPE_SEPARATOR:
return MENUITEMTYPE_SEPARATOR;
case ui::MenuModel::TYPE_SUBMENU:
return MENUITEMTYPE_SUBMENU;
default:
return MENUITEMTYPE_NONE;
}
}
} // namespace
CefSimpleMenuModelImpl::CefSimpleMenuModelImpl(
ui::SimpleMenuModel* model,
ui::SimpleMenuModel::Delegate* delegate,
StateDelegate* state_delegate,
bool is_owned,
bool is_submenu)
: supported_thread_id_(base::PlatformThread::CurrentId()),
model_(model),
delegate_(delegate),
state_delegate_(state_delegate),
is_owned_(is_owned),
is_submenu_(is_submenu) {
DCHECK(model_);
DCHECK(delegate_);
DCHECK(state_delegate_);
}
CefSimpleMenuModelImpl::~CefSimpleMenuModelImpl() {
// Detach() must be called before object destruction.
DCHECK(!model_);
DCHECK(submenumap_.empty());
}
void CefSimpleMenuModelImpl::Detach() {
DCHECK(VerifyContext());
if (!submenumap_.empty()) {
auto it = submenumap_.begin();
for (; it != submenumap_.end(); ++it) {
it->second->Detach();
}
submenumap_.clear();
}
if (is_owned_)
delete model_;
model_ = nullptr;
}
bool CefSimpleMenuModelImpl::IsSubMenu() {
if (!VerifyContext())
return false;
return is_submenu_;
}
bool CefSimpleMenuModelImpl::Clear() {
if (!VerifyContext())
return false;
model_->Clear();
return true;
}
int CefSimpleMenuModelImpl::GetCount() {
if (!VerifyContext())
return 0;
return model_->GetItemCount();
}
bool CefSimpleMenuModelImpl::AddSeparator() {
if (!VerifyContext())
return false;
model_->AddSeparator(ui::NORMAL_SEPARATOR);
return true;
}
bool CefSimpleMenuModelImpl::AddItem(int command_id, const CefString& label) {
if (!VerifyContext())
return false;
model_->AddItem(command_id, label);
return true;
}
bool CefSimpleMenuModelImpl::AddCheckItem(int command_id,
const CefString& label) {
if (!VerifyContext())
return false;
model_->AddCheckItem(command_id, label);
return true;
}
bool CefSimpleMenuModelImpl::AddRadioItem(int command_id,
const CefString& label,
int group_id) {
if (!VerifyContext())
return false;
model_->AddRadioItem(command_id, label, group_id);
return true;
}
CefRefPtr<CefMenuModel> CefSimpleMenuModelImpl::AddSubMenu(
int command_id,
const CefString& label) {
if (!VerifyContext())
return nullptr;
auto new_menu = CreateNewSubMenu(nullptr);
model_->AddSubMenu(command_id, label, new_menu->model());
return new_menu;
}
bool CefSimpleMenuModelImpl::InsertSeparatorAt(int index) {
if (!VerifyContext())
return false;
model_->InsertSeparatorAt(index, ui::NORMAL_SEPARATOR);
return true;
}
bool CefSimpleMenuModelImpl::InsertItemAt(int index,
int command_id,
const CefString& label) {
if (!VerifyContext() || !ValidIndex(index))
return false;
model_->InsertItemAt(index, command_id, label);
return true;
}
bool CefSimpleMenuModelImpl::InsertCheckItemAt(int index,
int command_id,
const CefString& label) {
if (!VerifyContext() || !ValidIndex(index))
return false;
model_->InsertCheckItemAt(index, command_id, label);
return true;
}
bool CefSimpleMenuModelImpl::InsertRadioItemAt(int index,
int command_id,
const CefString& label,
int group_id) {
if (!VerifyContext() || !ValidIndex(index))
return false;
model_->InsertRadioItemAt(index, command_id, label, group_id);
return true;
}
CefRefPtr<CefMenuModel> CefSimpleMenuModelImpl::InsertSubMenuAt(
int index,
int command_id,
const CefString& label) {
if (!VerifyContext() || !ValidIndex(index))
return nullptr;
auto new_menu = CreateNewSubMenu(nullptr);
model_->InsertSubMenuAt(index, command_id, label, new_menu->model());
return new_menu;
}
bool CefSimpleMenuModelImpl::Remove(int command_id) {
return RemoveAt(GetIndexOf(command_id));
}
bool CefSimpleMenuModelImpl::RemoveAt(int index) {
if (!VerifyContext() || !ValidIndex(index))
return false;
auto* sub_menu =
static_cast<ui::SimpleMenuModel*>(model_->GetSubmenuModelAt(index));
if (sub_menu) {
auto it = submenumap_.find(sub_menu);
if (it != submenumap_.end()) {
it->second->Detach();
submenumap_.erase(it);
}
}
model_->RemoveItemAt(index);
return true;
}
int CefSimpleMenuModelImpl::GetIndexOf(int command_id) {
if (!VerifyContext())
return kInvalidIndex;
return model_->GetIndexOfCommandId(command_id);
}
int CefSimpleMenuModelImpl::GetCommandIdAt(int index) {
if (!VerifyContext() || !ValidIndex(index))
return kInvalidCommandId;
return model_->GetCommandIdAt(index);
}
bool CefSimpleMenuModelImpl::SetCommandIdAt(int index, int command_id) {
NOTIMPLEMENTED();
return false;
}
CefString CefSimpleMenuModelImpl::GetLabel(int command_id) {
return GetLabelAt(GetIndexOf(command_id));
}
CefString CefSimpleMenuModelImpl::GetLabelAt(int index) {
if (!VerifyContext() || !ValidIndex(index))
return CefString();
return model_->GetLabelAt(index);
}
bool CefSimpleMenuModelImpl::SetLabel(int command_id, const CefString& label) {
return SetLabelAt(GetIndexOf(command_id), label);
}
bool CefSimpleMenuModelImpl::SetLabelAt(int index, const CefString& label) {
if (!VerifyContext() || !ValidIndex(index))
return false;
model_->SetLabel(index, label);
return true;
}
CefSimpleMenuModelImpl::MenuItemType CefSimpleMenuModelImpl::GetType(
int command_id) {
return GetTypeAt(GetIndexOf(command_id));
}
CefSimpleMenuModelImpl::MenuItemType CefSimpleMenuModelImpl::GetTypeAt(
int index) {
if (!VerifyContext() || !ValidIndex(index))
return MENUITEMTYPE_NONE;
return GetCefItemType(model_->GetTypeAt(index));
}
int CefSimpleMenuModelImpl::GetGroupId(int command_id) {
return GetGroupIdAt(GetIndexOf(command_id));
}
int CefSimpleMenuModelImpl::GetGroupIdAt(int index) {
if (!VerifyContext() || !ValidIndex(index))
return kInvalidGroupId;
return model_->GetGroupIdAt(index);
}
bool CefSimpleMenuModelImpl::SetGroupId(int command_id, int group_id) {
return SetGroupIdAt(GetIndexOf(command_id), group_id);
}
bool CefSimpleMenuModelImpl::SetGroupIdAt(int index, int group_id) {
NOTIMPLEMENTED();
return false;
}
CefRefPtr<CefMenuModel> CefSimpleMenuModelImpl::GetSubMenu(int command_id) {
return GetSubMenuAt(GetIndexOf(command_id));
}
CefRefPtr<CefMenuModel> CefSimpleMenuModelImpl::GetSubMenuAt(int index) {
if (!VerifyContext() || !ValidIndex(index))
return nullptr;
auto* sub_model =
static_cast<ui::SimpleMenuModel*>(model_->GetSubmenuModelAt(index));
auto it = submenumap_.find(sub_model);
if (it != submenumap_.end())
return it->second;
return CreateNewSubMenu(sub_model);
}
bool CefSimpleMenuModelImpl::IsVisible(int command_id) {
return IsVisibleAt(GetIndexOf(command_id));
}
bool CefSimpleMenuModelImpl::IsVisibleAt(int index) {
if (!VerifyContext() || !ValidIndex(index))
return false;
return model_->IsVisibleAt(index);
}
bool CefSimpleMenuModelImpl::SetVisible(int command_id, bool visible) {
return SetVisibleAt(GetIndexOf(command_id), visible);
}
bool CefSimpleMenuModelImpl::SetVisibleAt(int index, bool visible) {
if (!VerifyContext() || !ValidIndex(index))
return false;
model_->SetVisibleAt(index, visible);
return true;
}
bool CefSimpleMenuModelImpl::IsEnabled(int command_id) {
return IsEnabledAt(GetIndexOf(command_id));
}
bool CefSimpleMenuModelImpl::IsEnabledAt(int index) {
if (!VerifyContext() || !ValidIndex(index))
return false;
return model_->IsEnabledAt(index);
}
bool CefSimpleMenuModelImpl::SetEnabled(int command_id, bool enabled) {
return SetEnabledAt(GetIndexOf(command_id), enabled);
}
bool CefSimpleMenuModelImpl::SetEnabledAt(int index, bool enabled) {
if (!VerifyContext() || !ValidIndex(index))
return false;
model_->SetEnabledAt(index, enabled);
return true;
}
bool CefSimpleMenuModelImpl::IsChecked(int command_id) {
return IsCheckedAt(GetIndexOf(command_id));
}
bool CefSimpleMenuModelImpl::IsCheckedAt(int index) {
if (!VerifyContext() || !ValidIndex(index))
return false;
return model_->IsItemCheckedAt(index);
}
bool CefSimpleMenuModelImpl::SetChecked(int command_id, bool checked) {
if (!VerifyContext() || command_id == kInvalidIndex)
return false;
state_delegate_->SetChecked(command_id, checked);
return true;
}
bool CefSimpleMenuModelImpl::SetCheckedAt(int index, bool checked) {
return SetChecked(GetCommandIdAt(index), checked);
}
bool CefSimpleMenuModelImpl::HasAccelerator(int command_id) {
return HasAcceleratorAt(GetIndexOf(command_id));
}
bool CefSimpleMenuModelImpl::HasAcceleratorAt(int index) {
if (!VerifyContext() || !ValidIndex(index))
return false;
ui::Accelerator accelerator;
return model_->GetAcceleratorAt(index, &accelerator);
}
bool CefSimpleMenuModelImpl::SetAccelerator(int command_id,
int key_code,
bool shift_pressed,
bool ctrl_pressed,
bool alt_pressed) {
if (!VerifyContext() || command_id == kInvalidIndex)
return false;
int modifiers = 0;
if (shift_pressed)
modifiers |= ui::EF_SHIFT_DOWN;
if (ctrl_pressed)
modifiers |= ui::EF_CONTROL_DOWN;
if (alt_pressed)
modifiers |= ui::EF_ALT_DOWN;
state_delegate_->SetAccelerator(
command_id,
ui::Accelerator(static_cast<ui::KeyboardCode>(key_code), modifiers));
return true;
}
bool CefSimpleMenuModelImpl::SetAcceleratorAt(int index,
int key_code,
bool shift_pressed,
bool ctrl_pressed,
bool alt_pressed) {
return SetAccelerator(GetCommandIdAt(index), key_code, shift_pressed,
ctrl_pressed, alt_pressed);
}
bool CefSimpleMenuModelImpl::RemoveAccelerator(int command_id) {
if (!VerifyContext() || command_id == kInvalidIndex)
return false;
state_delegate_->SetAccelerator(command_id, base::nullopt);
return true;
}
bool CefSimpleMenuModelImpl::RemoveAcceleratorAt(int index) {
return RemoveAccelerator(GetCommandIdAt(index));
}
bool CefSimpleMenuModelImpl::GetAccelerator(int command_id,
int& key_code,
bool& shift_pressed,
bool& ctrl_pressed,
bool& alt_pressed) {
return GetAcceleratorAt(GetIndexOf(command_id), key_code, shift_pressed,
ctrl_pressed, alt_pressed);
}
bool CefSimpleMenuModelImpl::GetAcceleratorAt(int index,
int& key_code,
bool& shift_pressed,
bool& ctrl_pressed,
bool& alt_pressed) {
if (!VerifyContext() || !ValidIndex(index))
return false;
ui::Accelerator accel;
if (model_->GetAcceleratorAt(index, &accel)) {
key_code = accel.key_code();
shift_pressed = accel.modifiers() & ui::EF_SHIFT_DOWN;
ctrl_pressed = accel.modifiers() & ui::EF_CONTROL_DOWN;
alt_pressed = accel.modifiers() & ui::EF_ALT_DOWN;
return true;
}
return false;
}
bool CefSimpleMenuModelImpl::SetColor(int command_id,
cef_menu_color_type_t color_type,
cef_color_t color) {
NOTIMPLEMENTED();
return false;
}
bool CefSimpleMenuModelImpl::SetColorAt(int index,
cef_menu_color_type_t color_type,
cef_color_t color) {
NOTIMPLEMENTED();
return false;
}
bool CefSimpleMenuModelImpl::GetColor(int command_id,
cef_menu_color_type_t color_type,
cef_color_t& color) {
NOTIMPLEMENTED();
return false;
}
bool CefSimpleMenuModelImpl::GetColorAt(int index,
cef_menu_color_type_t color_type,
cef_color_t& color) {
NOTIMPLEMENTED();
return false;
}
bool CefSimpleMenuModelImpl::SetFontList(int command_id,
const CefString& font_list) {
NOTIMPLEMENTED();
return false;
}
bool CefSimpleMenuModelImpl::SetFontListAt(int index,
const CefString& font_list) {
NOTIMPLEMENTED();
return false;
}
bool CefSimpleMenuModelImpl::VerifyContext() {
if (base::PlatformThread::CurrentId() != supported_thread_id_) {
// This object should only be accessed from the thread that created it.
NOTREACHED();
return false;
}
if (!model_)
return false;
return true;
}
bool CefSimpleMenuModelImpl::ValidIndex(int index) {
return index > kInvalidIndex && index < model_->GetItemCount();
}
CefRefPtr<CefSimpleMenuModelImpl> CefSimpleMenuModelImpl::CreateNewSubMenu(
ui::SimpleMenuModel* model) {
bool is_owned = false;
if (!model) {
model = new ui::SimpleMenuModel(delegate_);
is_owned = true;
}
CefRefPtr<CefSimpleMenuModelImpl> new_impl = new CefSimpleMenuModelImpl(
model, delegate_, state_delegate_, is_owned, /*is_submodel=*/true);
submenumap_.insert(std::make_pair(model, new_impl));
return new_impl;
}

View File

@@ -0,0 +1,166 @@
// Copyright (c) 2021 The Chromium Embedded Framework Authors.
// Portions copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CEF_LIBCEF_BROWSER_SIMPLE_MENU_MODEL_IMPL_H_
#define CEF_LIBCEF_BROWSER_SIMPLE_MENU_MODEL_IMPL_H_
#pragma once
#include <vector>
#include "include/cef_menu_model.h"
#include "base/threading/platform_thread.h"
#include "ui/base/models/simple_menu_model.h"
// Implementation of CefMenuModel that wraps an existing ui::SimpleMenuModel.
class CefSimpleMenuModelImpl : public CefMenuModel {
public:
// Interface for setting state using CefMenuModel methods that will later be
// retrieved via the ui::SimpleMenuModel::Delegate implementation.
class StateDelegate {
public:
virtual void SetChecked(int command_id, bool checked) = 0;
virtual void SetAccelerator(int command_id,
base::Optional<ui::Accelerator> accel) = 0;
protected:
virtual ~StateDelegate() {}
};
// |delegate| should be the same that was used to create |model|.
// If |is_owned| is true then |model| will be deleted on Detach().
CefSimpleMenuModelImpl(ui::SimpleMenuModel* model,
ui::SimpleMenuModel::Delegate* delegate,
StateDelegate* state_delegate,
bool is_owned,
bool is_submenu);
~CefSimpleMenuModelImpl() override;
// Must be called before the object is deleted.
void Detach();
// CefMenuModel methods.
bool IsSubMenu() override;
bool Clear() override;
int GetCount() override;
bool AddSeparator() override;
bool AddItem(int command_id, const CefString& label) override;
bool AddCheckItem(int command_id, const CefString& label) override;
bool AddRadioItem(int command_id,
const CefString& label,
int group_id) override;
CefRefPtr<CefMenuModel> AddSubMenu(int command_id,
const CefString& label) override;
bool InsertSeparatorAt(int index) override;
bool InsertItemAt(int index, int command_id, const CefString& label) override;
bool InsertCheckItemAt(int index,
int command_id,
const CefString& label) override;
bool InsertRadioItemAt(int index,
int command_id,
const CefString& label,
int group_id) override;
CefRefPtr<CefMenuModel> InsertSubMenuAt(int index,
int command_id,
const CefString& label) override;
bool Remove(int command_id) override;
bool RemoveAt(int index) override;
int GetIndexOf(int command_id) override;
int GetCommandIdAt(int index) override;
bool SetCommandIdAt(int index, int command_id) override;
CefString GetLabel(int command_id) override;
CefString GetLabelAt(int index) override;
bool SetLabel(int command_id, const CefString& label) override;
bool SetLabelAt(int index, const CefString& label) override;
MenuItemType GetType(int command_id) override;
MenuItemType GetTypeAt(int index) override;
int GetGroupId(int command_id) override;
int GetGroupIdAt(int index) override;
bool SetGroupId(int command_id, int group_id) override;
bool SetGroupIdAt(int index, int group_id) override;
CefRefPtr<CefMenuModel> GetSubMenu(int command_id) override;
CefRefPtr<CefMenuModel> GetSubMenuAt(int index) override;
bool IsVisible(int command_id) override;
bool IsVisibleAt(int index) override;
bool SetVisible(int command_id, bool visible) override;
bool SetVisibleAt(int index, bool visible) override;
bool IsEnabled(int command_id) override;
bool IsEnabledAt(int index) override;
bool SetEnabled(int command_id, bool enabled) override;
bool SetEnabledAt(int index, bool enabled) override;
bool IsChecked(int command_id) override;
bool IsCheckedAt(int index) override;
bool SetChecked(int command_id, bool checked) override;
bool SetCheckedAt(int index, bool checked) override;
bool HasAccelerator(int command_id) override;
bool HasAcceleratorAt(int index) override;
bool SetAccelerator(int command_id,
int key_code,
bool shift_pressed,
bool ctrl_pressed,
bool alt_pressed) override;
bool SetAcceleratorAt(int index,
int key_code,
bool shift_pressed,
bool ctrl_pressed,
bool alt_pressed) override;
bool RemoveAccelerator(int command_id) override;
bool RemoveAcceleratorAt(int index) override;
bool GetAccelerator(int command_id,
int& key_code,
bool& shift_pressed,
bool& ctrl_pressed,
bool& alt_pressed) override;
bool GetAcceleratorAt(int index,
int& key_code,
bool& shift_pressed,
bool& ctrl_pressed,
bool& alt_pressed) override;
bool SetColor(int command_id,
cef_menu_color_type_t color_type,
cef_color_t color) override;
bool SetColorAt(int index,
cef_menu_color_type_t color_type,
cef_color_t color) override;
bool GetColor(int command_id,
cef_menu_color_type_t color_type,
cef_color_t& color) override;
bool GetColorAt(int index,
cef_menu_color_type_t color_type,
cef_color_t& color) override;
bool SetFontList(int command_id, const CefString& font_list) override;
bool SetFontListAt(int index, const CefString& font_list) override;
ui::SimpleMenuModel* model() const { return model_; }
private:
// Verify that the object is attached and being accessed from the correct
// thread.
bool VerifyContext();
// Returns true if |index| is valid.
bool ValidIndex(int index);
CefRefPtr<CefSimpleMenuModelImpl> CreateNewSubMenu(
ui::SimpleMenuModel* model);
base::PlatformThreadId supported_thread_id_;
ui::SimpleMenuModel* model_;
ui::SimpleMenuModel::Delegate* const delegate_;
StateDelegate* const state_delegate_;
const bool is_owned_;
const bool is_submenu_;
// Keep the submenus alive until they're removed, or we're destroyed.
using SubMenuMap =
std::map<ui::SimpleMenuModel*, CefRefPtr<CefSimpleMenuModelImpl>>;
SubMenuMap submenumap_;
IMPLEMENT_REFCOUNTING(CefSimpleMenuModelImpl);
DISALLOW_COPY_AND_ASSIGN(CefSimpleMenuModelImpl);
};
#endif // CEF_LIBCEF_BROWSER_SIMPLE_MENU_MODEL_IMPL_H_

View File

@@ -8,10 +8,9 @@
#include "libcef/browser/browser_util.h"
#include "libcef/browser/chrome/views/chrome_browser_view.h"
#include "libcef/browser/context.h"
#include "libcef/browser/request_context_impl.h"
#include "libcef/browser/thread_util.h"
#include "libcef/browser/views/window_impl.h"
#include "libcef/features/runtime.h"
#include "libcef/features/runtime_checks.h"
#include "content/public/browser/native_web_keyboard_event.h"
#include "ui/content_accelerators/accelerator_util.h"
@@ -50,6 +49,18 @@ CefRefPtr<CefBrowserViewImpl> CefBrowserViewImpl::Create(
CefRefPtr<CefBrowserViewDelegate> delegate) {
CEF_REQUIRE_UIT_RETURN(nullptr);
if (!request_context) {
request_context = CefRequestContext::GetGlobalContext();
}
// Verify that the browser context is valid. Do this here instead of risking
// potential browser creation failure when this view is added to the window.
auto request_context_impl =
static_cast<CefRequestContextImpl*>(request_context.get());
if (!request_context_impl->VerifyBrowserContext()) {
return nullptr;
}
CefRefPtr<CefBrowserViewImpl> browser_view = new CefBrowserViewImpl(delegate);
browser_view->SetPendingBrowserCreateParams(client, url, settings, extra_info,
request_context);
@@ -62,7 +73,6 @@ CefRefPtr<CefBrowserViewImpl> CefBrowserViewImpl::Create(
CefRefPtr<CefBrowserViewImpl> CefBrowserViewImpl::CreateForPopup(
const CefBrowserSettings& settings,
CefRefPtr<CefBrowserViewDelegate> delegate) {
REQUIRE_ALLOY_RUNTIME();
CEF_REQUIRE_UIT_RETURN(nullptr);
CefRefPtr<CefBrowserViewImpl> browser_view = new CefBrowserViewImpl(delegate);
@@ -126,6 +136,15 @@ CefRefPtr<CefBrowser> CefBrowserViewImpl::GetBrowser() {
return browser_;
}
CefRefPtr<CefView> CefBrowserViewImpl::GetChromeToolbar() {
CEF_REQUIRE_VALID_RETURN(nullptr);
if (cef::IsChromeRuntimeEnabled()) {
return static_cast<ChromeBrowserView*>(root_view())->cef_toolbar();
}
return nullptr;
}
void CefBrowserViewImpl::SetPreferAccelerators(bool prefer_accelerators) {
CEF_REQUIRE_VALID_RETURN_VOID();
if (web_view())
@@ -201,7 +220,7 @@ void CefBrowserViewImpl::SetPendingBrowserCreateParams(
DCHECK(!pending_browser_create_params_);
pending_browser_create_params_.reset(new CefBrowserCreateParams());
pending_browser_create_params_->client = client;
pending_browser_create_params_->url = GURL(url.ToString());
pending_browser_create_params_->url = url;
pending_browser_create_params_->settings = settings;
pending_browser_create_params_->extra_info = extra_info;
pending_browser_create_params_->request_context = request_context;

View File

@@ -53,6 +53,7 @@ class CefBrowserViewImpl
// CefBrowserView methods:
CefRefPtr<CefBrowser> GetBrowser() override;
CefRefPtr<CefView> GetChromeToolbar() override;
void SetPreferAccelerators(bool prefer_accelerators) override;
// CefView methods:

View File

@@ -28,8 +28,9 @@ CEF_BUTTON_VIEW_T class CefButtonView : public CEF_VIEW_VIEW_D {
typedef CEF_VIEW_VIEW_D ParentClass;
// |cef_delegate| may be nullptr.
explicit CefButtonView(CefViewDelegateClass* cef_delegate)
: ParentClass(cef_delegate) {}
template <typename... Args>
explicit CefButtonView(CefViewDelegateClass* cef_delegate, Args... args)
: ParentClass(cef_delegate, args...) {}
// Returns the CefButton associated with this view. See comments on
// CefViewView::GetCefView.

View File

@@ -25,8 +25,9 @@ CEF_LABEL_BUTTON_VIEW_T class CefLabelButtonView : public CEF_BUTTON_VIEW_D {
typedef CEF_BUTTON_VIEW_D ParentClass;
// |cef_delegate| may be nullptr.
explicit CefLabelButtonView(CefViewDelegateClass* cef_delegate)
: ParentClass(cef_delegate) {}
template <typename... Args>
explicit CefLabelButtonView(CefViewDelegateClass* cef_delegate, Args... args)
: ParentClass(cef_delegate, args...) {}
void Initialize() override {
ParentClass::Initialize();

View File

@@ -113,12 +113,14 @@ CEF_PANEL_IMPL_T void CEF_PANEL_IMPL_D::AddChildView(CefRefPtr<CefView> view) {
CEF_REQUIRE_VALID_RETURN_VOID();
DCHECK(view.get());
DCHECK(view->IsValid());
DCHECK(!view->IsAttached());
if (!view.get() || !view->IsValid() || view->IsAttached())
if (!view.get() || !view->IsValid())
return;
std::unique_ptr<views::View> view_ptr = view_util::PassOwnership(view);
ParentClass::content_view()->AddChildView(view_ptr.release());
auto* view_ptr = view->IsAttached()
? view_util::GetFor(view)
: view_util::PassOwnership(view).release();
DCHECK(view_ptr);
ParentClass::content_view()->AddChildView(view_ptr);
}
CEF_PANEL_IMPL_T void CEF_PANEL_IMPL_D::AddChildViewAt(CefRefPtr<CefView> view,
@@ -126,18 +128,20 @@ CEF_PANEL_IMPL_T void CEF_PANEL_IMPL_D::AddChildViewAt(CefRefPtr<CefView> view,
CEF_REQUIRE_VALID_RETURN_VOID();
DCHECK(view.get());
DCHECK(view->IsValid());
DCHECK(!view->IsAttached());
DCHECK_GE(index, 0);
DCHECK_LE(static_cast<unsigned int>(index),
ParentClass::content_view()->children().size());
if (!view.get() || !view->IsValid() || view->IsAttached() || index < 0 ||
if (!view.get() || !view->IsValid() || index < 0 ||
(static_cast<unsigned int>(index) >
ParentClass::content_view()->children().size())) {
return;
}
std::unique_ptr<views::View> view_ptr = view_util::PassOwnership(view);
ParentClass::content_view()->AddChildViewAt(view_ptr.release(), index);
auto* view_ptr = view->IsAttached()
? view_util::GetFor(view)
: view_util::PassOwnership(view).release();
DCHECK(view_ptr);
ParentClass::content_view()->AddChildViewAt(view_ptr, index);
}
CEF_PANEL_IMPL_T void CEF_PANEL_IMPL_D::ReorderChildView(

View File

@@ -26,8 +26,9 @@ CEF_PANEL_VIEW_T class CefPanelView : public CEF_VIEW_VIEW_D {
typedef CEF_VIEW_VIEW_D ParentClass;
// |cef_delegate| may be nullptr.
explicit CefPanelView(CefViewDelegateClass* cef_delegate)
: ParentClass(cef_delegate) {}
template <typename... Args>
explicit CefPanelView(CefViewDelegateClass* cef_delegate, Args... args)
: ParentClass(cef_delegate, args...) {}
// Returns the CefPanel associated with this view. See comments on
// CefViewView::GetCefView.

View File

@@ -4,6 +4,7 @@
#include "libcef/browser/views/view_adapter.h"
#include "libcef/browser/chrome/views/toolbar_view_impl.h"
#include "libcef/browser/views/basic_label_button_impl.h"
#include "libcef/browser/views/basic_panel_impl.h"
#include "libcef/browser/views/browser_view_impl.h"
@@ -40,6 +41,9 @@ CefViewAdapter* CefViewAdapter::GetFor(CefRefPtr<CefView> view) {
adapter = static_cast<CefScrollViewImpl*>(view->AsScrollView().get());
} else if (view->AsTextfield()) {
adapter = static_cast<CefTextfieldImpl*>(view->AsTextfield().get());
} else if (view->GetTypeString().ToString() ==
CefToolbarViewImpl::kTypeString) {
adapter = static_cast<CefToolbarViewImpl*>(view.get());
}
DCHECK(adapter);

View File

@@ -34,8 +34,9 @@ CEF_VIEW_VIEW_T class CefViewView : public ViewsViewClass {
// Do not call complex views::View-derived methods from a CefViewView-derived
// constructor as they may attempt to call back into CefViewImpl before
// registration has been performed. |cef_delegate| may be nullptr.
explicit CefViewView(CefViewDelegateClass* cef_delegate)
: cef_delegate_(cef_delegate) {}
template <typename... Args>
explicit CefViewView(CefViewDelegateClass* cef_delegate, Args... args)
: ParentClass(args...), cef_delegate_(cef_delegate) {}
// Should be called from InitializeRootView() in the CefViewImpl-derived
// class that created this object. This method will be called after
@@ -70,6 +71,8 @@ CEF_VIEW_VIEW_T class CefViewView : public ViewsViewClass {
void Layout() override;
void ViewHierarchyChanged(
const views::ViewHierarchyChangedDetails& details) override;
void AddedToWidget() override;
void RemovedFromWidget() override;
void OnFocus() override;
void OnBlur() override;
@@ -84,7 +87,7 @@ CEF_VIEW_VIEW_T class CefViewView : public ViewsViewClass {
const views::ViewHierarchyChangedDetails& details);
// Not owned by this object.
CefViewDelegateClass* cef_delegate_;
CefViewDelegateClass* const cef_delegate_;
};
CEF_VIEW_VIEW_T gfx::Size CEF_VIEW_VIEW_D::CalculatePreferredSize() const {
@@ -162,6 +165,18 @@ CEF_VIEW_VIEW_T void CEF_VIEW_VIEW_D::ViewHierarchyChanged(
ParentClass::ViewHierarchyChanged(details);
}
CEF_VIEW_VIEW_T void CEF_VIEW_VIEW_D::AddedToWidget() {
ParentClass::AddedToWidget();
if (cef_delegate())
cef_delegate()->OnWindowChanged(GetCefView(), /*added=*/true);
}
CEF_VIEW_VIEW_T void CEF_VIEW_VIEW_D::RemovedFromWidget() {
if (cef_delegate())
cef_delegate()->OnWindowChanged(GetCefView(), /*added=*/false);
ParentClass::RemovedFromWidget();
}
CEF_VIEW_VIEW_T void CEF_VIEW_VIEW_D::OnFocus() {
if (cef_delegate())
cef_delegate()->OnFocus(GetCefView());

View File

@@ -150,9 +150,10 @@ bool AlloyMainDelegate::BasicStartupComplete(int* exit_code) {
if (settings_->user_agent.length > 0) {
command_line->AppendSwitchASCII(embedder_support::kUserAgent,
CefString(&settings_->user_agent));
} else if (settings_->product_version.length > 0) {
command_line->AppendSwitchASCII(switches::kProductVersion,
CefString(&settings_->product_version));
} else if (settings_->user_agent_product.length > 0) {
command_line->AppendSwitchASCII(
switches::kUserAgentProductAndVersion,
CefString(&settings_->user_agent_product));
}
if (settings_->locale.length > 0) {
@@ -443,9 +444,11 @@ CefRefPtr<CefRequestContext> AlloyMainDelegate::GetGlobalRequestContext() {
}
CefBrowserContext* AlloyMainDelegate::CreateNewBrowserContext(
const CefRequestContextSettings& settings) {
const CefRequestContextSettings& settings,
base::OnceClosure initialized_cb) {
auto context = new AlloyBrowserContext(settings);
context->Initialize();
std::move(initialized_cb).Run();
return context;
}

View File

@@ -62,7 +62,8 @@ class AlloyMainDelegate : public content::ContentMainDelegate,
}
CefRefPtr<CefRequestContext> GetGlobalRequestContext() override;
CefBrowserContext* CreateNewBrowserContext(
const CefRequestContextSettings& settings) override;
const CefRequestContextSettings& settings,
base::OnceClosure initialized_cb) override;
// CefTaskRunnerManager overrides.
scoped_refptr<base::SingleThreadTaskRunner> GetBackgroundTaskRunner()

View File

@@ -11,6 +11,7 @@
#include "include/cef_app.h"
#include "include/cef_request_context.h"
#include "base/callback.h"
#include "base/macros.h"
#include "build/build_config.h"
#include "content/public/common/content_client.h"
@@ -44,10 +45,12 @@ class CefAppManager {
// The following methods are only available in the main (browser) process.
// Called from CefRequestContextImpl.
// Called from CefRequestContextImpl. |initialized_cb| may be executed
// synchronously or asynchronously.
virtual CefRefPtr<CefRequestContext> GetGlobalRequestContext() = 0;
virtual CefBrowserContext* CreateNewBrowserContext(
const CefRequestContextSettings& settings) = 0;
const CefRequestContextSettings& settings,
base::OnceClosure initialized_cb) = 0;
#if defined(OS_WIN)
// Returns the module name (usually libcef.dll).

View File

@@ -126,6 +126,9 @@ const char kEnableChromeRuntime[] = "enable-chrome-runtime";
// using the Chrome runtime.
const char kDisableChromeLoginPrompt[] = "disable-chrome-login-prompt";
// Override the product component of the default User-Agent string.
const char kUserAgentProductAndVersion[] = "user-agent-product";
#if defined(OS_MAC)
// Path to the framework directory.
const char kFrameworkDirPath[] = "framework-dir-path";

View File

@@ -55,6 +55,7 @@ extern const char kDisableNewBrowserInfoTimeout[];
extern const char kDevToolsProtocolLogFile[];
extern const char kEnableChromeRuntime[];
extern const char kDisableChromeLoginPrompt[];
extern const char kUserAgentProductAndVersion[];
#if defined(OS_MAC)
extern const char kFrameworkDirPath[];

View File

@@ -15,8 +15,11 @@
#include "base/command_line.h"
#include "base/lazy_instance.h"
#include "chrome/common/chrome_switches.h"
#include "components/embedder_support/switches.h"
#include "content/public/common/content_switches.h"
#include "sandbox/policy/switches.h"
#include "ui/base/ui_base_switches.h"
#if defined(OS_MAC)
#include "libcef/common/util_mac.h"
@@ -78,6 +81,22 @@ bool ChromeMainDelegateCef::BasicStartupComplete(int* exit_code) {
command_line->AppendSwitch(sandbox::policy::switches::kNoSandbox);
}
if (settings_->user_agent.length > 0) {
command_line->AppendSwitchASCII(embedder_support::kUserAgent,
CefString(&settings_->user_agent));
} else if (settings_->user_agent_product.length > 0) {
command_line->AppendSwitchASCII(
switches::kUserAgentProductAndVersion,
CefString(&settings_->user_agent_product));
}
if (settings_->locale.length > 0) {
command_line->AppendSwitchASCII(switches::kLang,
CefString(&settings_->locale));
} else if (!command_line->HasSwitch(switches::kLang)) {
command_line->AppendSwitchASCII(switches::kLang, "en-US");
}
if (settings_->javascript_flags.length > 0) {
command_line->AppendSwitchASCII(switches::kJavaScriptFlags,
CefString(&settings_->javascript_flags));
@@ -194,9 +213,10 @@ CefRefPtr<CefRequestContext> ChromeMainDelegateCef::GetGlobalRequestContext() {
}
CefBrowserContext* ChromeMainDelegateCef::CreateNewBrowserContext(
const CefRequestContextSettings& settings) {
const CefRequestContextSettings& settings,
base::OnceClosure initialized_cb) {
auto context = new ChromeBrowserContext(settings);
context->Initialize();
context->InitializeAsync(std::move(initialized_cb));
return context;
}

View File

@@ -54,7 +54,8 @@ class ChromeMainDelegateCef : public ChromeMainDelegate,
}
CefRefPtr<CefRequestContext> GetGlobalRequestContext() override;
CefBrowserContext* CreateNewBrowserContext(
const CefRequestContextSettings& settings) override;
const CefRequestContextSettings& settings,
base::OnceClosure initialized_cb) override;
// CefTaskRunnerManager overrides.
scoped_refptr<base::SingleThreadTaskRunner> GetBackgroundTaskRunner()

View File

@@ -0,0 +1,41 @@
// Copyright (c) 2021 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
#include "libcef/common/net/url_util.h"
#include "base/logging.h"
#include "components/url_formatter/url_fixer.h"
namespace url_util {
GURL MakeGURL(const CefString& url, bool fixup) {
GURL gurl = GURL(url.ToString());
if (!url.empty() && !gurl.is_valid() && !gurl.has_scheme()) {
std::string fixed_scheme(url::kHttpScheme);
fixed_scheme.append(url::kStandardSchemeSeparator);
std::string new_url = url;
new_url.insert(0, fixed_scheme);
gurl = GURL(new_url);
}
if (fixup)
FixupGURL(gurl);
return gurl;
}
bool FixupGURL(GURL& gurl) {
if (!gurl.is_empty()) {
GURL fixup_url =
url_formatter::FixupURL(gurl.possibly_invalid_spec(), std::string());
if (fixup_url.is_valid()) {
gurl = fixup_url;
} else {
LOG(ERROR) << "Invalid URL: " << gurl.possibly_invalid_spec();
gurl = GURL();
return false;
}
}
return true;
}
} // namespace url_util

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