Compare commits

...

60 Commits
4103 ... 4147

Author SHA1 Message Date
Cristian Amarie
fdc7504631 Add limit on request redirects (fixes issue #3001) 2020-08-13 15:03:41 -04:00
Marshall Greenblatt
304e015509 Update API hash to include enums (see issue #3000) 2020-08-07 13:17:46 -04:00
Dmitry Azaraev
6c81b2125f Include enum declarations into API hash calculation (fixes issue #3000) 2020-08-07 13:17:07 -04:00
Marshall Greenblatt
a46056b1eb Fix automate-git.py argument error 2020-08-03 15:02:39 -04:00
Marshall Greenblatt
7efb1099d9 Add --distrib-subdir-suffix option to make_distrib 2020-08-03 14:43:15 -04:00
Marshall Greenblatt
c8a556f173 Update to Chromium version 84.0.4147.105 2020-07-29 13:09:37 -04:00
Marshall Greenblatt
97011bca14 Fix DCHECK when showing print preview dialog (see issue #2952) 2020-07-23 15:54:55 -04:00
Marshall Greenblatt
83f4983b73 Fix link navigation from PDF files (fixes issue #2952)
Navigations initiated from a guest view will now be routed to the
OpenURLFromTab callback.
2020-07-23 15:54:55 -04:00
Marshall Greenblatt
d246bb6967 Windows: cmake: Simplify the MSVC version check 2020-07-23 12:32:26 -04:00
Czarek Tomczak
1058991018 MacOS: Update target SDK to 10.10 for cmake and tests 2020-07-23 12:32:21 -04:00
Marshall Greenblatt
ffc2f0ea62 cmake: Update documentation of build requirements and examples 2020-07-21 16:14:58 -04:00
Marshall Greenblatt
1a795a1b4b Fix crash in ThemeService with --disable-extensions (fixes issue #2852) 2020-07-21 13:28:56 -04:00
Masako Toda
7448470392 Fix excessive CPU usage with external and multi-threaded message loops (fixes issue #2809, fixes issue #2970). 2020-07-21 12:31:21 -04:00
Mike Wiedenbauer
a8731e7501 Return decompressed values from CefResourceBundle (fixes issue #2976) 2020-07-21 12:02:33 -04:00
Masako Toda
eeda28cdc8 Fix timing of InstallTransparency for OSR + gpu-disabled (see issue #2938) 2020-07-20 16:05:37 -04:00
Marshall Greenblatt
3dd2e2902a cefclient: Fix rendering of example background for OSR transparency (see issue #2938) 2020-07-20 15:44:57 -04:00
Andrei Kurushin
d9aa1a58ec Fix crash when closing an OSR browser (fixes issue #2919)
Release the Compositor before the WebContents is destroyed to match
the behavior in non-OSR code.
2020-07-20 14:55:05 -04:00
Cristian Amarie
7c5e746ea4 Properly disable the notification and push APIs (fixes issue #2951) 2020-07-20 14:53:45 -04:00
Marshall Greenblatt
149ccf946f Fix shutdown crash in InitNetworkContext with multi-threaded message loop (fixes issue #2985) 2020-07-20 14:03:15 -04:00
Marshall Greenblatt
3f2c37255f Update to Chromium version 84.0.4147.89 2020-07-17 19:12:13 -04:00
Marshall Greenblatt
7077b0efe1 Expose MediaSink device ip/port and model name (see issue #2900) 2020-07-14 17:04:39 -04:00
Marshall Greenblatt
1812f94ebd Windows: Explicitly specify the SDK version in setup_toolchain.py
Avoid building with a new and untested SDK version. See
https://crbug.com/1089996 for background.
2020-07-13 16:23:44 -04:00
Marshall Greenblatt
c551bc2695 Make chrome://chrome-urls an alias for chrome://webui-hosts (fixes issue #2977) 2020-07-02 15:45:50 -04:00
Marshall Greenblatt
f7c90a6bb2 Fix decoding of resources (fixes issue #2966)
Use LoadDataResourceString instead of GetDataResource. It will perform
decoding if necessary.
2020-07-02 14:50:25 -04:00
lwttai.lu
08c49aa624 Windows: File dialog add filter with all supported extensions as default (see issue #860) 2020-06-30 14:48:19 -04:00
Cristian Amarie
2fef70b664 Fix crash when reading malformed Flash manifest file (fixes issue #2948) 2020-06-30 14:48:13 -04:00
Marshall Greenblatt
48637c687c Windows: Fix CefCookieVisitor crash on invalid date (fixes issue #2927) 2020-06-30 14:35:41 -04:00
Mike Wiedenbauer
d808850d4e Fix decoding of the DevTools remote debugging discovery page (fixes issue #2974) 2020-06-30 10:45:41 -04:00
Marshall Greenblatt
0fb8a5f1ea Add support for direct DevTools protocol messaging (fixes issue #2961).
This change allows the client to directly send and receive DevTools
protocol messages (send method calls, and receive method results and
events) without requiring a DevTools front-end or remote-debugging
session.

This change includes additional supporting changes:
- Add a new CefRequestHandler::OnDocumentAvailableInMainFrame
  callback (see issue #1454).
- Add a CefParseJSON variant that accepts a UTF8-encoded buffer.
- Add a `--devtools-protocol-log-file=<path>` command-line flag for
  logging protocol messages sent to/from the DevTools front-end
  while it is displayed. This is useful for understanding existing
  DevTools protocol usage.
- Add a new "libcef_static_unittests" executable target to support
  light-weight unit tests of libcef_static internals (e.g. without
  requiring exposure via the CEF API). Files to be unittested are
  placed in the new "libcef_static_unittested" source_set which is
  then included by both the existing libcef_static library and the
  new unittests executable target.
- Linux: Remove use_bundled_fontconfig=false, which is no longer
  required and causes unittest build errors (see issue #2424).

This change also adds a cefclient demo for configuring offline mode
using the DevTools protocol (fixes issue #245). This is controlled
by the "Offline mode" context menu option and the `--offline`
command-line switch which will launch cefclient in offline mode. When
cefclient is offline all network requests will fail with
ERR_INTERNET_DISCONNECTED and navigator.onLine will return false when
called from JavaScript in any frame. This mode is per-browser so
newly created browser windows will have the default mode. Note that
configuring offline mode in this way will not update the Network tab
UI ("Throtting" option) in a displayed DevTools front-end instance.
2020-06-19 22:17:11 -04:00
Marshall Greenblatt
98e6450272 Update to Chromium version 84.0.4147.38 2020-06-11 16:44:33 -04:00
Marshall Greenblatt
a9aef28966 Improve AudioOutputTest.AudioTogglePlaybackTest to avoid flakyness. 2020-06-10 15:26:40 -04:00
Alexander Guettler
790d248111 Update to Chromium version 84.0.4147.0 (#768962) 2020-06-10 15:26:29 -04:00
Marshall Greenblatt
640cd0f411 Remove duplicate local_discovery file entries (see issue #2900)
This fixes duplicate symbol errors when linking libcef on Linux. These files
are now included by default with enable_service_discovery=true.
2020-05-26 12:32:40 -04:00
Marshall Greenblatt
cfe8e320be Enable DNS-SD discovery for cast devices (see issue #2900) 2020-05-25 16:54:45 -04:00
Marshall Greenblatt
5780bf40d4 Linux: Fix undefined symbol: ui::GtkUiDelegate::SetInstance
See https://crbug.com/1085806 for details.
2020-05-22 14:56:09 -04:00
Marshall Greenblatt
31d3e88d32 Add |client_| nullptr check in CefBrowserHostImpl::CanDragEnter (fixes issue #2934) 2020-05-13 14:30:44 -04:00
Marshall Greenblatt
7ecaa8afdd Windows: Add VS2019 path discovery to msvs_env.bat (fixes issue #2925) 2020-05-13 13:23:05 -04:00
Marshall Greenblatt
8c996d2efd Remember the user-selected printer by default (fixes issue #2875) 2020-05-13 13:10:08 -04:00
Marshall Greenblatt
d8b4281c06 Fix window.print() of PDF file (fixes issue #2987) 2020-05-12 16:25:13 -04:00
Marshall Greenblatt
c82eb3e80f Windows: cefclient: Fix return value check for AcquireSync (fixes issue #2933) 2020-05-12 15:41:20 -04:00
Marshall Greenblatt
14571658a2 Fix load of non-standard custom scheme URI as iframe src (see issue #2929) 2020-05-11 18:12:34 -04:00
Marshall Greenblatt
aa4473e2c6 Fix registration of WebSafe schemes (fixes issue #2929) 2020-05-11 18:11:53 -04:00
Marshall Greenblatt
9deef4189c Update AUTHORS.txt documentation 2020-05-08 12:35:04 -04:00
Marshall Greenblatt
25d81e0f1d Update AUTHORS.txt documentation 2020-05-08 12:25:35 -04:00
Marshall Greenblatt
70590a759d Update API hash for audio handler changes (see issue #2755) 2020-05-01 14:24:53 -04:00
Mike Wiedenbauer
8d01442d75 Re-implement audio capturing based on the AudioService API (fixes issue #2755) 2020-05-01 18:18:18 +00:00
Marshall Greenblatt
d65483ae16 Update cef_api_hash.h at build time if necessary (fixes issue #2922)
The cef_api_hash.h file was previously only updated when the translator tool
was run manually. Forgetting to run the translator tool after changing
include/internal/cef_types*.h files would result in cef_parser.py
incorrectly computing the CEF minor version number for future builds. By
updating this file automatically at build time the number of errors should be
reduced.
2020-04-30 17:52:10 -04:00
Marshall Greenblatt
7c6e53ddfb Save LocalPrefs.json in CefSettings.root_cache_path (see issue #2890) 2020-04-29 15:36:29 -04:00
Marshall Greenblatt
ff0c36b465 Add CefMediaSink::GetIconType (see issue #2900)
This attribute is useful for identifying different classes of cast devices
without first requiring a connection (CAST, CAST_AUDIO, CAST_AUDIO_GROUP, etc).
2020-04-29 15:01:12 -04:00
Vladislav
dafce45e49 Fix OSR resize issue with DPI scaling (fixes issue #2733) 2020-04-27 16:48:06 +00:00
Dmitry Azaraev
be6af15754 Add SameSite (same_site) and Priority attributes to CefCookie (fixes issue #2524)
This change also restores the Chromium default values for the
SameSiteByDefaultCookies and CookiesWithoutSameSiteMustBeSecure features. See
https://www.chromium.org/updates/same-site for feature details and rollout
timeline.
2020-04-24 17:48:26 -04:00
Marshall Greenblatt
cbc0625272 Revert "Fix background color assignment for popups (fixes issue #2482)"
This change is causing the OSRTest.OsrPopupJSOtherClient test to fail.

This reverts commit 3adb801ca8.
2020-04-24 15:41:07 -04:00
Marshall Greenblatt
fd1f465fa7 Normalize path values and add additional error logging (fixes issue #2405)
This change also improves the settings documentation and enforces the
requirement that path values be absolute (see issue #2916).
2020-04-23 17:51:19 -04:00
Marshall Greenblatt
8ed39e4ae5 Fix transposed variables in GetRequestInfo (fixes issue #2530) 2020-04-23 14:40:19 -04:00
Marshall Greenblatt
3adb801ca8 Fix background color assignment for popups (fixes issue #2482) 2020-04-23 13:47:10 -04:00
Marshall Greenblatt
ccf7b28723 Fix PDF extension loading of large files (fixes issue #2905)
The PDF extension will send Range requests when loading large PDF files. For
these cross-origin requests to be allowed (from extension origin to PDF origin)
the CORB checks in URLLoader must be disabled.
2020-04-22 16:26:22 -04:00
Alex Maitland
e876217e24 Change cef_pdf_print_settings_t custom margins from double to int (fixes issue #2694) 2020-04-21 18:44:52 +00:00
Mike Wiedenbauer
ec0c57d0e1 Fix OSR keyboard input for editable PDF (fixes issue #2907) 2020-04-21 18:30:52 +00:00
Jengerer
87a7c4f94b Fix handling of partial range request (fixes issue #2873) 2020-04-20 13:19:42 -04:00
Marshall Greenblatt
27257d0288 Remove DCHECK in InterceptedRequest::OnReceiveRedirect (fixes issue #2917) 2020-04-20 12:38:31 -04:00
239 changed files with 7753 additions and 1579 deletions

View File

@@ -1,6 +1,8 @@
# This file is an addendum to the Chromium AUTHORS file.
# Names should be added to this file like so:
# Name or Organization <email address>
# This file is an addendum to the Chromium AUTHORS file. It lists authors
# through March 16, 2015 when Git was introduced for source code management.
# A list of additional authors added after that date can be found by executing
# this command on a local Git checkout:
# git log --all --format="%aN <%aE>" | sort -u
Marshall Greenblatt <magreenblatt@gmail.com>
Jamie Kirkpatrick <jkp@spotify.com>

139
BUILD.gn
View File

@@ -106,6 +106,7 @@ import("//media/media_options.gni")
import("//mojo/public/tools/bindings/mojom.gni")
import("//ppapi/buildflags/buildflags.gni")
import("//printing/buildflags/buildflags.gni")
import("//testing/test.gni")
import("//third_party/icu/config.gni")
import("//third_party/widevine/cdm/widevine.gni")
import("//tools/grit/repack.gni")
@@ -253,7 +254,6 @@ if (is_linux) {
# Set ENABLE_PRINTING=1 ENABLE_BASIC_PRINTING=1.
assert(enable_basic_printing)
assert(enable_print_preview)
assert(!enable_service_discovery)
# Enable support for Widevine CDM.
assert(enable_widevine)
@@ -263,12 +263,6 @@ if (is_clang) {
assert(!clang_use_chrome_plugins)
}
if (is_linux) {
# Use system fontconfig. This avoids a startup hang on Ubuntu 16.04.4 (see
# issue #2424).
assert(!use_bundled_fontconfig)
}
if (is_mac) {
# Always generate dSYM files. The make_distrib script will fail if
# enable_dsyms=true is not explicitly set when is_official_build=false.
@@ -303,6 +297,10 @@ gypi_paths2 = exec_script("//cef/tools/gypi_to_gn.py",
"scope",
[ "cef_paths2.gypi" ])
includes_common = gypi_paths2.includes_common + gypi_paths2.includes_common_capi
includes_mac = gypi_paths2.includes_mac + gypi_paths2.includes_mac_capi
includes_linux = gypi_paths2.includes_linux + gypi_paths2.includes_linux_capi
includes_win = gypi_paths2.includes_win + gypi_paths2.includes_win_capi
#
# Targets that will be built when depending on "//cef".
@@ -313,6 +311,7 @@ group("cef") {
deps = [
":cefsimple",
":ceftests",
":libcef_static_unittests",
]
if (!is_linux || use_x11) {
@@ -370,9 +369,46 @@ if (is_win) {
}
}
# libcef_static source files that have unit tests.
source_set("libcef_static_unittested") {
sources = [
"libcef/browser/devtools/devtools_util.cc",
"libcef/browser/devtools/devtools_util.h",
]
deps = [
"//base",
]
configs += [
"libcef/features:config",
"//build/config:precompiled_headers",
]
}
# Executable target for libcef_static unit tests.
test("libcef_static_unittests") {
sources = [
"libcef/browser/devtools/devtools_util_unittest.cc",
]
deps = [
":libcef_static_unittested",
"//base/test:run_all_unittests",
"//testing/gtest",
]
configs += [
"libcef/features:config",
"//build/config:precompiled_headers",
]
}
static_library("libcef_static") {
sources = gypi_paths2.includes_common +
sources = includes_common +
gypi_paths.autogen_cpp_includes + [
"libcef/browser/audio_capturer.cc",
"libcef/browser/audio_capturer.h",
"libcef/browser/browser_context.cc",
"libcef/browser/browser_context.h",
"libcef/browser/browser_context_keyed_service_factories.cc",
@@ -407,10 +443,14 @@ static_library("libcef_static") {
"libcef/browser/context.h",
"libcef/browser/context_menu_params_impl.cc",
"libcef/browser/context_menu_params_impl.h",
"libcef/browser/devtools/devtools_controller.cc",
"libcef/browser/devtools/devtools_controller.h",
"libcef/browser/devtools/devtools_file_manager.cc",
"libcef/browser/devtools/devtools_file_manager.h",
"libcef/browser/devtools/devtools_frontend.cc",
"libcef/browser/devtools/devtools_frontend.h",
"libcef/browser/devtools/devtools_manager.cc",
"libcef/browser/devtools/devtools_manager.h",
"libcef/browser/devtools/devtools_manager_delegate.cc",
"libcef/browser/devtools/devtools_manager_delegate.h",
"libcef/browser/download_item_impl.cc",
@@ -706,17 +746,6 @@ static_library("libcef_static") {
"libcef/renderer/url_loader_throttle_provider_impl.h",
"libcef/renderer/v8_impl.cc",
"libcef/renderer/v8_impl.h",
"//chrome/browser/local_discovery/service_discovery_device_lister.cc",
"//chrome/browser/local_discovery/service_discovery_device_lister.h",
"//chrome/browser/local_discovery/service_discovery_client_impl.cc",
"//chrome/browser/local_discovery/service_discovery_client_impl.h",
"//chrome/browser/local_discovery/service_discovery_client.cc",
"//chrome/browser/local_discovery/service_discovery_client.h",
"//chrome/browser/local_discovery/service_discovery_client_mdns.cc",
"//chrome/browser/local_discovery/service_discovery_client_mdns.h",
"//chrome/browser/local_discovery/service_discovery_shared_client.cc",
"//chrome/browser/local_discovery/service_discovery_shared_client.h",
]
configs += [
@@ -745,6 +774,8 @@ static_library("libcef_static") {
":cef_make_headers",
":cef_service_manifests",
":libcef_static_unittested",
# Generate API bindings for extensions.
# TODO(cef): Enable if/when CEF exposes its own Mojo APIs. See
# libcef/common/extensions/api/README.txt for details.
@@ -794,7 +825,7 @@ static_library("libcef_static") {
"//components/visitedlink/renderer",
"//components/viz/service",
"//components/web_cache/renderer",
"//content/public/app:both",
"//content/public/app",
"//content/public/browser",
"//content/public/child",
"//content/public/common",
@@ -847,7 +878,7 @@ static_library("libcef_static") {
]
if (is_win) {
sources += gypi_paths2.includes_win + [
sources += includes_win + [
"libcef/browser/browser_main_win.cc",
"libcef/browser/native/browser_platform_delegate_native_win.cc",
"libcef/browser/native/browser_platform_delegate_native_win.h",
@@ -892,7 +923,7 @@ static_library("libcef_static") {
}
if (is_linux) {
sources += gypi_paths2.includes_linux + [
sources += includes_linux + [
"libcef/browser/native/browser_platform_delegate_native_linux.cc",
"libcef/browser/native/browser_platform_delegate_native_linux.h",
"libcef/browser/native/menu_runner_linux.cc",
@@ -924,7 +955,7 @@ static_library("libcef_static") {
}
if (is_mac) {
sources += gypi_paths2.includes_mac + [
sources += includes_mac + [
"libcef/browser/native/browser_platform_delegate_native_mac.h",
"libcef/browser/native/browser_platform_delegate_native_mac.mm",
"libcef/browser/native/file_dialog_runner_mac.h",
@@ -1138,7 +1169,7 @@ config("libcef_dll_wrapper_config") {
# libcef_dll_wrapper target.
static_library("libcef_dll_wrapper") {
sources = gypi_paths2.includes_common +
sources = includes_common +
gypi_paths.autogen_cpp_includes +
gypi_paths2.includes_capi +
gypi_paths.autogen_capi_includes +
@@ -1494,11 +1525,29 @@ make_pack_header("strings") {
]
}
# Generate cef_api_hash.h.
action("make_api_hash_header") {
script = "tools/make_api_hash_header.py"
# List of all C API files that will be checked for changes by cef_api_hash.py.
inputs = gypi_paths2.includes_common_capi +
gypi_paths2.includes_linux_capi +
gypi_paths2.includes_mac_capi +
gypi_paths2.includes_win_capi +
gypi_paths2.includes_capi +
gypi_paths.autogen_capi_includes
include_dir = [ "include" ]
outputs = [ "$root_out_dir/includes/include/cef_api_hash.h" ]
args = rebase_path(outputs + include_dir, root_build_dir)
}
# Generate pack files and associated CEF header files.
group("cef_make_headers") {
deps = [
":make_pack_header_resources",
":make_pack_header_strings",
":make_api_hash_header",
]
}
@@ -1634,8 +1683,8 @@ if (is_mac) {
"Resources",
]
sources = gypi_paths2.includes_common +
gypi_paths2.includes_mac +
sources = includes_common +
includes_mac +
gypi_paths.autogen_cpp_includes +
gypi_paths2.includes_capi +
gypi_paths.autogen_capi_includes +
@@ -1678,7 +1727,7 @@ if (is_mac) {
}
} else {
shared_library("libcef") {
sources = gypi_paths2.includes_common +
sources = includes_common +
gypi_paths.autogen_cpp_includes +
gypi_paths2.includes_capi +
gypi_paths.autogen_capi_includes +
@@ -1690,7 +1739,7 @@ if (is_mac) {
]
if (is_win) {
sources += gypi_paths2.includes_win + [
sources += includes_win + [
"libcef_dll/libcef_dll.rc",
]
@@ -1901,8 +1950,8 @@ if (is_mac) {
cef_app("cefclient") {
helper_info_plist = "tests/cefclient/resources/mac/helper-Info.plist"
helper_sources = gypi_paths2.includes_mac +
gypi_paths2.includes_common +
helper_sources = includes_common +
includes_mac +
gypi_paths2.includes_wrapper +
gypi_paths2.includes_wrapper_mac +
gypi_paths2.shared_sources_common +
@@ -1915,8 +1964,8 @@ if (is_mac) {
]
info_plist = "tests/cefclient/resources/mac/Info.plist"
sources = gypi_paths2.includes_mac +
gypi_paths2.includes_common +
sources = includes_common +
includes_mac +
gypi_paths2.includes_wrapper +
gypi_paths2.includes_wrapper_mac +
gypi_paths2.shared_sources_browser +
@@ -1974,8 +2023,8 @@ if (is_mac) {
cef_app("cefsimple") {
helper_info_plist = "tests/cefsimple/mac/helper-Info.plist"
helper_sources = gypi_paths2.includes_mac +
gypi_paths2.includes_common +
helper_sources = includes_common +
includes_mac +
gypi_paths2.includes_wrapper +
gypi_paths2.includes_wrapper_mac +
gypi_paths2.cefsimple_sources_mac_helper
@@ -1984,8 +2033,8 @@ if (is_mac) {
]
info_plist = "tests/cefsimple/mac/Info.plist"
sources = gypi_paths2.includes_mac +
gypi_paths2.includes_common +
sources = includes_common +
includes_mac +
gypi_paths2.includes_wrapper +
gypi_paths2.includes_wrapper_mac +
gypi_paths2.cefsimple_sources_common +
@@ -2051,8 +2100,8 @@ if (is_mac) {
]
info_plist = "tests/ceftests/resources/mac/Info.plist"
sources = gypi_paths2.includes_mac +
gypi_paths2.includes_common +
sources = includes_common +
includes_mac +
gypi_paths2.includes_wrapper +
gypi_paths2.includes_wrapper_mac +
gypi_paths2.shared_sources_browser +
@@ -2120,7 +2169,7 @@ if (is_mac) {
}
executable("cefclient") {
sources = gypi_paths2.includes_common +
sources = includes_common +
gypi_paths2.includes_wrapper +
gypi_paths2.shared_sources_browser +
gypi_paths2.shared_sources_common +
@@ -2139,7 +2188,7 @@ if (is_mac) {
]
if (is_win) {
sources += gypi_paths2.includes_win +
sources += includes_win +
gypi_paths2.shared_sources_win +
gypi_paths2.cefclient_sources_win
@@ -2174,7 +2223,7 @@ if (is_mac) {
}
if (is_linux) {
sources += gypi_paths2.includes_linux +
sources += includes_linux +
gypi_paths2.shared_sources_linux +
gypi_paths2.cefclient_sources_linux
@@ -2213,7 +2262,7 @@ if (is_mac) {
#
executable("cefsimple") {
sources = gypi_paths2.includes_common +
sources = includes_common +
gypi_paths2.includes_wrapper +
gypi_paths2.cefsimple_sources_common
@@ -2227,7 +2276,7 @@ if (is_mac) {
]
if (is_win) {
sources += gypi_paths2.includes_win +
sources += includes_win +
gypi_paths2.cefsimple_sources_win
# Set /SUBSYSTEM:WINDOWS.
@@ -2247,7 +2296,7 @@ if (is_mac) {
}
if (is_linux) {
sources += gypi_paths2.includes_linux +
sources += includes_linux +
gypi_paths2.cefsimple_sources_linux
if (use_x11) {
@@ -2278,7 +2327,7 @@ if (is_mac) {
executable("ceftests") {
testonly = true
sources = gypi_paths2.includes_common +
sources = includes_common +
gypi_paths2.includes_wrapper +
gypi_paths2.shared_sources_browser +
gypi_paths2.shared_sources_common +

View File

@@ -7,5 +7,6 @@
# https://bitbucket.org/chromiumembedded/cef/wiki/BranchesAndBuilding
{
'chromium_checkout': 'refs/tags/83.0.4103.0'
'chromium_checkout': 'refs/tags/84.0.4147.105',
'depot_tools_checkout': '233589f2e7'
}

View File

@@ -12,8 +12,8 @@
# distribution include:
#
# Linux: Ninja, Unix Makefiles
# Mac OS X: Ninja, Xcode 5+
# Windows: Ninja, Visual Studio 2010+
# MacOS: Ninja, Xcode 8+
# Windows: Ninja, Visual Studio 2015+
#
# Ninja is a cross-platform open-source tool for running fast builds using
# pre-installed platform toolchains (GNU, clang, Xcode or MSVC). It can be
@@ -40,21 +40,21 @@
#
# - Linux requirements:
# Currently supported distributions include Debian Wheezy, Ubuntu Precise, and
# related. Ubuntu 14.04 64-bit is recommended. Newer versions will likely also
# related. Ubuntu 18.04 64-bit is recommended. Newer versions will likely also
# work but may not have been tested.
# Required packages include:
# build-essential
# libgtk2.0-dev (required by the cefclient target only)
# libgtkglext1-dev (required by the cefclient target only)
#
# - Mac OS X requirements:
# Xcode 5 or newer building on Mac OS X 10.9 (Mavericks) or newer. Xcode 8.3
# and OS X 10.12 are recommended. The Xcode command-line tools must also be
# installed. Only 64-bit builds are supported on OS X.
# - MacOS requirements:
# Xcode 8 or newer building on MacOS 10.10 (Yosemite) or newer. Xcode 11.2
# and MacOS 10.14 are recommended. The Xcode command-line tools must also be
# installed. Only 64-bit builds are supported.
#
# - Windows requirements:
# Visual Studio 2010 or newer building on Windows 7 or newer. Visual Studio
# 2015 Update 3 and Windows 10 64-bit are recommended.
# Visual Studio 2015 or newer building on Windows 7 or newer. Visual Studio
# 2019 and Windows 10 64-bit are recommended.
#
# BUILD EXAMPLES
#
@@ -75,7 +75,7 @@
# > cmake -G "Ninja" -DCMAKE_BUILD_TYPE=Debug ..
# > ninja cefclient cefsimple
#
# To perform a Mac OS X build using a 64-bit CEF binary distribution:
# To perform a MacOS build using a 64-bit CEF binary distribution:
# Using the Xcode IDE:
# > cmake -G "Xcode" -DPROJECT_ARCH="x86_64" ..
# Open build\cef.xcodeproj in Xcode and select Product > Build.
@@ -85,24 +85,24 @@
# > ninja cefclient cefsimple
#
# To perform a Windows build using a 32-bit CEF binary distribution:
# Using the Visual Studio 2015 IDE:
# > cmake -G "Visual Studio 14" ..
# Using the Visual Studio 2019 IDE:
# > cmake -G "Visual Studio 16" -A Win32 ..
# Open build\cef.sln in Visual Studio and select Build > Build Solution.
#
# Using Ninja with Visual Studio 2015 command-line tools:
# Using Ninja with Visual Studio 2019 command-line tools:
# (this path may be different depending on your Visual Studio installation)
# > "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\vcvars32.bat"
# > "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Auxiliary\Build\vcvars32.bat"
# > cmake -G "Ninja" -DCMAKE_BUILD_TYPE=Debug ..
# > ninja cefclient cefsimple
#
# To perform a Windows build using a 64-bit CEF binary distribution:
# Using the Visual Studio 2015 IDE:
# > cmake -G "Visual Studio 14 Win64" ..
# Using the Visual Studio 2019 IDE:
# > cmake -G "Visual Studio 16" -A x64 ..
# Open build\cef.sln in Visual Studio and select Build > Build Solution.
#
# Using Ninja with Visual Studio 2015 command-line tools:
# Using Ninja with Visual Studio 2019 command-line tools:
# (this path may be different depending on your Visual Studio installation)
# > "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\amd64\vcvars64.bat"
# > "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Auxiliary\Build\vcvars64.bat"
# > cmake -G "Ninja" -DCMAKE_BUILD_TYPE=Debug ..
# > ninja cefclient cefsimple

View File

@@ -8,7 +8,7 @@
# by hand. See the translator.README.txt file in the tools directory for
# more information.
#
# $hash=578c0aef11c3c7840679e480069fc9031c628e25$
# $hash=72268a78a76d7d91b8ad47f6b6e9f6d9cb04d9cf$
#
{
@@ -16,6 +16,7 @@
'autogen_cpp_includes': [
'include/cef_accessibility_handler.h',
'include/cef_app.h',
'include/cef_audio_handler.h',
'include/cef_auth_callback.h',
'include/cef_browser.h',
'include/cef_browser_process_handler.h',
@@ -25,6 +26,7 @@
'include/cef_context_menu_handler.h',
'include/cef_cookie.h',
'include/cef_crash_util.h',
'include/cef_devtools_message_observer.h',
'include/cef_dialog_handler.h',
'include/cef_display_handler.h',
'include/cef_dom.h',
@@ -111,6 +113,7 @@
'autogen_capi_includes': [
'include/capi/cef_accessibility_handler_capi.h',
'include/capi/cef_app_capi.h',
'include/capi/cef_audio_handler_capi.h',
'include/capi/cef_auth_callback_capi.h',
'include/capi/cef_browser_capi.h',
'include/capi/cef_browser_process_handler_capi.h',
@@ -120,6 +123,7 @@
'include/capi/cef_context_menu_handler_capi.h',
'include/capi/cef_cookie_capi.h',
'include/capi/cef_crash_util_capi.h',
'include/capi/cef_devtools_message_observer_capi.h',
'include/capi/cef_dialog_handler_capi.h',
'include/capi/cef_display_handler_capi.h',
'include/capi/cef_dom_capi.h',
@@ -208,6 +212,8 @@
'libcef_dll/ctocpp/accessibility_handler_ctocpp.h',
'libcef_dll/ctocpp/app_ctocpp.cc',
'libcef_dll/ctocpp/app_ctocpp.h',
'libcef_dll/ctocpp/audio_handler_ctocpp.cc',
'libcef_dll/ctocpp/audio_handler_ctocpp.h',
'libcef_dll/cpptoc/auth_callback_cpptoc.cc',
'libcef_dll/cpptoc/auth_callback_cpptoc.h',
'libcef_dll/cpptoc/before_download_callback_cpptoc.cc',
@@ -256,6 +262,8 @@
'libcef_dll/ctocpp/domvisitor_ctocpp.h',
'libcef_dll/ctocpp/delete_cookies_callback_ctocpp.cc',
'libcef_dll/ctocpp/delete_cookies_callback_ctocpp.h',
'libcef_dll/ctocpp/dev_tools_message_observer_ctocpp.cc',
'libcef_dll/ctocpp/dev_tools_message_observer_ctocpp.h',
'libcef_dll/ctocpp/dialog_handler_ctocpp.cc',
'libcef_dll/ctocpp/dialog_handler_ctocpp.h',
'libcef_dll/cpptoc/dictionary_value_cpptoc.cc',
@@ -322,6 +330,8 @@
'libcef_dll/cpptoc/media_router_cpptoc.h',
'libcef_dll/cpptoc/media_sink_cpptoc.cc',
'libcef_dll/cpptoc/media_sink_cpptoc.h',
'libcef_dll/ctocpp/media_sink_device_info_callback_ctocpp.cc',
'libcef_dll/ctocpp/media_sink_device_info_callback_ctocpp.h',
'libcef_dll/cpptoc/media_source_cpptoc.cc',
'libcef_dll/cpptoc/media_source_cpptoc.h',
'libcef_dll/cpptoc/views/menu_button_cpptoc.cc',
@@ -512,6 +522,8 @@
'libcef_dll/cpptoc/accessibility_handler_cpptoc.h',
'libcef_dll/cpptoc/app_cpptoc.cc',
'libcef_dll/cpptoc/app_cpptoc.h',
'libcef_dll/cpptoc/audio_handler_cpptoc.cc',
'libcef_dll/cpptoc/audio_handler_cpptoc.h',
'libcef_dll/ctocpp/auth_callback_ctocpp.cc',
'libcef_dll/ctocpp/auth_callback_ctocpp.h',
'libcef_dll/ctocpp/before_download_callback_ctocpp.cc',
@@ -560,6 +572,8 @@
'libcef_dll/cpptoc/domvisitor_cpptoc.h',
'libcef_dll/cpptoc/delete_cookies_callback_cpptoc.cc',
'libcef_dll/cpptoc/delete_cookies_callback_cpptoc.h',
'libcef_dll/cpptoc/dev_tools_message_observer_cpptoc.cc',
'libcef_dll/cpptoc/dev_tools_message_observer_cpptoc.h',
'libcef_dll/cpptoc/dialog_handler_cpptoc.cc',
'libcef_dll/cpptoc/dialog_handler_cpptoc.h',
'libcef_dll/ctocpp/dictionary_value_ctocpp.cc',
@@ -626,6 +640,8 @@
'libcef_dll/ctocpp/media_router_ctocpp.h',
'libcef_dll/ctocpp/media_sink_ctocpp.cc',
'libcef_dll/ctocpp/media_sink_ctocpp.h',
'libcef_dll/cpptoc/media_sink_device_info_callback_cpptoc.cc',
'libcef_dll/cpptoc/media_sink_device_info_callback_cpptoc.h',
'libcef_dll/ctocpp/media_source_ctocpp.cc',
'libcef_dll/ctocpp/media_source_ctocpp.h',
'libcef_dll/ctocpp/views/menu_button_ctocpp.cc',

View File

@@ -39,19 +39,21 @@
'include/cef_config.h',
'include/cef_version.h',
'include/internal/cef_export.h',
'include/internal/cef_logging_internal.h',
'include/internal/cef_ptr.h',
'include/internal/cef_string_wrappers.h',
'include/internal/cef_types_wrappers.h',
],
'includes_common_capi': [
'include/internal/cef_logging_internal.h',
'include/internal/cef_string.h',
'include/internal/cef_string_list.h',
'include/internal/cef_string_map.h',
'include/internal/cef_string_multimap.h',
'include/internal/cef_string_types.h',
'include/internal/cef_string_wrappers.h',
'include/internal/cef_thread_internal.h',
'include/internal/cef_time.h',
'include/internal/cef_trace_event_internal.h',
'include/internal/cef_types.h',
'include/internal/cef_types_wrappers.h',
],
'includes_capi': [
'include/capi/cef_base_capi.h',
@@ -75,15 +77,19 @@
'include/base/internal/cef_atomicops_x86_msvc.h',
'include/base/internal/cef_bind_internal_win.h',
'include/cef_sandbox_win.h',
'include/internal/cef_types_win.h',
'include/internal/cef_win.h',
],
'includes_win_capi': [
'include/internal/cef_types_win.h',
],
'includes_mac': [
'include/base/internal/cef_atomicops_atomicword_compat.h',
'include/base/internal/cef_atomicops_mac.h',
'include/cef_application_mac.h',
'include/cef_sandbox_mac.h',
'include/internal/cef_mac.h',
],
'includes_mac_capi': [
'include/internal/cef_types_mac.h',
],
'includes_linux': [
@@ -92,6 +98,8 @@
'include/base/internal/cef_atomicops_arm64_gcc.h',
'include/base/internal/cef_atomicops_x86_gcc.h',
'include/internal/cef_linux.h',
],
'includes_linux_capi': [
'include/internal/cef_types_linux.h',
],
'libcef_sources_common': [
@@ -458,9 +466,11 @@
'tests/cefsimple/simple_handler_linux.cc',
],
'ceftests_sources_common': [
'tests/ceftests/audio_output_unittest.cc',
'tests/ceftests/browser_info_map_unittest.cc',
'tests/ceftests/command_line_unittest.cc',
'tests/ceftests/cookie_unittest.cc',
'tests/ceftests/devtools_message_unittest.cc',
'tests/ceftests/dialog_unittest.cc',
'tests/ceftests/display_unittest.cc',
'tests/ceftests/dom_unittest.cc',
@@ -557,6 +567,7 @@
'tests/shared/browser/resource_util.h',
'tests/shared/browser/resource_util_mac.mm',
'tests/shared/browser/resource_util_posix.cc',
'tests/ceftests/audio_output_unittest.cc',
'tests/ceftests/client_app_delegates.cc',
'tests/ceftests/cookie_unittest.cc',
'tests/ceftests/dom_unittest.cc',

View File

@@ -310,7 +310,7 @@ if(OS_MACOSX)
# Find the newest available base SDK.
execute_process(COMMAND xcode-select --print-path OUTPUT_VARIABLE XCODE_PATH OUTPUT_STRIP_TRAILING_WHITESPACE)
foreach(OS_VERSION 10.11 10.10 10.9)
foreach(OS_VERSION 10.15 10.14 10.13 10.12 10.11 10.10)
set(SDK "${XCODE_PATH}/Platforms/MacOSX.platform/Developer/SDKs/MacOSX${OS_VERSION}.sdk")
if(NOT "${CMAKE_OSX_SYSROOT}" AND EXISTS "${SDK}" AND IS_DIRECTORY "${SDK}")
set(CMAKE_OSX_SYSROOT ${SDK})
@@ -318,7 +318,7 @@ if(OS_MACOSX)
endforeach()
# Target SDK.
set(CEF_TARGET_SDK "10.9")
set(CEF_TARGET_SDK "10.10")
list(APPEND CEF_COMPILER_FLAGS
-mmacosx-version-min=${CEF_TARGET_SDK}
)
@@ -375,25 +375,8 @@ if(OS_WINDOWS)
if(USE_SANDBOX)
# Check if the current MSVC version is compatible with the cef_sandbox.lib
# static library. For a list of all version numbers see
# https://en.wikipedia.org/wiki/Microsoft_Visual_C%2B%2B#Internal_version_numbering
list(APPEND supported_msvc_versions
1900 # VS2015 and updates 1, 2, & 3
1910 # VS2017 version 15.1 & 15.2
1911 # VS2017 version 15.3 & 15.4
1912 # VS2017 version 15.5
1913 # VS2017 version 15.6
1914 # VS2017 version 15.7
1915 # VS2017 version 15.8
1916 # VS2017 version 15.9
1920 # VS2019 version 16.0
1921 # VS2019 version 16.1
1922 # VS2019 version 16.2
1923 # VS2019 version 16.3
1924 # VS2019 version 16.4
)
list(FIND supported_msvc_versions ${MSVC_VERSION} _index)
if (${_index} EQUAL -1)
# static library. We require VS2015 or newer.
if(MSVC_VERSION LESS 1900)
message(WARNING "CEF sandbox is not compatible with the current MSVC version (${MSVC_VERSION})")
set(USE_SANDBOX OFF)
endif()

View File

@@ -0,0 +1,121 @@
// Copyright (c) 2020 Marshall A. Greenblatt. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the name Chromium Embedded
// Framework nor the names of its contributors may be used to endorse
// or promote products derived from this software without specific prior
// written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// ---------------------------------------------------------------------------
//
// This file was generated by the CEF translator tool and should not edited
// by hand. See the translator.README.txt file in the tools directory for
// more information.
//
// $hash=430877d950508a545d0baa18c8c8c0d2d183fec4$
//
#ifndef CEF_INCLUDE_CAPI_CEF_AUDIO_HANDLER_CAPI_H_
#define CEF_INCLUDE_CAPI_CEF_AUDIO_HANDLER_CAPI_H_
#pragma once
#include "include/capi/cef_base_capi.h"
#include "include/capi/cef_browser_capi.h"
#ifdef __cplusplus
extern "C" {
#endif
///
// Implement this structure to handle audio events.
///
typedef struct _cef_audio_handler_t {
///
// Base structure.
///
cef_base_ref_counted_t base;
///
// Called on the UI thread to allow configuration of audio stream parameters.
// Return true (1) to proceed with audio stream capture, or false (0) to
// cancel it. All members of |params| can optionally be configured here, but
// they are also pre-filled with some sensible defaults.
///
int(CEF_CALLBACK* get_audio_parameters)(struct _cef_audio_handler_t* self,
struct _cef_browser_t* browser,
cef_audio_parameters_t* params);
///
// Called on a browser audio capture thread when the browser starts streaming
// audio. OnAudioSteamStopped will always be called after
// OnAudioStreamStarted; both functions may be called multiple times for the
// same browser. |params| contains the audio parameters like sample rate and
// channel layout. |channels| is the number of channels.
///
void(CEF_CALLBACK* on_audio_stream_started)(
struct _cef_audio_handler_t* self,
struct _cef_browser_t* browser,
const cef_audio_parameters_t* params,
int channels);
///
// Called on the audio stream thread when a PCM packet is received for the
// stream. |data| is an array representing the raw PCM data as a floating
// point type, i.e. 4-byte value(s). |frames| is the number of frames in the
// PCM packet. |pts| is the presentation timestamp (in milliseconds since the
// Unix Epoch) and represents the time at which the decompressed packet should
// be presented to the user. Based on |frames| and the |channel_layout| value
// passed to OnAudioStreamStarted you can calculate the size of the |data|
// array in bytes.
///
void(CEF_CALLBACK* on_audio_stream_packet)(struct _cef_audio_handler_t* self,
struct _cef_browser_t* browser,
const float** data,
int frames,
int64 pts);
///
// Called on the UI thread when the stream has stopped. OnAudioSteamStopped
// will always be called after OnAudioStreamStarted; both functions may be
// called multiple times for the same stream.
///
void(CEF_CALLBACK* on_audio_stream_stopped)(struct _cef_audio_handler_t* self,
struct _cef_browser_t* browser);
///
// Called on the UI or audio stream thread when an error occurred. During the
// stream creation phase this callback will be called on the UI thread while
// in the capturing phase it will be called on the audio stream thread. The
// stream will be stopped immediately.
///
void(CEF_CALLBACK* on_audio_stream_error)(struct _cef_audio_handler_t* self,
struct _cef_browser_t* browser,
const cef_string_t* message);
} cef_audio_handler_t;
#ifdef __cplusplus
}
#endif
#endif // CEF_INCLUDE_CAPI_CEF_AUDIO_HANDLER_CAPI_H_

View File

@@ -33,7 +33,7 @@
// by hand. See the translator.README.txt file in the tools directory for
// more information.
//
// $hash=ba4033eaf40a8ee24408b89b78496bf1381e7e6b$
// $hash=6cb00a0fa3631a46903abb3a783f315895511db2$
//
#ifndef CEF_INCLUDE_CAPI_CEF_BROWSER_CAPI_H_
@@ -41,10 +41,12 @@
#pragma once
#include "include/capi/cef_base_capi.h"
#include "include/capi/cef_devtools_message_observer_capi.h"
#include "include/capi/cef_drag_data_capi.h"
#include "include/capi/cef_frame_capi.h"
#include "include/capi/cef_image_capi.h"
#include "include/capi/cef_navigation_entry_capi.h"
#include "include/capi/cef_registration_capi.h"
#include "include/capi/cef_request_context_capi.h"
#ifdef __cplusplus
@@ -484,6 +486,71 @@ typedef struct _cef_browser_host_t {
///
int(CEF_CALLBACK* has_dev_tools)(struct _cef_browser_host_t* self);
///
// Send a function call message over the DevTools protocol. |message| must be
// a UTF8-encoded JSON dictionary that contains "id" (int), "function"
// (string) and "params" (dictionary, optional) values. See the DevTools
// protocol documentation at https://chromedevtools.github.io/devtools-
// protocol/ for details of supported functions and the expected "params"
// dictionary contents. |message| will be copied if necessary. This function
// will return true (1) if called on the UI thread and the message was
// successfully submitted for validation, otherwise false (0). Validation will
// be applied asynchronously and any messages that fail due to formatting
// errors or missing parameters may be discarded without notification. Prefer
// ExecuteDevToolsMethod if a more structured approach to message formatting
// is desired.
//
// Every valid function call will result in an asynchronous function result or
// error message that references the sent message "id". Event messages are
// received while notifications are enabled (for example, between function
// calls for "Page.enable" and "Page.disable"). All received messages will be
// delivered to the observer(s) registered with AddDevToolsMessageObserver.
// See cef_dev_tools_message_observer_t::OnDevToolsMessage documentation for
// details of received message contents.
//
// Usage of the SendDevToolsMessage, ExecuteDevToolsMethod and
// AddDevToolsMessageObserver functions does not require an active DevTools
// front-end or remote-debugging session. Other active DevTools sessions will
// continue to function independently. However, any modification of global
// browser state by one session may not be reflected in the UI of other
// sessions.
//
// Communication with the DevTools front-end (when displayed) can be logged
// for development purposes by passing the `--devtools-protocol-log-
// file=<path>` command-line flag.
///
int(CEF_CALLBACK* send_dev_tools_message)(struct _cef_browser_host_t* self,
const void* message,
size_t message_size);
///
// Execute a function call over the DevTools protocol. This is a more
// structured version of SendDevToolsMessage. |message_id| is an incremental
// number that uniquely identifies the message (pass 0 to have the next number
// assigned automatically based on previous values). |function| is the
// function name. |params| are the function parameters, which may be NULL. See
// the DevTools protocol documentation (linked above) for details of supported
// functions and the expected |params| dictionary contents. This function will
// return the assigned message ID if called on the UI thread and the message
// was successfully submitted for validation, otherwise 0. See the
// SendDevToolsMessage documentation for additional usage information.
///
int(CEF_CALLBACK* execute_dev_tools_method)(
struct _cef_browser_host_t* self,
int message_id,
const cef_string_t* method,
struct _cef_dictionary_value_t* params);
///
// Add an observer for DevTools protocol messages (function results and
// events). The observer will remain registered until the returned
// Registration object is destroyed. See the SendDevToolsMessage documentation
// for additional usage information.
///
struct _cef_registration_t*(CEF_CALLBACK* add_dev_tools_message_observer)(
struct _cef_browser_host_t* self,
struct _cef_dev_tools_message_observer_t* observer);
///
// Retrieve a snapshot of current navigation entries as values sent to the
// specified visitor. If |current_only| is true (1) only the current

View File

@@ -33,13 +33,14 @@
// by hand. See the translator.README.txt file in the tools directory for
// more information.
//
// $hash=6a0312765614a697d56e87c8503afba8404bb08b$
// $hash=8d4cb3e0bbf230804c93898daa4a8b2866a2c1ce$
//
#ifndef CEF_INCLUDE_CAPI_CEF_CLIENT_CAPI_H_
#define CEF_INCLUDE_CAPI_CEF_CLIENT_CAPI_H_
#pragma once
#include "include/capi/cef_audio_handler_capi.h"
#include "include/capi/cef_base_capi.h"
#include "include/capi/cef_context_menu_handler_capi.h"
#include "include/capi/cef_dialog_handler_capi.h"
@@ -69,6 +70,12 @@ typedef struct _cef_client_t {
///
cef_base_ref_counted_t base;
///
// Return the handler for audio rendering events.
///
struct _cef_audio_handler_t*(CEF_CALLBACK* get_audio_handler)(
struct _cef_client_t* self);
///
// Return the handler for context menus. If no handler is provided the default
// implementation will be used.

View File

@@ -0,0 +1,147 @@
// Copyright (c) 2020 Marshall A. Greenblatt. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the name Chromium Embedded
// Framework nor the names of its contributors may be used to endorse
// or promote products derived from this software without specific prior
// written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// ---------------------------------------------------------------------------
//
// This file was generated by the CEF translator tool and should not edited
// by hand. See the translator.README.txt file in the tools directory for
// more information.
//
// $hash=86906c2e971fea7e479738f59bbf85d71ce31953$
//
#ifndef CEF_INCLUDE_CAPI_CEF_DEVTOOLS_MESSAGE_OBSERVER_CAPI_H_
#define CEF_INCLUDE_CAPI_CEF_DEVTOOLS_MESSAGE_OBSERVER_CAPI_H_
#pragma once
#include "include/capi/cef_base_capi.h"
#ifdef __cplusplus
extern "C" {
#endif
struct _cef_browser_t;
///
// Callback structure for cef_browser_host_t::AddDevToolsMessageObserver. The
// functions of this structure will be called on the browser process UI thread.
///
typedef struct _cef_dev_tools_message_observer_t {
///
// Base structure.
///
cef_base_ref_counted_t base;
///
// Method that will be called on receipt of a DevTools protocol message.
// |browser| is the originating browser instance. |message| is a UTF8-encoded
// JSON dictionary representing either a function result or an event.
// |message| is only valid for the scope of this callback and should be copied
// if necessary. Return true (1) if the message was handled or false (0) if
// the message should be further processed and passed to the
// OnDevToolsMethodResult or OnDevToolsEvent functions as appropriate.
//
// Method result dictionaries include an "id" (int) value that identifies the
// orginating function call sent from cef_browser_host_t::SendDevToolsMessage,
// and optionally either a "result" (dictionary) or "error" (dictionary)
// value. The "error" dictionary will contain "code" (int) and "message"
// (string) values. Event dictionaries include a "function" (string) value and
// optionally a "params" (dictionary) value. See the DevTools protocol
// documentation at https://chromedevtools.github.io/devtools-protocol/ for
// details of supported function calls and the expected "result" or "params"
// dictionary contents. JSON dictionaries can be parsed using the CefParseJSON
// function if desired, however be aware of performance considerations when
// parsing large messages (some of which may exceed 1MB in size).
///
int(CEF_CALLBACK* on_dev_tools_message)(
struct _cef_dev_tools_message_observer_t* self,
struct _cef_browser_t* browser,
const void* message,
size_t message_size);
///
// Method that will be called after attempted execution of a DevTools protocol
// function. |browser| is the originating browser instance. |message_id| is
// the "id" value that identifies the originating function call message. If
// the function succeeded |success| will be true (1) and |result| will be the
// UTF8-encoded JSON "result" dictionary value (which may be NULL). If the
// function failed |success| will be false (0) and |result| will be the
// UTF8-encoded JSON "error" dictionary value. |result| is only valid for the
// scope of this callback and should be copied if necessary. See the
// OnDevToolsMessage documentation for additional details on |result|
// contents.
///
void(CEF_CALLBACK* on_dev_tools_method_result)(
struct _cef_dev_tools_message_observer_t* self,
struct _cef_browser_t* browser,
int message_id,
int success,
const void* result,
size_t result_size);
///
// Method that will be called on receipt of a DevTools protocol event.
// |browser| is the originating browser instance. |function| is the "function"
// value. |params| is the UTF8-encoded JSON "params" dictionary value (which
// may be NULL). |params| is only valid for the scope of this callback and
// should be copied if necessary. See the OnDevToolsMessage documentation for
// additional details on |params| contents.
///
void(CEF_CALLBACK* on_dev_tools_event)(
struct _cef_dev_tools_message_observer_t* self,
struct _cef_browser_t* browser,
const cef_string_t* method,
const void* params,
size_t params_size);
///
// Method that will be called when the DevTools agent has attached. |browser|
// is the originating browser instance. This will generally occur in response
// to the first message sent while the agent is detached.
///
void(CEF_CALLBACK* on_dev_tools_agent_attached)(
struct _cef_dev_tools_message_observer_t* self,
struct _cef_browser_t* browser);
///
// Method that will be called when the DevTools agent has detached. |browser|
// is the originating browser instance. Any function results that were pending
// before the agent became detached will not be delivered, and any active
// event subscriptions will be canceled.
///
void(CEF_CALLBACK* on_dev_tools_agent_detached)(
struct _cef_dev_tools_message_observer_t* self,
struct _cef_browser_t* browser);
} cef_dev_tools_message_observer_t;
#ifdef __cplusplus
}
#endif
#endif // CEF_INCLUDE_CAPI_CEF_DEVTOOLS_MESSAGE_OBSERVER_CAPI_H_

View File

@@ -33,7 +33,7 @@
// by hand. See the translator.README.txt file in the tools directory for
// more information.
//
// $hash=a7070419332ec8f6d6e4df898c8eb666b988970a$
// $hash=9d5077fdb3fe7fa0ff1141f839988ac821eba4bf$
//
#ifndef CEF_INCLUDE_CAPI_CEF_MEDIA_ROUTER_CAPI_H_
@@ -50,6 +50,7 @@ extern "C" {
struct _cef_media_observer_t;
struct _cef_media_route_create_callback_t;
struct _cef_media_route_t;
struct _cef_media_sink_device_info_callback_t;
struct _cef_media_sink_t;
struct _cef_media_source_t;
@@ -264,6 +265,19 @@ typedef struct _cef_media_sink_t {
cef_string_userfree_t(CEF_CALLBACK* get_description)(
struct _cef_media_sink_t* self);
///
// Returns the icon type for this sink.
///
cef_media_sink_icon_type_t(CEF_CALLBACK* get_icon_type)(
struct _cef_media_sink_t* self);
///
// Asynchronously retrieves device info.
///
void(CEF_CALLBACK* get_device_info)(
struct _cef_media_sink_t* self,
struct _cef_media_sink_device_info_callback_t* callback);
///
// Returns true (1) if this sink accepts content via Cast.
///
@@ -281,6 +295,25 @@ typedef struct _cef_media_sink_t {
struct _cef_media_source_t* source);
} cef_media_sink_t;
///
// Callback structure for cef_media_sink_t::GetDeviceInfo. The functions of this
// structure will be called on the browser process UI thread.
///
typedef struct _cef_media_sink_device_info_callback_t {
///
// Base structure.
///
cef_base_ref_counted_t base;
///
// Method that will be executed asyncronously once device information has been
// retrieved.
///
void(CEF_CALLBACK* on_media_sink_device_info)(
struct _cef_media_sink_device_info_callback_t* self,
const struct _cef_media_sink_device_info_t* device_info);
} cef_media_sink_device_info_callback_t;
///
// Represents a source from which media can be routed. Instances of this object
// are retrieved via cef_media_router_t::GetSource. The functions of this

View File

@@ -33,7 +33,7 @@
// by hand. See the translator.README.txt file in the tools directory for
// more information.
//
// $hash=3bc4225f43428d8a3a24dcac1830dafac18b0caf$
// $hash=14cf03e02d8ca3416e65f756470afd8185c7bc78$
//
#ifndef CEF_INCLUDE_CAPI_CEF_PARSER_CAPI_H_
@@ -140,6 +140,16 @@ CEF_EXPORT struct _cef_value_t* cef_parse_json(
const cef_string_t* json_string,
cef_json_parser_options_t options);
///
// Parses the specified UTF8-encoded |json| buffer of size |json_size| and
// returns a dictionary or list representation. If JSON parsing fails this
// function returns NULL.
///
CEF_EXPORT struct _cef_value_t* cef_parse_json_buffer(
const void* json,
size_t json_size,
cef_json_parser_options_t options);
///
// Parses the specified |json_string| and returns a dictionary or list
// representation. If JSON parsing fails this function returns NULL and

View File

@@ -33,7 +33,7 @@
// by hand. See the translator.README.txt file in the tools directory for
// more information.
//
// $hash=a28219cc8c1cb53faacaf236374c3cf2c0c45bef$
// $hash=0167eb1abe614bd6391d273a8085fa3e53e7c217$
//
#ifndef CEF_INCLUDE_CAPI_CEF_REQUEST_HANDLER_CAPI_H_
@@ -253,6 +253,14 @@ typedef struct _cef_request_handler_t {
struct _cef_request_handler_t* self,
struct _cef_browser_t* browser,
cef_termination_status_t status);
///
// Called on the browser process UI thread when the window.document object of
// the main frame has been created.
///
void(CEF_CALLBACK* on_document_available_in_main_frame)(
struct _cef_request_handler_t* self,
struct _cef_browser_t* browser);
} cef_request_handler_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=b9577b495df3990284d4e4a3db2824196175dc91$
// $hash=b0e2b63b467c6d4e990405d948908da3546ea1c7$
//
#ifndef CEF_INCLUDE_CAPI_CEF_RESOURCE_BUNDLE_CAPI_H_
@@ -41,6 +41,7 @@
#pragma once
#include "include/capi/cef_base_capi.h"
#include "include/capi/cef_values_capi.h"
#ifdef __cplusplus
extern "C" {
@@ -70,34 +71,25 @@ typedef struct _cef_resource_bundle_t {
int string_id);
///
// Retrieves the contents of the specified scale independent |resource_id|. If
// the value is found then |data| and |data_size| will be populated and this
// function will return true (1). If the value is not found then this function
// will return false (0). The returned |data| pointer will remain resident in
// memory and should not be freed. Include cef_pack_resources.h for a listing
// of valid resource ID values.
// Returns a cef_binary_value_t containing the decompressed contents of the
// specified scale independent |resource_id| or NULL if not found. Include
// cef_pack_resources.h for a listing of valid resource ID values.
///
int(CEF_CALLBACK* get_data_resource)(struct _cef_resource_bundle_t* self,
int resource_id,
void** data,
size_t* data_size);
struct _cef_binary_value_t*(CEF_CALLBACK* get_data_resource)(
struct _cef_resource_bundle_t* self,
int resource_id);
///
// Retrieves the contents of the specified |resource_id| nearest the scale
// factor |scale_factor|. Use a |scale_factor| value of SCALE_FACTOR_NONE for
// scale independent resources or call GetDataResource instead. If the value
// is found then |data| and |data_size| will be populated and this function
// will return true (1). If the value is not found then this function will
// return false (0). The returned |data| pointer will remain resident in
// memory and should not be freed. Include cef_pack_resources.h for a listing
// of valid resource ID values.
// Returns a cef_binary_value_t containing the decompressed contents of the
// specified |resource_id| nearest the scale factor |scale_factor| or NULL if
// not found. Use a |scale_factor| value of SCALE_FACTOR_NONE for scale
// independent resources or call GetDataResource instead.Include
// cef_pack_resources.h for a listing of valid resource ID values.
///
int(CEF_CALLBACK* get_data_resource_for_scale)(
struct _cef_binary_value_t*(CEF_CALLBACK* get_data_resource_for_scale)(
struct _cef_resource_bundle_t* self,
int resource_id,
cef_scale_factor_t scale_factor,
void** data,
size_t* data_size);
cef_scale_factor_t scale_factor);
} cef_resource_bundle_t;
///

View File

@@ -33,7 +33,7 @@
// by hand. See the translator.README.txt file in the tools directory for
// more information.
//
// $hash=71ba0e5714400e2bea3ca564cab4527d95e4b52c$
// $hash=06f1c03ba824052122c6217c1227931f15dadd08$
//
#ifndef CEF_INCLUDE_CAPI_VIEWS_CEF_TEXTFIELD_CAPI_H_
@@ -219,16 +219,13 @@ typedef struct _cef_textfield_t {
// enabled. See additional comments on execute_command().
///
int(CEF_CALLBACK* is_command_enabled)(struct _cef_textfield_t* self,
int command_id);
cef_text_field_commands_t command_id);
///
// Performs the action associated with the specified command id. Valid values
// include IDS_APP_UNDO, IDS_APP_REDO, IDS_APP_CUT, IDS_APP_COPY,
// IDS_APP_PASTE, IDS_APP_DELETE, IDS_APP_SELECT_ALL, IDS_DELETE_* and
// IDS_MOVE_*. See include/cef_pack_strings.h for definitions.
// Performs the action associated with the specified command id.
///
void(CEF_CALLBACK* execute_command)(struct _cef_textfield_t* self,
int command_id);
cef_text_field_commands_t command_id);
///
// Clears Edit history.

View File

@@ -29,12 +29,7 @@
//
// ---------------------------------------------------------------------------
//
// This file was generated by the CEF translator tool. If making changes by
// hand only do so within the body of existing method and function
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=af15b08731cc133c3974ceb18002b146a53b9c9e$
// This file was generated by the make_api_hash_header.py tool.
//
#ifndef CEF_INCLUDE_API_HASH_H_
@@ -47,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 "f76dc8c40e454ef26318d0f83312dadaf909e4c5"
#define CEF_API_HASH_UNIVERSAL "63365efe2e93a4e7cc789cbb8f618d61c92c1b6d"
#if defined(OS_WIN)
#define CEF_API_HASH_PLATFORM "831ef33853bb8575bcd097ba65851d4d98a08db8"
#define CEF_API_HASH_PLATFORM "726d42ca7d92188542b433d88d17a87af5b53c05"
#elif defined(OS_MACOSX)
#define CEF_API_HASH_PLATFORM "0944363458590a23d84e99eb1b81372be6784b97"
#define CEF_API_HASH_PLATFORM "1c8a413434b592d388446e66b54a3f0bfc0d6fff"
#elif defined(OS_LINUX)
#define CEF_API_HASH_PLATFORM "dfd012193a93782cd4b041f4cd71e1e8f2ca401e"
#define CEF_API_HASH_PLATFORM "13f7e0e86daab3b1a08d8a31103fc93e45cc508f"
#endif
#ifdef __cplusplus

111
include/cef_audio_handler.h Normal file
View File

@@ -0,0 +1,111 @@
// Copyright (c) 2019 Marshall A. Greenblatt. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the name Chromium Embedded
// Framework nor the names of its contributors may be used to endorse
// or promote products derived from this software without specific prior
// written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// ---------------------------------------------------------------------------
//
// The contents of this file must follow a specific format in order to
// support the CEF translator tool. See the translator.README.txt file in the
// tools directory for more information.
//
#ifndef CEF_INCLUDE_CEF_AUDIO_HANDLER_H_
#define CEF_INCLUDE_CEF_AUDIO_HANDLER_H_
#pragma once
#include "include/cef_base.h"
#include "include/cef_browser.h"
///
// Implement this interface to handle audio events.
///
/*--cef(source=client)--*/
class CefAudioHandler : public virtual CefBaseRefCounted {
public:
typedef cef_channel_layout_t ChannelLayout;
///
// Called on the UI thread to allow configuration of audio stream parameters.
// Return true to proceed with audio stream capture, or false to cancel it.
// All members of |params| can optionally be configured here, but they are
// also pre-filled with some sensible defaults.
///
/*--cef()--*/
virtual bool GetAudioParameters(CefRefPtr<CefBrowser> browser,
CefAudioParameters& params) {
return true;
}
///
// Called on a browser audio capture thread when the browser starts
// streaming audio. OnAudioSteamStopped will always be called after
// OnAudioStreamStarted; both methods may be called multiple times
// for the same browser. |params| contains the audio parameters like
// sample rate and channel layout. |channels| is the number of channels.
///
/*--cef()--*/
virtual void OnAudioStreamStarted(CefRefPtr<CefBrowser> browser,
const CefAudioParameters& params,
int channels) = 0;
///
// Called on the audio stream thread when a PCM packet is received for the
// stream. |data| is an array representing the raw PCM data as a floating
// point type, i.e. 4-byte value(s). |frames| is the number of frames in the
// PCM packet. |pts| is the presentation timestamp (in milliseconds since the
// Unix Epoch) and represents the time at which the decompressed packet should
// be presented to the user. Based on |frames| and the |channel_layout| value
// passed to OnAudioStreamStarted you can calculate the size of the |data|
// array in bytes.
///
/*--cef()--*/
virtual void OnAudioStreamPacket(CefRefPtr<CefBrowser> browser,
const float** data,
int frames,
int64 pts) = 0;
///
// Called on the UI thread when the stream has stopped. OnAudioSteamStopped
// will always be called after OnAudioStreamStarted; both methods may be
// called multiple times for the same stream.
///
/*--cef()--*/
virtual void OnAudioStreamStopped(CefRefPtr<CefBrowser> browser) = 0;
///
// Called on the UI or audio stream thread when an error occurred. During the
// stream creation phase this callback will be called on the UI thread while
// in the capturing phase it will be called on the audio stream thread. The
// stream will be stopped immediately.
///
/*--cef()--*/
virtual void OnAudioStreamError(CefRefPtr<CefBrowser> browser,
const CefString& message) = 0;
};
#endif // CEF_INCLUDE_CEF_AUDIO_HANDLER_H_

View File

@@ -40,10 +40,12 @@
#include <vector>
#include "include/cef_base.h"
#include "include/cef_devtools_message_observer.h"
#include "include/cef_drag_data.h"
#include "include/cef_frame.h"
#include "include/cef_image.h"
#include "include/cef_navigation_entry.h"
#include "include/cef_registration.h"
#include "include/cef_request_context.h"
class CefBrowserHost;
@@ -517,6 +519,69 @@ class CefBrowserHost : public virtual CefBaseRefCounted {
/*--cef()--*/
virtual bool HasDevTools() = 0;
///
// Send a method call message over the DevTools protocol. |message| must be a
// UTF8-encoded JSON dictionary that contains "id" (int), "method" (string)
// and "params" (dictionary, optional) values. See the DevTools protocol
// documentation at https://chromedevtools.github.io/devtools-protocol/ for
// details of supported methods and the expected "params" dictionary contents.
// |message| will be copied if necessary. This method will return true if
// called on the UI thread and the message was successfully submitted for
// validation, otherwise false. Validation will be applied asynchronously and
// any messages that fail due to formatting errors or missing parameters may
// be discarded without notification. Prefer ExecuteDevToolsMethod if a more
// structured approach to message formatting is desired.
//
// Every valid method call will result in an asynchronous method result or
// error message that references the sent message "id". Event messages are
// received while notifications are enabled (for example, between method calls
// for "Page.enable" and "Page.disable"). All received messages will be
// delivered to the observer(s) registered with AddDevToolsMessageObserver.
// See CefDevToolsMessageObserver::OnDevToolsMessage documentation for details
// of received message contents.
//
// Usage of the SendDevToolsMessage, ExecuteDevToolsMethod and
// AddDevToolsMessageObserver methods does not require an active DevTools
// front-end or remote-debugging session. Other active DevTools sessions will
// continue to function independently. However, any modification of global
// browser state by one session may not be reflected in the UI of other
// sessions.
//
// Communication with the DevTools front-end (when displayed) can be logged
// for development purposes by passing the
// `--devtools-protocol-log-file=<path>` command-line flag.
///
/*--cef()--*/
virtual bool SendDevToolsMessage(const void* message,
size_t message_size) = 0;
///
// Execute a method call over the DevTools protocol. This is a more structured
// version of SendDevToolsMessage. |message_id| is an incremental number that
// uniquely identifies the message (pass 0 to have the next number assigned
// automatically based on previous values). |method| is the method name.
// |params| are the method parameters, which may be empty. See the DevTools
// protocol documentation (linked above) for details of supported methods and
// the expected |params| dictionary contents. This method will return the
// assigned message ID if called on the UI thread and the message was
// successfully submitted for validation, otherwise 0. See the
// SendDevToolsMessage documentation for additional usage information.
///
/*--cef(optional_param=params)--*/
virtual int ExecuteDevToolsMethod(int message_id,
const CefString& method,
CefRefPtr<CefDictionaryValue> params) = 0;
///
// Add an observer for DevTools protocol messages (method results and events).
// The observer will remain registered until the returned Registration object
// is destroyed. See the SendDevToolsMessage documentation for additional
// usage information.
///
/*--cef()--*/
virtual CefRefPtr<CefRegistration> AddDevToolsMessageObserver(
CefRefPtr<CefDevToolsMessageObserver> observer) = 0;
///
// Retrieve a snapshot of current navigation entries as values sent to the
// specified visitor. If |current_only| is true only the current navigation

View File

@@ -38,6 +38,7 @@
#define CEF_INCLUDE_CEF_CLIENT_H_
#pragma once
#include "include/cef_audio_handler.h"
#include "include/cef_base.h"
#include "include/cef_context_menu_handler.h"
#include "include/cef_dialog_handler.h"
@@ -60,6 +61,12 @@
/*--cef(source=client,no_debugct_check)--*/
class CefClient : public virtual CefBaseRefCounted {
public:
///
// Return the handler for audio rendering events.
///
/*--cef()--*/
virtual CefRefPtr<CefAudioHandler> GetAudioHandler() { return nullptr; }
///
// Return the handler for context menus. If no handler is provided the default
// implementation will be used.

View File

@@ -0,0 +1,130 @@
// Copyright (c) 2020 Marshall A. Greenblatt. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the name Chromium Embedded
// Framework nor the names of its contributors may be used to endorse
// or promote products derived from this software without specific prior
// written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// ---------------------------------------------------------------------------
//
// The contents of this file must follow a specific format in order to
// support the CEF translator tool. See the translator.README.txt file in the
// tools directory for more information.
//
#ifndef CEF_INCLUDE_CEF_DEVTOOLS_MESSAGE_OBSERVER_H_
#define CEF_INCLUDE_CEF_DEVTOOLS_MESSAGE_OBSERVER_H_
#pragma once
#include "include/cef_base.h"
class CefBrowser;
///
// Callback interface for CefBrowserHost::AddDevToolsMessageObserver. The
// methods of this class will be called on the browser process UI thread.
///
/*--cef(source=client)--*/
class CefDevToolsMessageObserver : public virtual CefBaseRefCounted {
public:
///
// Method that will be called on receipt of a DevTools protocol message.
// |browser| is the originating browser instance. |message| is a UTF8-encoded
// JSON dictionary representing either a method result or an event. |message|
// is only valid for the scope of this callback and should be copied if
// necessary. Return true if the message was handled or false if the message
// should be further processed and passed to the OnDevToolsMethodResult or
// OnDevToolsEvent methods as appropriate.
//
// Method result dictionaries include an "id" (int) value that identifies the
// orginating method call sent from CefBrowserHost::SendDevToolsMessage, and
// optionally either a "result" (dictionary) or "error" (dictionary) value.
// The "error" dictionary will contain "code" (int) and "message" (string)
// values. Event dictionaries include a "method" (string) value and optionally
// a "params" (dictionary) value. See the DevTools protocol documentation at
// https://chromedevtools.github.io/devtools-protocol/ for details of
// supported method calls and the expected "result" or "params" dictionary
// contents. JSON dictionaries can be parsed using the CefParseJSON function
// if desired, however be aware of performance considerations when parsing
// large messages (some of which may exceed 1MB in size).
///
/*--cef()--*/
virtual bool OnDevToolsMessage(CefRefPtr<CefBrowser> browser,
const void* message,
size_t message_size) {
return false;
}
///
// Method that will be called after attempted execution of a DevTools protocol
// method. |browser| is the originating browser instance. |message_id| is the
// "id" value that identifies the originating method call message. If the
// method succeeded |success| will be true and |result| will be the
// UTF8-encoded JSON "result" dictionary value (which may be empty). If the
// method failed |success| will be false and |result| will be the UTF8-encoded
// JSON "error" dictionary value. |result| is only valid for the scope of this
// callback and should be copied if necessary. See the OnDevToolsMessage
// documentation for additional details on |result| contents.
///
/*--cef(optional_param=result)--*/
virtual void OnDevToolsMethodResult(CefRefPtr<CefBrowser> browser,
int message_id,
bool success,
const void* result,
size_t result_size) {}
///
// Method that will be called on receipt of a DevTools protocol event.
// |browser| is the originating browser instance. |method| is the "method"
// value. |params| is the UTF8-encoded JSON "params" dictionary value (which
// may be empty). |params| is only valid for the scope of this callback and
// should be copied if necessary. See the OnDevToolsMessage documentation for
// additional details on |params| contents.
///
/*--cef(optional_param=params)--*/
virtual void OnDevToolsEvent(CefRefPtr<CefBrowser> browser,
const CefString& method,
const void* params,
size_t params_size) {}
///
// Method that will be called when the DevTools agent has attached. |browser|
// is the originating browser instance. This will generally occur in response
// to the first message sent while the agent is detached.
///
/*--cef()--*/
virtual void OnDevToolsAgentAttached(CefRefPtr<CefBrowser> browser) {}
///
// Method that will be called when the DevTools agent has detached. |browser|
// is the originating browser instance. Any method results that were pending
// before the agent became detached will not be delivered, and any active
// event subscriptions will be canceled.
///
/*--cef()--*/
virtual void OnDevToolsAgentDetached(CefRefPtr<CefBrowser> browser) {}
};
#endif // CEF_INCLUDE_CEF_DEVTOOLS_MESSAGE_OBSERVER_H_

View File

@@ -46,6 +46,7 @@ class CefMediaObserver;
class CefMediaRoute;
class CefMediaRouteCreateCallback;
class CefMediaSink;
class CefMediaSinkDeviceInfoCallback;
class CefMediaSource;
///
@@ -221,6 +222,8 @@ class CefMediaRouteCreateCallback : public virtual CefBaseRefCounted {
/*--cef(source=library)--*/
class CefMediaSink : public virtual CefBaseRefCounted {
public:
typedef cef_media_sink_icon_type_t IconType;
///
// Returns the ID for this sink.
///
@@ -245,6 +248,19 @@ class CefMediaSink : public virtual CefBaseRefCounted {
/*--cef()--*/
virtual CefString GetDescription() = 0;
///
// Returns the icon type for this sink.
///
/*--cef(default_retval=CEF_MSIT_GENERIC)--*/
virtual IconType GetIconType() = 0;
///
// Asynchronously retrieves device info.
///
/*--cef()--*/
virtual void GetDeviceInfo(
CefRefPtr<CefMediaSinkDeviceInfoCallback> callback) = 0;
///
// Returns true if this sink accepts content via Cast.
///
@@ -264,6 +280,22 @@ class CefMediaSink : public virtual CefBaseRefCounted {
virtual bool IsCompatibleWith(CefRefPtr<CefMediaSource> source) = 0;
};
///
// Callback interface for CefMediaSink::GetDeviceInfo. The methods of this
// class will be called on the browser process UI thread.
///
/*--cef(source=client)--*/
class CefMediaSinkDeviceInfoCallback : public virtual CefBaseRefCounted {
public:
///
// Method that will be executed asyncronously once device information has been
// retrieved.
///
/*--cef()--*/
virtual void OnMediaSinkDeviceInfo(
const CefMediaSinkDeviceInfo& device_info) = 0;
};
///
// Represents a source from which media can be routed. Instances of this object
// are retrieved via CefMediaRouter::GetSource. The methods of this class may be

View File

@@ -133,6 +133,16 @@ CefString CefURIDecode(const CefString& text,
CefRefPtr<CefValue> CefParseJSON(const CefString& json_string,
cef_json_parser_options_t options);
///
// Parses the specified UTF8-encoded |json| buffer of size |json_size| and
// returns a dictionary or list representation. If JSON parsing fails this
// method returns NULL.
///
/*--cef(capi_name=cef_parse_json_buffer)--*/
CefRefPtr<CefValue> CefParseJSON(const void* json,
size_t json_size,
cef_json_parser_options_t options);
///
// Parses the specified |json_string| and returns a dictionary or list
// representation. If JSON parsing fails this method returns NULL and populates

View File

@@ -252,6 +252,13 @@ class CefRequestHandler : public virtual CefBaseRefCounted {
/*--cef()--*/
virtual void OnRenderProcessTerminated(CefRefPtr<CefBrowser> browser,
TerminationStatus status) {}
///
// Called on the browser process UI thread when the window.document object of
// the main frame has been created.
///
/*--cef()--*/
virtual void OnDocumentAvailableInMainFrame(CefRefPtr<CefBrowser> browser) {}
};
#endif // CEF_INCLUDE_CEF_REQUEST_HANDLER_H_

View File

@@ -39,6 +39,7 @@
#pragma once
#include "include/cef_base.h"
#include "include/cef_values.h"
///
// Class used for retrieving resources from the resource bundle (*.pak) files
@@ -67,33 +68,24 @@ class CefResourceBundle : public virtual CefBaseRefCounted {
virtual CefString GetLocalizedString(int string_id) = 0;
///
// Retrieves the contents of the specified scale independent |resource_id|.
// If the value is found then |data| and |data_size| will be populated and
// this method will return true. If the value is not found then this method
// will return false. The returned |data| pointer will remain resident in
// memory and should not be freed. Include cef_pack_resources.h for a listing
// of valid resource ID values.
// Returns a CefBinaryValue containing the decompressed contents of the
// specified scale independent |resource_id| or NULL if not found. Include
// cef_pack_resources.h for a listing of valid resource ID values.
///
/*--cef()--*/
virtual bool GetDataResource(int resource_id,
void*& data,
size_t& data_size) = 0;
virtual CefRefPtr<CefBinaryValue> GetDataResource(int resource_id) = 0;
///
// Retrieves the contents of the specified |resource_id| nearest the scale
// factor |scale_factor|. Use a |scale_factor| value of SCALE_FACTOR_NONE for
// scale independent resources or call GetDataResource instead. If the value
// is found then |data| and |data_size| will be populated and this method will
// return true. If the value is not found then this method will return false.
// The returned |data| pointer will remain resident in memory and should not
// be freed. Include cef_pack_resources.h for a listing of valid resource ID
// values.
// Returns a CefBinaryValue containing the decompressed contents of the
// specified |resource_id| nearest the scale factor |scale_factor| or NULL if
// not found. Use a |scale_factor| value of SCALE_FACTOR_NONE for scale
// independent resources or call GetDataResource instead.Include
// cef_pack_resources.h for a listing of valid resource ID values.
///
/*--cef()--*/
virtual bool GetDataResourceForScale(int resource_id,
ScaleFactor scale_factor,
void*& data,
size_t& data_size) = 0;
virtual CefRefPtr<CefBinaryValue> GetDataResourceForScale(
int resource_id,
ScaleFactor scale_factor) = 0;
};
#endif // CEF_INCLUDE_CEF_RESOURCE_BUNDLE_H_

View File

@@ -170,23 +170,25 @@ typedef struct _cef_settings_t {
// will be used. If this value is empty on macOS then a helper executable must
// exist at "Contents/Frameworks/<app> Helper.app/Contents/MacOS/<app> Helper"
// in the top-level app bundle. See the comments on CefExecuteProcess() for
// details. Also configurable using the "browser-subprocess-path" command-line
// switch.
// details. If this value is non-empty then it must be an absolute path. Also
// configurable using the "browser-subprocess-path" command-line switch.
///
cef_string_t browser_subprocess_path;
///
// The path to the CEF framework directory on macOS. If this value is empty
// then the framework must exist at "Contents/Frameworks/Chromium Embedded
// Framework.framework" in the top-level app bundle. Also configurable using
// the "framework-dir-path" command-line switch.
// Framework.framework" in the top-level app bundle. If this value is
// non-empty then it must be an absolute path. Also configurable using the
// "framework-dir-path" command-line switch.
///
cef_string_t framework_dir_path;
///
// The path to the main bundle on macOS. If this value is empty then it
// defaults to the top-level app bundle. Also configurable using
// the "main-bundle-path" command-line switch.
// defaults to the top-level app bundle. If this value is non-empty then it
// must be an absolute path. Also configurable using the "main-bundle-path"
// command-line switch.
///
cef_string_t main_bundle_path;
@@ -227,33 +229,35 @@ typedef struct _cef_settings_t {
///
// The location where data for the global browser cache will be stored on
// disk. If non-empty this must be either equal to or a child directory of
// CefSettings.root_cache_path. If empty then browsers will be created in
// "incognito mode" where 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.
// disk. If this value is non-empty then it must be an absolute path that is
// either equal to or a child directory of CefSettings.root_cache_path. If
// this value is empty then browsers will be created in "incognito mode" where
// 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.
///
cef_string_t cache_path;
///
// The root directory that all CefSettings.cache_path and
// CefRequestContextSettings.cache_path values must have in common. If this
// value is empty and CefSettings.cache_path is non-empty then this value will
// default to the CefSettings.cache_path value. Failure to set this value
// correctly may result in the sandbox blocking read/write access to the
// cache_path directory.
// value is empty and CefSettings.cache_path is non-empty then it will
// default to the CefSettings.cache_path value. If this value is non-empty
// then it must be an absolute path. Failure to set this value correctly may
// result in the sandbox blocking read/write access to the cache_path
// directory.
///
cef_string_t root_cache_path;
///
// The location where user data such as spell checking dictionary files will
// be stored on disk. If empty then the default platform-specific user data
// directory will be used ("~/.cef_user_data" 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).
// be stored on disk. If this value is empty then the default
// platform-specific user data directory will be used ("~/.cef_user_data"
// 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.
///
cef_string_t user_data_path;
@@ -333,16 +337,17 @@ typedef struct _cef_settings_t {
// The fully qualified path for the resources directory. If this value is
// empty the cef.pak and/or devtools_resources.pak files must be located in
// the module directory on Windows/Linux or the app bundle Resources directory
// on Mac OS X. Also configurable using the "resources-dir-path" command-line
// switch.
// on Mac OS X. If this value is non-empty then it must be an absolute path.
// Also configurable using the "resources-dir-path" command-line switch.
///
cef_string_t resources_dir_path;
///
// The fully qualified path for the locales directory. If this value is empty
// the locales directory must be located in the module directory. This value
// is ignored on Mac OS X where pack files are always loaded from the app
// bundle Resources directory. Also configurable using the "locales-dir-path"
// the locales directory must be located in the module directory. If this
// value is non-empty then it must be an absolute path. This value is ignored
// on Mac OS X where pack files are always loaded from the app bundle
// Resources directory. Also configurable using the "locales-dir-path"
// command-line switch.
///
cef_string_t locales_dir_path;
@@ -428,13 +433,13 @@ typedef struct _cef_request_context_settings_t {
///
// The location where cache data for this request context will be stored on
// disk. If non-empty this must be either equal to or a child directory of
// CefSettings.root_cache_path. If empty then browsers will be created in
// "incognito mode" where 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. To share the global browser
// cache and related configuration set this value to match the
// CefSettings.cache_path value.
// disk. If this value is non-empty then it must be an absolute path that is
// either equal to or a child directory of CefSettings.root_cache_path. If
// this value is empty then browsers will be created in "incognito mode" where
// 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. To share the global browser cache and related
// configuration set this value to match the CefSettings.cache_path value.
///
cef_string_t cache_path;
@@ -732,6 +737,25 @@ typedef struct _cef_urlparts_t {
cef_string_t fragment;
} cef_urlparts_t;
///
// Cookie priority values.
///
typedef enum {
CEF_COOKIE_PRIORITY_LOW = -1,
CEF_COOKIE_PRIORITY_MEDIUM = 0,
CEF_COOKIE_PRIORITY_HIGH = 1,
} cef_cookie_priority_t;
///
// Cookie same site values.
///
typedef enum {
CEF_COOKIE_SAME_SITE_UNSPECIFIED,
CEF_COOKIE_SAME_SITE_NO_RESTRICTION,
CEF_COOKIE_SAME_SITE_LAX_MODE,
CEF_COOKIE_SAME_SITE_STRICT_MODE,
} cef_cookie_same_site_t;
///
// Cookie information.
///
@@ -786,6 +810,16 @@ typedef struct _cef_cookie_t {
///
int has_expires;
cef_time_t expires;
///
// Same site.
///
cef_cookie_same_site_t same_site;
///
// Priority.
///
cef_cookie_priority_t priority;
} cef_cookie_t;
///
@@ -2430,13 +2464,13 @@ typedef struct _cef_pdf_print_settings_t {
int scale_factor;
///
// Margins in millimeters. Only used if |margin_type| is set to
// Margins in points. Only used if |margin_type| is set to
// PDF_PRINT_MARGIN_CUSTOM.
///
double margin_top;
double margin_right;
double margin_bottom;
double margin_left;
int margin_top;
int margin_right;
int margin_bottom;
int margin_left;
///
// Margin type.
@@ -2970,9 +3004,139 @@ typedef struct _cef_composition_underline_t {
} cef_composition_underline_t;
///
// Result codes for CefMediaRouter::CreateRoute. These constants match
// their equivalents in Chromium's route_request_result.h and should not be
// renumbered.
// Enumerates the various representations of the ordering of audio channels.
// Must be kept synchronized with media::ChannelLayout from Chromium.
// See media\base\channel_layout.h
///
typedef enum {
CEF_CHANNEL_LAYOUT_NONE = 0,
CEF_CHANNEL_LAYOUT_UNSUPPORTED = 1,
// Front C
CEF_CHANNEL_LAYOUT_MONO = 2,
// Front L, Front R
CEF_CHANNEL_LAYOUT_STEREO = 3,
// Front L, Front R, Back C
CEF_CHANNEL_LAYOUT_2_1 = 4,
// Front L, Front R, Front C
CEF_CHANNEL_LAYOUT_SURROUND = 5,
// Front L, Front R, Front C, Back C
CEF_CHANNEL_LAYOUT_4_0 = 6,
// Front L, Front R, Side L, Side R
CEF_CHANNEL_LAYOUT_2_2 = 7,
// Front L, Front R, Back L, Back R
CEF_CHANNEL_LAYOUT_QUAD = 8,
// Front L, Front R, Front C, Side L, Side R
CEF_CHANNEL_LAYOUT_5_0 = 9,
// Front L, Front R, Front C, LFE, Side L, Side R
CEF_CHANNEL_LAYOUT_5_1 = 10,
// Front L, Front R, Front C, Back L, Back R
CEF_CHANNEL_LAYOUT_5_0_BACK = 11,
// Front L, Front R, Front C, LFE, Back L, Back R
CEF_CHANNEL_LAYOUT_5_1_BACK = 12,
// Front L, Front R, Front C, Side L, Side R, Back L, Back R
CEF_CHANNEL_LAYOUT_7_0 = 13,
// Front L, Front R, Front C, LFE, Side L, Side R, Back L, Back R
CEF_CHANNEL_LAYOUT_7_1 = 14,
// Front L, Front R, Front C, LFE, Side L, Side R, Front LofC, Front RofC
CEF_CHANNEL_LAYOUT_7_1_WIDE = 15,
// Stereo L, Stereo R
CEF_CHANNEL_LAYOUT_STEREO_DOWNMIX = 16,
// Stereo L, Stereo R, LFE
CEF_CHANNEL_LAYOUT_2POINT1 = 17,
// Stereo L, Stereo R, Front C, LFE
CEF_CHANNEL_LAYOUT_3_1 = 18,
// Stereo L, Stereo R, Front C, Rear C, LFE
CEF_CHANNEL_LAYOUT_4_1 = 19,
// Stereo L, Stereo R, Front C, Side L, Side R, Back C
CEF_CHANNEL_LAYOUT_6_0 = 20,
// Stereo L, Stereo R, Side L, Side R, Front LofC, Front RofC
CEF_CHANNEL_LAYOUT_6_0_FRONT = 21,
// Stereo L, Stereo R, Front C, Rear L, Rear R, Rear C
CEF_CHANNEL_LAYOUT_HEXAGONAL = 22,
// Stereo L, Stereo R, Front C, LFE, Side L, Side R, Rear Center
CEF_CHANNEL_LAYOUT_6_1 = 23,
// Stereo L, Stereo R, Front C, LFE, Back L, Back R, Rear Center
CEF_CHANNEL_LAYOUT_6_1_BACK = 24,
// Stereo L, Stereo R, Side L, Side R, Front LofC, Front RofC, LFE
CEF_CHANNEL_LAYOUT_6_1_FRONT = 25,
// Front L, Front R, Front C, Side L, Side R, Front LofC, Front RofC
CEF_CHANNEL_LAYOUT_7_0_FRONT = 26,
// Front L, Front R, Front C, LFE, Back L, Back R, Front LofC, Front RofC
CEF_CHANNEL_LAYOUT_7_1_WIDE_BACK = 27,
// Front L, Front R, Front C, Side L, Side R, Rear L, Back R, Back C.
CEF_CHANNEL_LAYOUT_OCTAGONAL = 28,
// Channels are not explicitly mapped to speakers.
CEF_CHANNEL_LAYOUT_DISCRETE = 29,
// Front L, Front R, Front C. Front C contains the keyboard mic audio. This
// layout is only intended for input for WebRTC. The Front C channel
// is stripped away in the WebRTC audio input pipeline and never seen outside
// of that.
CEF_CHANNEL_LAYOUT_STEREO_AND_KEYBOARD_MIC = 30,
// Front L, Front R, Side L, Side R, LFE
CEF_CHANNEL_LAYOUT_4_1_QUAD_SIDE = 31,
// Actual channel layout is specified in the bitstream and the actual channel
// count is unknown at Chromium media pipeline level (useful for audio
// pass-through mode).
CEF_CHANNEL_LAYOUT_BITSTREAM = 32,
// Max value, must always equal the largest entry ever logged.
CEF_CHANNEL_LAYOUT_MAX = CEF_CHANNEL_LAYOUT_BITSTREAM
} cef_channel_layout_t;
///
// Structure representing the audio parameters for setting up the audio handler.
///
typedef struct _cef_audio_parameters_t {
///
// Layout of the audio channels
///
cef_channel_layout_t channel_layout;
///
// Sample rate
//
int sample_rate;
///
// Number of frames per buffer
///
int frames_per_buffer;
} cef_audio_parameters_t;
///
// Result codes for CefMediaRouter::CreateRoute. Should be kept in sync with
// Chromium's media_router::RouteRequestResult::ResultCode type.
///
typedef enum {
CEF_MRCR_UNKNOWN_ERROR = 0,
@@ -2999,6 +3163,44 @@ typedef enum {
CEF_MRCS_TERMINATED,
} cef_media_route_connection_state_t;
///
// Icon types for a MediaSink object. Should be kept in sync with Chromium's
// media_router::SinkIconType type.
///
typedef enum {
CEF_MSIT_CAST,
CEF_MSIT_CAST_AUDIO_GROUP,
CEF_MSIT_CAST_AUDIO,
CEF_MSIT_MEETING,
CEF_MSIT_HANGOUT,
CEF_MSIT_EDUCATION,
CEF_MSIT_WIRED_DISPLAY,
CEF_MSIT_GENERIC,
CEF_MSIT_TOTAL_COUNT, // The total number of values.
} cef_media_sink_icon_type_t;
///
// Device information for a MediaSink object.
///
typedef struct _cef_media_sink_device_info_t {
cef_string_t ip_address;
int port;
cef_string_t model_name;
} cef_media_sink_device_info_t;
///
// Represents commands available to TextField.
///
typedef enum {
CEF_TFC_CUT = 1,
CEF_TFC_COPY,
CEF_TFC_PASTE,
CEF_TFC_UNDO,
CEF_TFC_DELETE,
CEF_TFC_SELECT_ALL,
} cef_text_field_commands_t;
#ifdef __cplusplus
}
#endif

View File

@@ -851,6 +851,8 @@ struct CefCookieTraits {
target->last_access = src->last_access;
target->has_expires = src->has_expires;
target->expires = src->expires;
target->same_site = src->same_site;
target->priority = src->priority;
}
};
@@ -958,4 +960,49 @@ struct CefCompositionUnderlineTraits {
///
typedef CefStructBase<CefCompositionUnderlineTraits> CefCompositionUnderline;
struct CefAudioParametersTraits {
typedef cef_audio_parameters_t struct_type;
static inline void init(struct_type* s) {}
static inline void clear(struct_type* s) {}
static inline void set(const struct_type* src,
struct_type* target,
bool copy) {
*target = *src;
}
};
///
// Class representing CefAudioParameters settings
///
typedef CefStructBase<CefAudioParametersTraits> CefAudioParameters;
struct CefMediaSinkDeviceInfoTraits {
typedef cef_media_sink_device_info_t struct_type;
static inline void init(struct_type* s) {}
static inline void clear(struct_type* s) {
cef_string_clear(&s->ip_address);
cef_string_clear(&s->model_name);
}
static inline void set(const struct_type* src,
struct_type* target,
bool copy) {
cef_string_set(src->ip_address.str, src->ip_address.length,
&target->ip_address, copy);
target->port = src->port;
cef_string_set(src->model_name.str, src->model_name.length,
&target->model_name, copy);
}
};
///
// Class representing MediaSink device info.
///
typedef CefStructBase<CefMediaSinkDeviceInfoTraits> CefMediaSinkDeviceInfo;
#endif // CEF_INCLUDE_INTERNAL_CEF_TYPES_WRAPPERS_H_

View File

@@ -224,16 +224,13 @@ class CefTextfield : public CefView {
// enabled. See additional comments on ExecuteCommand().
///
/*--cef()--*/
virtual bool IsCommandEnabled(int command_id) = 0;
virtual bool IsCommandEnabled(cef_text_field_commands_t command_id) = 0;
///
// Performs the action associated with the specified command id. Valid values
// include IDS_APP_UNDO, IDS_APP_REDO, IDS_APP_CUT, IDS_APP_COPY,
// IDS_APP_PASTE, IDS_APP_DELETE, IDS_APP_SELECT_ALL, IDS_DELETE_* and
// IDS_MOVE_*. See include/cef_pack_strings.h for definitions.
// Performs the action associated with the specified command id.
///
/*--cef()--*/
virtual void ExecuteCommand(int command_id) = 0;
virtual void ExecuteCommand(cef_text_field_commands_t command_id) = 0;
///
// Clears Edit history.

View File

@@ -0,0 +1,125 @@
// Copyright (c) 2019 The Chromium Embedded Framework Authors.
// Portions copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "libcef/browser/audio_capturer.h"
#include "libcef/browser/browser_host_impl.h"
#include "components/mirroring/service/captured_audio_input.h"
#include "content/public/browser/audio_loopback_stream_creator.h"
#include "media/audio/audio_input_device.h"
namespace {
media::ChannelLayout TranslateChannelLayout(
cef_channel_layout_t channel_layout) {
// Verify that our enum matches Chromium's values. The enum values match
// between those enums and existing values don't ever change, so it's enough
// to check that there are no new ones added.
static_assert(
static_cast<int>(CEF_CHANNEL_LAYOUT_MAX) ==
static_cast<int>(media::CHANNEL_LAYOUT_MAX),
"cef_channel_layout_t must match the ChannelLayout enum in Chromium");
return static_cast<media::ChannelLayout>(channel_layout);
}
void StreamCreatorHelper(
content::WebContents* source_web_contents,
content::AudioLoopbackStreamCreator* audio_stream_creator,
mojo::PendingRemote<mirroring::mojom::AudioStreamCreatorClient> client,
const media::AudioParameters& params,
uint32_t total_segments) {
audio_stream_creator->CreateLoopbackStream(
source_web_contents, params, total_segments,
base::BindRepeating(
[](mojo::PendingRemote<mirroring::mojom::AudioStreamCreatorClient>
client,
mojo::PendingRemote<media::mojom::AudioInputStream> stream,
mojo::PendingReceiver<media::mojom::AudioInputStreamClient>
client_receiver,
media::mojom::ReadOnlyAudioDataPipePtr data_pipe) {
mojo::Remote<mirroring::mojom::AudioStreamCreatorClient>
audio_client(std::move(client));
audio_client->StreamCreated(std::move(stream),
std::move(client_receiver),
std::move(data_pipe));
},
base::Passed(&client)));
}
} // namespace
CefAudioCapturer::CefAudioCapturer(const CefAudioParameters& params,
CefRefPtr<CefBrowserHostImpl> browser,
CefRefPtr<CefAudioHandler> audio_handler)
: params_(params),
browser_(browser),
audio_handler_(audio_handler),
audio_stream_creator_(content::AudioLoopbackStreamCreator::
CreateInProcessAudioLoopbackStreamCreator()) {
media::AudioParameters audio_params(
media::AudioParameters::AUDIO_PCM_LINEAR,
TranslateChannelLayout(params.channel_layout), params.sample_rate,
params.frames_per_buffer);
if (!audio_params.IsValid()) {
LOG(ERROR) << "Invalid audio parameters";
return;
}
DCHECK(browser_);
DCHECK(audio_handler_);
DCHECK(browser_->web_contents());
channels_ = audio_params.channels();
audio_input_device_ = new media::AudioInputDevice(
std::make_unique<mirroring::CapturedAudioInput>(base::BindRepeating(
&StreamCreatorHelper, base::Unretained(browser_->web_contents()),
base::Unretained(audio_stream_creator_.get()))),
media::AudioInputDevice::kLoopback);
audio_input_device_->Initialize(audio_params, this);
audio_input_device_->Start();
}
CefAudioCapturer::~CefAudioCapturer() {
StopStream();
}
void CefAudioCapturer::OnCaptureStarted() {
audio_handler_->OnAudioStreamStarted(browser_, params_, channels_);
DCHECK(!capturing_);
capturing_ = true;
}
void CefAudioCapturer::Capture(const media::AudioBus* source,
base::TimeTicks audio_capture_time,
double /*volume*/,
bool /*key_pressed*/) {
const int channels = source->channels();
std::array<const float*, media::CHANNELS_MAX> data;
DCHECK(channels == channels_);
DCHECK(channels <= static_cast<int>(data.size()));
for (int c = 0; c < channels; ++c) {
data[c] = source->channel(c);
}
base::TimeDelta pts = audio_capture_time - base::TimeTicks::UnixEpoch();
audio_handler_->OnAudioStreamPacket(browser_, data.data(), source->frames(),
pts.InMilliseconds());
}
void CefAudioCapturer::OnCaptureError(const std::string& message) {
audio_handler_->OnAudioStreamError(browser_, message);
StopStream();
}
void CefAudioCapturer::StopStream() {
if (audio_input_device_)
audio_input_device_->Stop();
if (capturing_)
audio_handler_->OnAudioStreamStopped(browser_);
audio_input_device_ = nullptr;
capturing_ = false;
}

View File

@@ -0,0 +1,53 @@
// Copyright (c) 2019 The Chromium Embedded Framework Authors.
// Portions copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CEF_LIBCEF_BROWSER_AUDIO_CAPTURER_H_
#define CEF_LIBCEF_BROWSER_AUDIO_CAPTURER_H_
#pragma once
#include "include/internal/cef_ptr.h"
#include "include/internal/cef_types_wrappers.h"
#include "media/base/audio_capturer_source.h"
namespace content {
class AudioLoopbackStreamCreator;
} // namespace content
namespace media {
class AudioInputDevice;
} // namespace media
class CefAudioHandler;
class CefBrowserHostImpl;
class CefAudioCapturer : public media::AudioCapturerSource::CaptureCallback {
public:
CefAudioCapturer(const CefAudioParameters& params,
CefRefPtr<CefBrowserHostImpl> browser,
CefRefPtr<CefAudioHandler> audio_handler);
~CefAudioCapturer() override;
private:
void OnCaptureStarted() override;
void Capture(const media::AudioBus* audio_source,
base::TimeTicks audio_capture_time,
double volume,
bool key_pressed) override;
void OnCaptureError(const std::string& message) override;
void OnCaptureMuted(bool is_muted) override {}
void StopStream();
CefAudioParameters params_;
CefRefPtr<CefBrowserHostImpl> browser_;
CefRefPtr<CefAudioHandler> audio_handler_;
std::unique_ptr<content::AudioLoopbackStreamCreator> audio_stream_creator_;
scoped_refptr<media::AudioInputDevice> audio_input_device_;
bool capturing_ = false;
int channels_ = 0;
};
#endif // CEF_LIBCEF_BROWSER_AUDIO_CAPTURER_H_

View File

@@ -8,7 +8,6 @@
#include <utility>
#include "libcef/browser/content_browser_client.h"
#include "libcef/browser/context.h"
#include "libcef/browser/download_manager_delegate.h"
#include "libcef/browser/extensions/extension_system.h"
#include "libcef/browser/media_router/media_router_manager.h"
@@ -292,37 +291,22 @@ CefBrowserContext::~CefBrowserContext() {
}
void CefBrowserContext::Initialize() {
CefContext* context = CefContext::Get();
cache_path_ = base::FilePath(CefString(&settings_.cache_path));
if (!context->ValidateCachePath(cache_path_)) {
// Reset to in-memory storage.
CefString(&settings_.cache_path).clear();
cache_path_ = base::FilePath();
}
if (!cache_path_.empty())
g_manager.Get().SetImplPath(this, cache_path_);
if (settings_.accept_language_list.length == 0) {
// Use the global language list setting.
CefString(&settings_.accept_language_list) =
CefString(&context->settings().accept_language_list);
}
if (!!settings_.persist_session_cookies) {
set_should_persist_session_cookies(true);
}
key_ = std::make_unique<ProfileKey>(GetPath());
key_ = std::make_unique<ProfileKey>(cache_path_);
SimpleKeyMap::GetInstance()->Associate(this, key_.get());
// Initialize the PrefService object.
pref_service_ = browser_prefs::CreatePrefService(
this, cache_path_, !!settings_.persist_user_preferences);
content::BrowserContext::Initialize(this, GetPath());
resource_context_.reset(new CefResourceContext(IsOffTheRecord()));
// This must be called before creating any services to avoid hitting
@@ -574,7 +558,7 @@ HostContentSettingsMap* CefBrowserContext::GetHostContentSettingsMap() {
// that can be stored in the settings map (for example, default values set
// via DefaultProvider::SetWebsiteSetting).
host_content_settings_map_ =
new HostContentSettingsMap(GetPrefs(), false, false, false);
new HostContentSettingsMap(GetPrefs(), false, false, false, false);
// Change the default plugin policy.
const base::CommandLine* command_line =

View File

@@ -296,7 +296,7 @@ class CefBrowserContext : public ChromeProfileStub,
~CefBrowserContext() override;
// Members initialized during construction are safe to access from any thread.
CefRequestContextSettings settings_;
const CefRequestContextSettings settings_;
base::FilePath cache_path_;
// CefRequestContextImpl objects referencing this object.

View File

@@ -8,6 +8,7 @@
#include <string>
#include <utility>
#include "libcef/browser/audio_capturer.h"
#include "libcef/browser/browser_context.h"
#include "libcef/browser/browser_info.h"
#include "libcef/browser/browser_info_manager.h"
@@ -15,8 +16,7 @@
#include "libcef/browser/browser_util.h"
#include "libcef/browser/content_browser_client.h"
#include "libcef/browser/context.h"
#include "libcef/browser/devtools/devtools_frontend.h"
#include "libcef/browser/devtools/devtools_manager_delegate.h"
#include "libcef/browser/devtools/devtools_manager.h"
#include "libcef/browser/extensions/browser_extensions_util.h"
#include "libcef/browser/extensions/extension_background_host.h"
#include "libcef/browser/extensions/extension_system.h"
@@ -70,10 +70,12 @@
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_widget_host.h"
#include "content/public/browser/render_widget_host_observer.h"
#include "content/public/browser/web_contents.h"
#include "extensions/browser/process_manager.h"
#include "net/base/net_errors.h"
#include "third_party/blink/public/mojom/frame/find_in_page.mojom.h"
#include "third_party/blink/public/mojom/page/widget.mojom-test-utils.h"
#include "ui/events/base_event_utils.h"
#if defined(OS_MACOSX)
@@ -194,6 +196,49 @@ void OnDownloadImage(uint32 max_image_size,
image_impl.get());
}
class CefWidgetHostInterceptor
: public blink::mojom::WidgetHostInterceptorForTesting,
public content::RenderWidgetHostObserver {
public:
CefWidgetHostInterceptor(CefBrowserHostImpl* browser,
content::RenderViewHost* render_view_host)
: browser_(browser),
render_widget_host_(
content::RenderWidgetHostImpl::From(render_view_host->GetWidget())),
impl_(render_widget_host_->widget_host_receiver_for_testing()
.SwapImplForTesting(this)) {
render_widget_host_->AddObserver(this);
}
blink::mojom::WidgetHost* GetForwardingInterface() override { return impl_; }
// WidgetHostInterceptorForTesting method:
void SetCursor(const ui::Cursor& cursor) override {
if (browser_->IsMouseCursorChangeDisabled()) {
// Don't change the cursor.
return;
}
GetForwardingInterface()->SetCursor(cursor);
}
// RenderWidgetHostObserver method:
void RenderWidgetHostDestroyed(
content::RenderWidgetHost* widget_host) override {
widget_host->RemoveObserver(this);
delete this;
}
private:
CefBrowserHostImpl* const browser_;
content::RenderWidgetHostImpl* const render_widget_host_;
blink::mojom::WidgetHost* const impl_;
DISALLOW_COPY_AND_ASSIGN(CefWidgetHostInterceptor);
};
static constexpr base::TimeDelta kRecentlyAudibleTimeout =
base::TimeDelta::FromSeconds(2);
} // namespace
// CefBrowserHost static methods.
@@ -548,26 +593,6 @@ CefRefPtr<CefBrowserHostImpl> CefBrowserHostImpl::GetBrowserForFrameRoute(
// CefBrowserHostImpl methods.
// -----------------------------------------------------------------------------
// WebContentsObserver that will be notified when the frontend WebContents is
// destroyed so that the inspected browser can clear its DevTools references.
class CefBrowserHostImpl::DevToolsWebContentsObserver
: public content::WebContentsObserver {
public:
DevToolsWebContentsObserver(CefBrowserHostImpl* browser,
content::WebContents* frontend_web_contents)
: WebContentsObserver(frontend_web_contents), browser_(browser) {}
// WebContentsObserver methods:
void WebContentsDestroyed() override {
browser_->OnDevToolsWebContentsDestroyed();
}
private:
CefBrowserHostImpl* browser_;
DISALLOW_COPY_AND_ASSIGN(DevToolsWebContentsObserver);
};
CefBrowserHostImpl::~CefBrowserHostImpl() {}
CefRefPtr<CefBrowser> CefBrowserHostImpl::GetBrowser() {
@@ -860,39 +885,29 @@ void CefBrowserHostImpl::ShowDevTools(const CefWindowInfo& windowInfo,
CefRefPtr<CefClient> client,
const CefBrowserSettings& settings,
const CefPoint& inspect_element_at) {
if (CEF_CURRENTLY_ON_UIT()) {
if (!web_contents())
return;
if (devtools_frontend_) {
if (!inspect_element_at.IsEmpty()) {
devtools_frontend_->InspectElementAt(inspect_element_at.x,
inspect_element_at.y);
}
devtools_frontend_->Focus();
return;
}
devtools_frontend_ = CefDevToolsFrontend::Show(
this, windowInfo, client, settings, inspect_element_at);
devtools_observer_.reset(new DevToolsWebContentsObserver(
this, devtools_frontend_->frontend_browser()->web_contents()));
} else {
if (!CEF_CURRENTLY_ON_UIT()) {
ShowDevToolsHelper* helper = new ShowDevToolsHelper(
this, windowInfo, client, settings, inspect_element_at);
CEF_POST_TASK(CEF_UIT, base::BindOnce(ShowDevToolsWithHelper, helper));
return;
}
if (!EnsureDevToolsManager())
return;
devtools_manager_->ShowDevTools(windowInfo, client, settings,
inspect_element_at);
}
void CefBrowserHostImpl::CloseDevTools() {
if (CEF_CURRENTLY_ON_UIT()) {
if (!devtools_frontend_)
return;
devtools_frontend_->Close();
} else {
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(CEF_UIT,
base::BindOnce(&CefBrowserHostImpl::CloseDevTools, this));
return;
}
if (!devtools_manager_)
return;
devtools_manager_->CloseDevTools();
}
bool CefBrowserHostImpl::HasDevTools() {
@@ -901,7 +916,84 @@ bool CefBrowserHostImpl::HasDevTools() {
return false;
}
return (devtools_frontend_ != nullptr);
if (!devtools_manager_)
return false;
return devtools_manager_->HasDevTools();
}
bool CefBrowserHostImpl::SendDevToolsMessage(const void* message,
size_t message_size) {
if (!message || message_size == 0)
return false;
if (!CEF_CURRENTLY_ON_UIT()) {
std::string message_str(static_cast<const char*>(message), message_size);
CEF_POST_TASK(
CEF_UIT,
base::BindOnce(
[](CefRefPtr<CefBrowserHostImpl> self, std::string message_str) {
self->SendDevToolsMessage(message_str.data(), message_str.size());
},
CefRefPtr<CefBrowserHostImpl>(this), std::move(message_str)));
return false;
}
if (!EnsureDevToolsManager())
return false;
return devtools_manager_->SendDevToolsMessage(message, message_size);
}
int CefBrowserHostImpl::ExecuteDevToolsMethod(
int message_id,
const CefString& method,
CefRefPtr<CefDictionaryValue> params) {
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(
CEF_UIT, base::BindOnce(base::IgnoreResult(
&CefBrowserHostImpl::ExecuteDevToolsMethod),
this, message_id, method, params));
return 0;
}
if (!EnsureDevToolsManager())
return 0;
return devtools_manager_->ExecuteDevToolsMethod(message_id, method, params);
}
CefRefPtr<CefRegistration> CefBrowserHostImpl::AddDevToolsMessageObserver(
CefRefPtr<CefDevToolsMessageObserver> observer) {
if (!observer)
return nullptr;
auto registration = CefDevToolsManager::CreateRegistration(observer);
InitializeDevToolsRegistrationOnUIThread(registration);
return registration.get();
}
bool CefBrowserHostImpl::EnsureDevToolsManager() {
CEF_REQUIRE_UIT();
if (!web_contents())
return false;
if (!devtools_manager_) {
devtools_manager_.reset(new CefDevToolsManager(this));
}
return true;
}
void CefBrowserHostImpl::InitializeDevToolsRegistrationOnUIThread(
CefRefPtr<CefRegistration> registration) {
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(
CEF_UIT,
base::BindOnce(
&CefBrowserHostImpl::InitializeDevToolsRegistrationOnUIThread, this,
registration));
return;
}
if (!EnsureDevToolsManager())
return;
devtools_manager_->InitializeRegistrationOnUIThread(registration);
}
void CefBrowserHostImpl::GetNavigationEntries(
@@ -1022,6 +1114,8 @@ bool CefBrowserHostImpl::IsBackgroundHost() {
void CefBrowserHostImpl::SetMouseCursorChangeDisabled(bool disabled) {
base::AutoLock lock_scope(state_lock_);
if (mouse_cursor_change_disabled_ == disabled)
return;
mouse_cursor_change_disabled_ = disabled;
}
@@ -1559,6 +1653,12 @@ void CefBrowserHostImpl::DestroyBrowser() {
javascript_dialog_manager_.reset(nullptr);
menu_manager_.reset(nullptr);
// Delete the audio capturer
recently_audible_timer_.Stop();
audio_capturer_.reset(nullptr);
devtools_manager_.reset(nullptr);
// Delete the platform delegate.
platform_delegate_.reset(nullptr);
@@ -2036,6 +2136,7 @@ bool CefBrowserHostImpl::ShouldTransferNavigation(
void CefBrowserHostImpl::AddNewContents(
content::WebContents* source,
std::unique_ptr<content::WebContents> new_contents,
const GURL& target_url,
WindowOpenDisposition disposition,
const gfx::Rect& initial_rect,
bool user_gesture,
@@ -2049,7 +2150,7 @@ void CefBrowserHostImpl::AddNewContents(
}
if (extension_host_) {
extension_host_->AddNewContents(source, std::move(new_contents),
extension_host_->AddNewContents(source, std::move(new_contents), target_url,
disposition, initial_rect, user_gesture,
was_blocked);
}
@@ -2281,8 +2382,10 @@ bool CefBrowserHostImpl::PreHandleGestureEvent(
bool CefBrowserHostImpl::CanDragEnter(content::WebContents* source,
const content::DropData& data,
blink::WebDragOperationsMask mask) {
CefRefPtr<CefDragHandler> handler = client_->GetDragHandler();
if (handler.get()) {
CefRefPtr<CefDragHandler> handler;
if (client_)
handler = client_->GetDragHandler();
if (handler) {
CefRefPtr<CefDragDataImpl> drag_data(new CefDragDataImpl(data));
drag_data->SetReadOnly(true);
if (handler->OnDragEnter(
@@ -2533,6 +2636,8 @@ void CefBrowserHostImpl::RenderViewCreated(
// RenderFrameCreated is otherwise not called for new popup browsers.
RenderFrameCreated(render_view_host->GetMainFrame());
new CefWidgetHostInterceptor(this, render_view_host);
platform_delegate_->RenderViewCreated(render_view_host);
}
@@ -2647,16 +2752,24 @@ void CefBrowserHostImpl::DidStopLoading() {
}
void CefBrowserHostImpl::DocumentAvailableInMainFrame() {
base::AutoLock lock_scope(state_lock_);
has_document_ = true;
{
base::AutoLock lock_scope(state_lock_);
has_document_ = true;
}
if (client_) {
CefRefPtr<CefRequestHandler> handler = client_->GetRequestHandler();
if (handler)
handler->OnDocumentAvailableInMainFrame(this);
}
}
void CefBrowserHostImpl::DidFailLoad(
content::RenderFrameHost* render_frame_host,
const GURL& validated_url,
int error_code) {
// The navigation failed after commit. OnLoadStart was called so we also call
// OnLoadEnd.
// The navigation failed after commit. OnLoadStart was called so we also
// call OnLoadEnd.
auto frame = browser_info_->GetFrameForHost(render_frame_host);
frame->RefreshAttributes();
OnLoadError(frame, validated_url, error_code);
@@ -2697,13 +2810,23 @@ void CefBrowserHostImpl::DidUpdateFaviconURL(
}
}
bool CefBrowserHostImpl::OnMessageReceived(const IPC::Message& message) {
// Handle the cursor message here if mouse cursor change is disabled instead
// of propegating the message to the normal handler.
if (message.type() == WidgetHostMsg_SetCursor::ID)
return IsMouseCursorChangeDisabled();
void CefBrowserHostImpl::OnAudioStateChanged(bool audible) {
if (audible) {
recently_audible_timer_.Stop();
StartAudioCapturer();
} else if (audio_capturer_) {
// If you have a media playing that has a short quiet moment, web_contents
// will immediately switch to non-audible state. We don't want to stop
// audio stream so quickly, let's give the stream some time to resume
// playing.
recently_audible_timer_.Start(
FROM_HERE, kRecentlyAudibleTimeout,
base::BindOnce(&CefBrowserHostImpl::OnRecentlyAudibleTimerFired, this));
}
}
return false;
void CefBrowserHostImpl::OnRecentlyAudibleTimerFired() {
audio_capturer_.reset();
}
bool CefBrowserHostImpl::OnMessageReceived(
@@ -2792,6 +2915,25 @@ bool CefBrowserHostImpl::HasObserver(Observer* observer) const {
return observers_.HasObserver(observer);
}
void CefBrowserHostImpl::StartAudioCapturer() {
if (!client_.get() || audio_capturer_)
return;
CefRefPtr<CefAudioHandler> audio_handler = client_->GetAudioHandler();
if (!audio_handler.get())
return;
CefAudioParameters params;
params.channel_layout = CEF_CHANNEL_LAYOUT_STEREO;
params.sample_rate = media::AudioParameters::kAudioCDSampleRate;
params.frames_per_buffer = 1024;
if (!audio_handler->GetAudioParameters(this, params))
return;
audio_capturer_.reset(new CefAudioCapturer(params, this, audio_handler));
}
CefBrowserHostImpl::NavigationLock::NavigationLock(
CefRefPtr<CefBrowserHostImpl> browser)
: browser_(browser) {
@@ -2863,18 +3005,6 @@ CefBrowserHostImpl::CefBrowserHostImpl(
platform_delegate_(std::move(platform_delegate)),
is_windowless_(platform_delegate_->IsWindowless()),
is_views_hosted_(platform_delegate_->IsViewsHosted()),
host_window_handle_(kNullWindowHandle),
is_loading_(false),
can_go_back_(false),
can_go_forward_(false),
has_document_(false),
is_fullscreen_(false),
destruction_state_(DESTRUCTION_STATE_NONE),
window_destroyed_(false),
is_in_onsetfocus_(false),
focus_on_editable_field_(false),
mouse_cursor_change_disabled_(false),
devtools_frontend_(nullptr),
extension_(extension) {
if (opener.get() && !platform_delegate_->IsViewsHosted()) {
// GetOpenerWindowHandle() only returns a value for non-views-hosted
@@ -3085,11 +3215,6 @@ void CefBrowserHostImpl::OnTitleChange(const base::string16& title) {
}
}
void CefBrowserHostImpl::OnDevToolsWebContentsDestroyed() {
devtools_observer_.reset();
devtools_frontend_ = nullptr;
}
void CefBrowserHostImpl::EnsureFileDialogManager() {
CEF_REQUIRE_UIT();
if (!file_dialog_manager_.get() && platform_delegate_) {

View File

@@ -48,9 +48,10 @@ class Widget;
}
#endif // defined(USE_AURA)
class CefAudioCapturer;
class CefBrowserInfo;
class CefBrowserPlatformDelegate;
class CefDevToolsFrontend;
class CefDevToolsManager;
class SiteInstance;
// Implementation of CefBrowser.
@@ -191,6 +192,12 @@ class CefBrowserHostImpl : public CefBrowserHost,
const CefPoint& inspect_element_at) override;
void CloseDevTools() override;
bool HasDevTools() override;
bool SendDevToolsMessage(const void* message, size_t message_size) override;
int ExecuteDevToolsMethod(int message_id,
const CefString& method,
CefRefPtr<CefDictionaryValue> params) override;
CefRefPtr<CefRegistration> AddDevToolsMessageObserver(
CefRefPtr<CefDevToolsMessageObserver> observer) override;
void GetNavigationEntries(CefRefPtr<CefNavigationEntryVisitor> visitor,
bool current_only) override;
void SetMouseCursorChangeDisabled(bool disabled) override;
@@ -378,6 +385,7 @@ class CefBrowserHostImpl : public CefBrowserHost,
bool ShouldTransferNavigation(bool is_main_frame_navigation) override;
void AddNewContents(content::WebContents* source,
std::unique_ptr<content::WebContents> new_contents,
const GURL& target_url,
WindowOpenDisposition disposition,
const gfx::Rect& initial_rect,
bool user_gesture,
@@ -486,7 +494,7 @@ class CefBrowserHostImpl : public CefBrowserHost,
base::ProcessId plugin_pid) override;
void DidUpdateFaviconURL(
const std::vector<blink::mojom::FaviconURLPtr>& candidates) override;
bool OnMessageReceived(const IPC::Message& message) override;
void OnAudioStateChanged(bool audible) override;
bool OnMessageReceived(const IPC::Message& message,
content::RenderFrameHost* render_frame_host) override;
void OnFrameFocused(content::RenderFrameHost* render_frame_host) override;
@@ -505,6 +513,7 @@ class CefBrowserHostImpl : public CefBrowserHost,
void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer);
bool HasObserver(Observer* observer) const;
class NavigationLock final {
private:
friend class CefBrowserHostImpl;
@@ -520,8 +529,6 @@ class CefBrowserHostImpl : public CefBrowserHost,
std::unique_ptr<NavigationLock> CreateNavigationLock();
private:
class DevToolsWebContentsObserver;
static CefRefPtr<CefBrowserHostImpl> CreateInternal(
const CefBrowserSettings& settings,
CefRefPtr<CefClient> client,
@@ -578,13 +585,18 @@ class CefBrowserHostImpl : public CefBrowserHost,
void OnFullscreenModeChange(bool fullscreen);
void OnTitleChange(const base::string16& title);
void OnDevToolsWebContentsDestroyed();
// Create the CefFileDialogManager if it doesn't already exist.
void EnsureFileDialogManager();
void ConfigureAutoResize();
void StartAudioCapturer();
void OnRecentlyAudibleTimerFired();
bool EnsureDevToolsManager();
void InitializeDevToolsRegistrationOnUIThread(
CefRefPtr<CefRegistration> registration);
CefBrowserSettings settings_;
CefRefPtr<CefClient> client_;
scoped_refptr<CefBrowserInfo> browser_info_;
@@ -593,7 +605,7 @@ class CefBrowserHostImpl : public CefBrowserHost,
std::unique_ptr<CefBrowserPlatformDelegate> platform_delegate_;
const bool is_windowless_;
const bool is_views_hosted_;
CefWindowHandle host_window_handle_;
CefWindowHandle host_window_handle_ = kNullWindowHandle;
// Non-nullptr if this object owns the WebContents. Will be nullptr for popup
// browsers between the calls to WebContentsCreated() and AddNewContents(),
@@ -603,18 +615,18 @@ class CefBrowserHostImpl : public CefBrowserHost,
// Volatile state information. All access must be protected by the state lock.
base::Lock state_lock_;
bool is_loading_;
bool can_go_back_;
bool can_go_forward_;
bool has_document_;
bool is_fullscreen_;
bool is_loading_ = false;
bool can_go_back_ = false;
bool can_go_forward_ = false;
bool has_document_ = false;
bool is_fullscreen_ = false;
// The currently focused frame, or nullptr if the main frame is focused.
CefRefPtr<CefFrameHostImpl> focused_frame_;
// Represents the current browser destruction state. Only accessed on the UI
// thread.
DestructionState destruction_state_;
DestructionState destruction_state_ = DESTRUCTION_STATE_NONE;
// Navigation will not occur while |navigation_lock_count_| > 0.
// |pending_navigation_action_| will be executed when the lock is released.
@@ -624,18 +636,18 @@ class CefBrowserHostImpl : public CefBrowserHost,
// True if the OS window hosting the browser has been destroyed. Only accessed
// on the UI thread.
bool window_destroyed_;
bool window_destroyed_ = false;
// True if currently in the OnSetFocus callback. Only accessed on the UI
// thread.
bool is_in_onsetfocus_;
bool is_in_onsetfocus_ = false;
// True if the focus is currently on an editable field on the page. Only
// accessed on the UI thread.
bool focus_on_editable_field_;
bool focus_on_editable_field_ = false;
// True if mouse cursor change is disabled.
bool mouse_cursor_change_disabled_;
bool mouse_cursor_change_disabled_ = false;
// Used for managing notification subscriptions.
std::unique_ptr<content::NotificationRegistrar> registrar_;
@@ -649,12 +661,8 @@ class CefBrowserHostImpl : public CefBrowserHost,
// Used for creating and managing context menus.
std::unique_ptr<CefMenuManager> menu_manager_;
// Track the lifespan of the frontend WebContents associated with this
// browser.
std::unique_ptr<DevToolsWebContentsObserver> devtools_observer_;
// CefDevToolsFrontend will delete itself when the frontend WebContents is
// destroyed.
CefDevToolsFrontend* devtools_frontend_;
// Used for creating and managing DevTools instances.
std::unique_ptr<CefDevToolsManager> devtools_manager_;
// Observers that want to be notified of changes to this object.
base::ObserverList<Observer>::Unchecked observers_;
@@ -667,6 +675,14 @@ class CefBrowserHostImpl : public CefBrowserHost,
CefRefPtr<CefExtension> extension_;
bool is_background_host_ = false;
// Used for capturing audio for CefAudioHandler.
std::unique_ptr<CefAudioCapturer> audio_capturer_;
// Timer for determining when "recently audible" transitions to false. This
// starts running when a tab stops being audible, and is canceled if it starts
// being audible again before it fires.
base::OneShotTimer recently_audible_timer_;
// Used with auto-resize.
bool auto_resize_enabled_ = false;
gfx::Size auto_resize_min_;

View File

@@ -22,6 +22,8 @@
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/child_process_host.h"
#include "content/public/common/url_constants.h"
#include "extensions/common/constants.h"
namespace {
@@ -115,26 +117,13 @@ bool CefBrowserInfoManager::CanCreateWindow(
bool* no_javascript_access) {
CEF_REQUIRE_UIT();
bool is_guest_view = false;
CefRefPtr<CefBrowserHostImpl> browser =
extensions::GetOwnerBrowserForHost(opener, &is_guest_view);
DCHECK(browser.get());
if (!browser.get()) {
// Cancel the popup.
return false;
}
if (is_guest_view) {
content::OpenURLParams params(target_url, referrer, disposition,
ui::PAGE_TRANSITION_LINK, true);
params.user_gesture = user_gesture;
// Pass navigation to the owner browser.
CEF_POST_TASK(
CEF_UIT,
base::Bind(base::IgnoreResult(&CefBrowserHostImpl::OpenURLFromTab),
browser.get(), nullptr, params));
content::OpenURLParams params(target_url, referrer, disposition,
ui::PAGE_TRANSITION_LINK,
/*is_renderer_initiated=*/true);
params.user_gesture = user_gesture;
CefRefPtr<CefBrowserHostImpl> browser;
if (!MaybeAllowNavigation(opener, params, browser) || !browser) {
// Cancel the popup.
return false;
}
@@ -369,6 +358,38 @@ CefBrowserInfoManager::GetBrowserInfoForFrameRoute(int render_process_id,
return GetBrowserInfo(render_process_id, render_routing_id, is_guest_view);
}
bool CefBrowserInfoManager::MaybeAllowNavigation(
content::RenderFrameHost* opener,
const content::OpenURLParams& params,
CefRefPtr<CefBrowserHostImpl>& browser_out) const {
CEF_REQUIRE_UIT();
bool is_guest_view = false;
CefRefPtr<CefBrowserHostImpl> browser =
extensions::GetOwnerBrowserForHost(opener, &is_guest_view);
if (!browser) {
// Print preview uses a modal dialog where we don't own the WebContents.
// Allow that navigation to proceed.
return true;
}
if (is_guest_view && !params.url.SchemeIs(extensions::kExtensionScheme) &&
!params.url.SchemeIs(content::kChromeUIScheme)) {
// The PDF viewer will load the PDF extension in the guest view, and print
// preview will load chrome://print in the guest view. All other navigations
// are passed to the owner browser.
CEF_POST_TASK(
CEF_UIT,
base::Bind(base::IgnoreResult(&CefBrowserHostImpl::OpenURLFromTab),
browser.get(), nullptr, params));
return false;
}
browser_out = browser;
return true;
}
scoped_refptr<CefBrowserInfo>
CefBrowserInfoManager::GetBrowserInfoForFrameTreeNode(int frame_tree_node_id,
bool* is_guest_view) {

View File

@@ -25,6 +25,7 @@ struct WebWindowFeatures;
}
namespace content {
struct OpenURLParams;
struct Referrer;
class RenderFrameHost;
class RenderViewHostDelegateView;
@@ -138,6 +139,13 @@ class CefBrowserInfoManager : public content::RenderProcessHostObserver {
typedef std::list<scoped_refptr<CefBrowserInfo>> BrowserInfoList;
BrowserInfoList GetBrowserInfoList();
// Returns true if the navigation should be allowed to proceed, or false if
// the navigation will instead be sent via OpenURLFromTab. If allowed,
// |browser| will be set to the target browser if any.
bool MaybeAllowNavigation(content::RenderFrameHost* opener,
const content::OpenURLParams& params,
CefRefPtr<CefBrowserHostImpl>& browser) const;
private:
// RenderProcessHostObserver methods:
void RenderProcessHostDestroyed(content::RenderProcessHost* host) override;

View File

@@ -191,7 +191,7 @@ void CefBrowserMainParts::PreMainMessageLoopRun() {
base::TaskShutdownBehavior::BLOCK_SHUTDOWN, base::MayBlock()});
CefRequestContextSettings settings;
CefContext::Get()->PopulateRequestContextSettings(&settings);
CefContext::Get()->PopulateGlobalRequestContextSettings(&settings);
// Create the global RequestContext.
global_request_context_ =

View File

@@ -71,19 +71,21 @@ class MessagePumpExternal : public base::MessagePumpForUI {
// is_immediate() returns true if the next task is ready right away.
more_immediate_work = next_work_info.is_immediate();
if (!more_immediate_work) {
// DoIdleWork() returns true if idle work was all done.
more_idle_work = !delegate->DoIdleWork();
// Check the next PendingTask's |delayed_run_time|.
// is_max() returns true if there are no more immediate nor delayed tasks.
more_delayed_work = !next_work_info.delayed_run_time.is_max();
if (more_delayed_work && !more_idle_work) {
if (more_delayed_work) {
// The only remaining work that we know about is the PendingTask.
// Consider the run time for that task in the time slice calculation.
*next_run_time = next_work_info.delayed_run_time;
}
}
if (!more_immediate_work && !more_delayed_work) {
// DoIdleWork() returns true if idle work was all done.
more_idle_work = !delegate->DoIdleWork();
}
return more_immediate_work || more_idle_work || more_delayed_work;
}

View File

@@ -11,16 +11,16 @@ namespace browser_util {
bool GetCefKeyEvent(const content::NativeWebKeyboardEvent& event,
CefKeyEvent& cef_event) {
switch (event.GetType()) {
case blink::WebKeyboardEvent::kRawKeyDown:
case blink::WebKeyboardEvent::Type::kRawKeyDown:
cef_event.type = KEYEVENT_RAWKEYDOWN;
break;
case blink::WebKeyboardEvent::kKeyDown:
case blink::WebKeyboardEvent::Type::kKeyDown:
cef_event.type = KEYEVENT_KEYDOWN;
break;
case blink::WebKeyboardEvent::kKeyUp:
case blink::WebKeyboardEvent::Type::kKeyUp:
cef_event.type = KEYEVENT_KEYUP;
break;
case blink::WebKeyboardEvent::kChar:
case blink::WebKeyboardEvent::Type::kChar:
cef_event.type = KEYEVENT_CHAR;
break;
default:

View File

@@ -157,15 +157,17 @@ ProfileManager* ChromeBrowserProcessStub::profile_manager() {
PrefService* ChromeBrowserProcessStub::local_state() {
DCHECK(initialized_);
if (!local_state_) {
// Use a location that is shared by all request contexts.
const CefSettings& settings = CefContext::Get()->settings();
const base::FilePath& cache_path =
base::FilePath(CefString(&settings.cache_path));
const base::FilePath& root_cache_path =
base::FilePath(CefString(&settings.root_cache_path));
// Used for very early NetworkService initialization.
// Always persist preferences for this PrefService if possible because it
// contains the cookie encryption key on Windows.
local_state_ = browser_prefs::CreatePrefService(
nullptr /* profile */, cache_path, true /* persist_user_preferences */);
local_state_ =
browser_prefs::CreatePrefService(nullptr /* profile */, root_cache_path,
true /* persist_user_preferences */);
}
return local_state_.get();
}
@@ -307,12 +309,6 @@ ChromeBrowserProcessStub::safe_browsing_service() {
return nullptr;
}
safe_browsing::ClientSideDetectionService*
ChromeBrowserProcessStub::safe_browsing_detection_service() {
NOTREACHED();
return nullptr;
}
subresource_filter::RulesetService*
ChromeBrowserProcessStub::subresource_filter_ruleset_service() {
NOTREACHED();

View File

@@ -78,8 +78,6 @@ class ChromeBrowserProcessStub : public BrowserProcess {
std::unique_ptr<BackgroundModeManager> manager) override;
StatusTray* status_tray() override;
safe_browsing::SafeBrowsingService* safe_browsing_service() override;
safe_browsing::ClientSideDetectionService* safe_browsing_detection_service()
override;
subresource_filter::RulesetService* subresource_filter_ruleset_service()
override;
optimization_guide::OptimizationGuideService* optimization_guide_service()

View File

@@ -46,6 +46,13 @@ bool ChromeProfileStub::IsOffTheRecord() const {
return false;
}
const Profile::OTRProfileID& ChromeProfileStub::GetOTRProfileID() const {
NOTREACHED();
static base::NoDestructor<Profile::OTRProfileID> otr_profile_id(
"ProfileImp::NoOTRProfileID");
return *otr_profile_id;
}
variations::VariationsClient* ChromeProfileStub::GetVariationsClient() {
if (!variations_client_)
variations_client_ = std::make_unique<CefVariationsClient>(this);
@@ -66,16 +73,27 @@ Profile::ProfileType ChromeProfileStub::GetProfileType() const {
return REGULAR_PROFILE;
}
Profile* ChromeProfileStub::GetOffTheRecordProfile() {
Profile* ChromeProfileStub::GetOffTheRecordProfile(
const Profile::OTRProfileID& otr_profile_id) {
NOTREACHED();
return nullptr;
}
void ChromeProfileStub::DestroyOffTheRecordProfile() {
std::vector<Profile*> ChromeProfileStub::GetAllOffTheRecordProfiles() {
NOTREACHED();
return {};
}
void ChromeProfileStub::DestroyOffTheRecordProfile(Profile* otr_profile) {
NOTREACHED();
}
bool ChromeProfileStub::HasOffTheRecordProfile() {
bool ChromeProfileStub::HasOffTheRecordProfile(
const Profile::OTRProfileID& otr_profile_id) {
return false;
}
bool ChromeProfileStub::HasAnyOffTheRecordProfile() {
return false;
}
@@ -140,10 +158,6 @@ bool ChromeProfileStub::WasCreatedByVersionOrLater(const std::string& version) {
return false;
}
bool ChromeProfileStub::IsIndependentOffTheRecordProfile() {
return false;
}
void ChromeProfileStub::SetExitType(ExitType exit_type) {
NOTREACHED();
}

View File

@@ -22,13 +22,18 @@ class ChromeProfileStub : public Profile {
// Profile methods.
bool IsOffTheRecord() override;
bool IsOffTheRecord() const override;
const OTRProfileID& GetOTRProfileID() const override;
variations::VariationsClient* GetVariationsClient() override;
scoped_refptr<base::SequencedTaskRunner> GetIOTaskRunner() override;
std::string GetProfileUserName() const override;
ProfileType GetProfileType() const override;
Profile* GetOffTheRecordProfile() override;
void DestroyOffTheRecordProfile() override;
bool HasOffTheRecordProfile() override;
Profile* GetOffTheRecordProfile(
const Profile::OTRProfileID& otr_profile_id) override;
std::vector<Profile*> GetAllOffTheRecordProfiles() override;
void DestroyOffTheRecordProfile(Profile* otr_profile) override;
bool HasOffTheRecordProfile(
const Profile::OTRProfileID& otr_profile_id) override;
bool HasAnyOffTheRecordProfile() override;
Profile* GetOriginalProfile() override;
const Profile* GetOriginalProfile() const override;
bool IsSupervised() const override;
@@ -42,7 +47,6 @@ class ChromeProfileStub : public Profile {
void set_last_selected_directory(const base::FilePath& path) override;
GURL GetHomePage() override;
bool WasCreatedByVersionOrLater(const std::string& version) override;
bool IsIndependentOffTheRecordProfile() override;
void SetExitType(ExitType exit_type) override;
ExitType GetLastSessionExitType() override;
base::Time GetCreationTime() const override;

View File

@@ -59,6 +59,7 @@
#include "chrome/browser/profiles/renderer_updater_factory.h"
#include "chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.h"
#include "chrome/browser/spellchecker/spell_check_host_chrome_impl.h"
#include "chrome/common/chrome_content_client.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/google_url_loader_throttle.h"
@@ -77,7 +78,6 @@
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_ppapi_host.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/child_process_security_policy.h"
#include "content/public/browser/client_certificate_delegate.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/overlay_window.h"
@@ -102,6 +102,7 @@
#include "extensions/browser/extensions_browser_client.h"
#include "extensions/browser/guest_view/extensions_guest_view_message_filter.h"
#include "extensions/browser/guest_view/web_view/web_view_guest.h"
#include "extensions/browser/url_loader_factory_manager.h"
#include "extensions/common/constants.h"
#include "extensions/common/switches.h"
#include "mojo/public/cpp/bindings/remote.h"
@@ -448,10 +449,20 @@ bool NavigationOnUIThread(
const navigation_interception::NavigationParams& params) {
CEF_REQUIRE_UIT();
content::OpenURLParams open_params(
params.url(), params.referrer(), WindowOpenDisposition::CURRENT_TAB,
params.transition_type(), params.is_renderer_initiated());
open_params.user_gesture = params.has_user_gesture();
CefRefPtr<CefBrowserHostImpl> browser;
if (!CefBrowserInfoManager::GetInstance()->MaybeAllowNavigation(
source->GetMainFrame(), open_params, browser)) {
// Cancel the navigation.
return true;
}
bool ignore_navigation = false;
CefRefPtr<CefBrowserHostImpl> browser =
CefBrowserHostImpl::GetBrowserForContents(source);
if (browser.get()) {
CefRefPtr<CefClient> client = browser->GetClient();
if (client.get()) {
@@ -520,7 +531,7 @@ base::FilePath GetRootCachePath() {
// blink.mojom.[Name] for the frame/document scope" errors.
// Based on chrome/browser/chrome_browser_interface_binders.cc.
void PopulateChromeFrameBinders(
service_manager::BinderMapWithContext<content::RenderFrameHost*>* map) {
mojo::BinderMapWithContext<content::RenderFrameHost*>* map) {
map->Add<blink::mojom::InsecureInputService>(base::BindRepeating(
[](content::RenderFrameHost* frame_host,
mojo::PendingReceiver<blink::mojom::InsecureInputService> receiver) {
@@ -626,6 +637,17 @@ bool CefContentBrowserClient::DoesSiteRequireDedicatedProcess(
return extension != nullptr;
}
void CefContentBrowserClient::OverrideURLLoaderFactoryParams(
content::BrowserContext* browser_context,
const url::Origin& origin,
bool is_for_isolated_world,
network::mojom::URLLoaderFactoryParams* factory_params) {
if (extensions::ExtensionsEnabled()) {
extensions::URLLoaderFactoryManager::OverrideURLLoaderFactoryParams(
browser_context, origin, is_for_isolated_world, factory_params);
}
}
void CefContentBrowserClient::GetAdditionalWebUISchemes(
std::vector<std::string>* additional_schemes) {
// Any schemes listed here are treated as WebUI schemes but do not get WebUI
@@ -1301,18 +1323,28 @@ void CefContentBrowserClient::OnNetworkServiceCreated(
network_service);
}
mojo::Remote<network::mojom::NetworkContext>
CefContentBrowserClient::CreateNetworkContext(
void CefContentBrowserClient::ConfigureNetworkContextParams(
content::BrowserContext* context,
bool in_memory,
const base::FilePath& relative_partition_path) {
const base::FilePath& relative_partition_path,
network::mojom::NetworkContextParams* network_context_params,
network::mojom::CertVerifierCreationParams* cert_verifier_creation_params) {
// This method may be called during shutdown when using multi-threaded
// message loop mode. In that case exit early to avoid crashes.
if (!SystemNetworkContextManager::GetInstance())
return mojo::Remote<network::mojom::NetworkContext>();
if (!SystemNetworkContextManager::GetInstance()) {
// This must match the value expected in
// StoragePartitionImpl::InitNetworkContext.
network_context_params->context_name = "magic_shutting_down";
return;
}
Profile* profile = Profile::FromBrowserContext(context);
return profile->CreateNetworkContext(in_memory, relative_partition_path);
profile->ConfigureNetworkContextParams(in_memory, relative_partition_path,
network_context_params,
cert_verifier_creation_params);
// TODO(cef): Remove this and add required NetworkIsolationKeys,
// this is currently not the case and this was not required pre M84.
network_context_params->require_network_isolation_key = false;
}
// The sandbox may block read/write access from the NetworkService to
@@ -1399,7 +1431,7 @@ CefContentBrowserClient::CreateWindowForPictureInPicture(
void CefContentBrowserClient::RegisterBrowserInterfaceBindersForFrame(
content::RenderFrameHost* render_frame_host,
service_manager::BinderMapWithContext<content::RenderFrameHost*>* map) {
mojo::BinderMapWithContext<content::RenderFrameHost*>* map) {
PopulateChromeFrameBinders(map);
if (!extensions::ExtensionsEnabled())
@@ -1448,7 +1480,8 @@ std::string CefContentBrowserClient::GetUserAgent() {
blink::UserAgentMetadata CefContentBrowserClient::GetUserAgentMetadata() {
blink::UserAgentMetadata metadata;
metadata.brand = version_info::GetProductName();
metadata.brand_version_list = {blink::UserAgentBrandVersion{
version_info::GetProductName(), version_info::GetMajorVersionNumber()}};
metadata.full_version = version_info::GetVersionNumber();
metadata.platform = version_info::GetOSType();
@@ -1469,14 +1502,29 @@ CefContentBrowserClient::GetPluginMimeTypesWithExternalHandlers(
return mime_types;
}
void CefContentBrowserClient::RegisterCustomScheme(const std::string& scheme) {
// Register as a Web-safe scheme so that requests for the scheme from a
// render process will be allowed in resource_dispatcher_host_impl.cc
// ShouldServiceRequest.
content::ChildProcessSecurityPolicy* policy =
content::ChildProcessSecurityPolicy::GetInstance();
if (!policy->IsWebSafeScheme(scheme))
policy->RegisterWebSafeScheme(scheme);
bool CefContentBrowserClient::ShouldAllowPluginCreation(
const url::Origin& embedder_origin,
const content::PepperPluginInfo& plugin_info) {
if (plugin_info.name == ChromeContentClient::kPDFInternalPluginName) {
// Allow embedding the internal PDF plugin in the built-in PDF extension.
if (embedder_origin.scheme() == extensions::kExtensionScheme &&
embedder_origin.host() == extension_misc::kPdfExtensionId) {
return true;
}
// Allow embedding the internal PDF plugin in chrome://print.
if (embedder_origin ==
url::Origin::Create(GURL(chrome::kChromeUIPrintURL))) {
return true;
}
// Only allow the PDF plugin in the known, trustworthy origins that are
// allowlisted above. See also https://crbug.com/520422 and
// https://crbug.com/1027173.
return false;
}
return true;
}
CefRefPtr<CefRequestContextImpl> CefContentBrowserClient::request_context()

View File

@@ -46,6 +46,11 @@ class CefContentBrowserClient : public content::ContentBrowserClient {
const GURL& effective_url) override;
bool DoesSiteRequireDedicatedProcess(content::BrowserContext* browser_context,
const GURL& effective_site_url) override;
void OverrideURLLoaderFactoryParams(
content::BrowserContext* browser_context,
const url::Origin& origin,
bool is_for_isolated_world,
network::mojom::URLLoaderFactoryParams* factory_params) override;
void GetAdditionalWebUISchemes(
std::vector<std::string>* additional_schemes) override;
void GetAdditionalViewSourceSchemes(
@@ -168,10 +173,13 @@ class CefContentBrowserClient : public content::ContentBrowserClient {
network::mojom::URLLoaderFactoryOverridePtr* factory_override) override;
void OnNetworkServiceCreated(
network::mojom::NetworkService* network_service) override;
mojo::Remote<network::mojom::NetworkContext> CreateNetworkContext(
void ConfigureNetworkContextParams(
content::BrowserContext* context,
bool in_memory,
const base::FilePath& relative_partition_path) override;
const base::FilePath& relative_partition_path,
network::mojom::NetworkContextParams* network_context_params,
network::mojom::CertVerifierCreationParams* cert_verifier_creation_params)
override;
std::vector<base::FilePath> GetNetworkContextsParentDirectory() override;
bool HandleExternalProtocol(
const GURL& url,
@@ -195,8 +203,7 @@ class CefContentBrowserClient : public content::ContentBrowserClient {
content::PictureInPictureWindowController* controller) override;
void RegisterBrowserInterfaceBindersForFrame(
content::RenderFrameHost* render_frame_host,
service_manager::BinderMapWithContext<content::RenderFrameHost*>* map)
override;
mojo::BinderMapWithContext<content::RenderFrameHost*>* map) override;
base::FilePath GetSandboxedStorageServiceDataDirectory() override;
std::string GetProduct() override;
std::string GetChromeProduct() override;
@@ -204,9 +211,9 @@ class CefContentBrowserClient : public content::ContentBrowserClient {
blink::UserAgentMetadata GetUserAgentMetadata() override;
base::flat_set<std::string> GetPluginMimeTypesWithExternalHandlers(
content::BrowserContext* browser_context) override;
// Perform browser process registration for the custom scheme.
void RegisterCustomScheme(const std::string& scheme);
bool ShouldAllowPluginCreation(
const url::Origin& embedder_origin,
const content::PepperPluginInfo& plugin_info) override;
CefRefPtr<CefRequestContextImpl> request_context() const;
CefDevToolsDelegate* devtools_delegate() const;

View File

@@ -160,6 +160,85 @@ bool GetColor(const cef_color_t cef_in, bool is_windowless, SkColor* sk_out) {
return true;
}
// Convert |path_str| to a normalized FilePath.
base::FilePath NormalizePath(const cef_string_t& path_str,
const char* name,
bool* has_error = nullptr) {
if (has_error)
*has_error = false;
base::FilePath path = base::FilePath(CefString(&path_str));
if (path.EndsWithSeparator()) {
// Remove the trailing separator because it will interfere with future
// equality checks.
path = path.StripTrailingSeparators();
}
if (!path.empty() && !path.IsAbsolute()) {
LOG(ERROR) << "The " << name << " directory (" << path.value()
<< ") is not an absolute path. Defaulting to empty.";
if (has_error)
*has_error = true;
path = base::FilePath();
}
return path;
}
void SetPath(cef_string_t& path_str, const base::FilePath& path) {
#if defined(OS_WIN)
CefString(&path_str).FromWString(path.value());
#else
CefString(&path_str).FromString(path.value());
#endif
}
// Convert |path_str| to a normalized FilePath and update the |path_str| value.
base::FilePath NormalizePathAndSet(cef_string_t& path_str, const char* name) {
const base::FilePath& path = NormalizePath(path_str, name);
SetPath(path_str, path);
return path;
}
// Verify that |cache_path| is valid and create it if necessary.
bool ValidateCachePath(const base::FilePath& cache_path,
const base::FilePath& root_cache_path) {
if (cache_path.empty())
return true;
if (!root_cache_path.empty() && root_cache_path != cache_path &&
!root_cache_path.IsParent(cache_path)) {
LOG(ERROR) << "The cache_path directory (" << cache_path.value()
<< ") is not a child of the root_cache_path directory ("
<< root_cache_path.value() << ")";
return false;
}
base::ThreadRestrictions::ScopedAllowIO allow_io;
if (!base::DirectoryExists(cache_path) &&
!base::CreateDirectory(cache_path)) {
LOG(ERROR) << "The cache_path directory (" << cache_path.value()
<< ") could not be created.";
return false;
}
return true;
}
// Like NormalizePathAndSet but with additional checks specific to the
// cache_path value.
base::FilePath NormalizeCachePathAndSet(cef_string_t& path_str,
const base::FilePath& root_cache_path) {
bool has_error = false;
base::FilePath path = NormalizePath(path_str, "cache_path", &has_error);
if (has_error || !ValidateCachePath(path, root_cache_path)) {
LOG(ERROR) << "The cache_path is invalid. Defaulting to in-memory storage.";
path = base::FilePath();
}
SetPath(path_str, path);
return path;
}
} // namespace
int CefExecuteProcess(const CefMainArgs& args,
@@ -370,18 +449,23 @@ bool CefContext::Initialize(const CefMainArgs& args,
SignalChromeElf();
#endif
base::FilePath cache_path = base::FilePath(CefString(&settings_.cache_path));
if (!ValidateCachePath(cache_path)) {
// Reset to in-memory storage.
CefString(&settings_.cache_path).clear();
cache_path = base::FilePath();
}
const base::FilePath& root_cache_path =
base::FilePath(CefString(&settings_.root_cache_path));
NormalizePathAndSet(settings_.root_cache_path, "root_cache_path");
const base::FilePath& cache_path =
NormalizeCachePathAndSet(settings_.cache_path, root_cache_path);
if (root_cache_path.empty() && !cache_path.empty()) {
CefString(&settings_.root_cache_path) = CefString(&settings_.cache_path);
CefString(&settings_.root_cache_path) = cache_path.value();
}
// All other paths that need to be normalized.
NormalizePathAndSet(settings_.browser_subprocess_path,
"browser_subprocess_path");
NormalizePathAndSet(settings_.framework_dir_path, "framework_dir_path");
NormalizePathAndSet(settings_.main_bundle_path, "main_bundle_path");
NormalizePathAndSet(settings_.user_data_path, "user_data_path");
NormalizePathAndSet(settings_.resources_dir_path, "resources_dir_path");
NormalizePathAndSet(settings_.locales_dir_path, "locales_dir_path");
main_delegate_.reset(new CefMainDelegate(application));
browser_info_manager_.reset(new CefBrowserInfoManager);
@@ -518,11 +602,14 @@ CefTraceSubscriber* CefContext::GetTraceSubscriber() {
return trace_subscriber_.get();
}
void CefContext::PopulateRequestContextSettings(
void CefContext::PopulateGlobalRequestContextSettings(
CefRequestContextSettings* settings) {
CefRefPtr<CefCommandLine> command_line =
CefCommandLine::GetGlobalCommandLine();
// This value was already normalized in Initialize.
CefString(&settings->cache_path) = CefString(&settings_.cache_path);
settings->persist_session_cookies =
settings_.persist_session_cookies ||
command_line->HasSwitch(switches::kPersistSessionCookies);
@@ -536,29 +623,17 @@ void CefContext::PopulateRequestContextSettings(
CefString(&settings_.accept_language_list);
}
bool CefContext::ValidateCachePath(const base::FilePath& cache_path) {
if (cache_path.empty())
return true;
void CefContext::NormalizeRequestContextSettings(
CefRequestContextSettings* settings) {
// 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);
const base::FilePath& root_cache_path =
base::FilePath(CefString(&settings_.root_cache_path));
if (!root_cache_path.empty() && root_cache_path != cache_path &&
!root_cache_path.IsParent(cache_path)) {
LOG(ERROR) << "The cache_path directory (" << cache_path.value()
<< ") is not a child of the root_cache_path directory ("
<< root_cache_path.value() << ")";
return false;
if (settings->accept_language_list.length == 0) {
// Use the global language list setting.
CefString(&settings->accept_language_list) =
CefString(&settings_.accept_language_list);
}
base::ThreadRestrictions::ScopedAllowIO allow_io;
if (!base::DirectoryExists(cache_path) &&
!base::CreateDirectory(cache_path)) {
LOG(ERROR) << "The cache_path directory (" << cache_path.value()
<< ") could not be created.";
return false;
}
return true;
}
void CefContext::AddObserver(Observer* observer) {

View File

@@ -87,10 +87,11 @@ class CefContext {
// Populate request context settings for the global system context based on
// CefSettings and command-line flags.
void PopulateRequestContextSettings(CefRequestContextSettings* settings);
void PopulateGlobalRequestContextSettings(
CefRequestContextSettings* settings);
// Verify that |cache_path| is valid and create it if necessary.
bool ValidateCachePath(const base::FilePath& cache_path);
// Normalize and validate request context settings for user-created contexts.
void NormalizeRequestContextSettings(CefRequestContextSettings* settings);
// Manage observer objects. The observer must either outlive this object or
// remove itself before destruction. These methods can only be called on the

View File

@@ -0,0 +1,137 @@
// Copyright (c) 2020 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
#include "libcef/browser/devtools/devtools_controller.h"
#include "libcef/browser/devtools/devtools_util.h"
#include "libcef/browser/thread_util.h"
#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
#include "content/public/browser/devtools_agent_host.h"
CefDevToolsController::CefDevToolsController(
content::WebContents* inspected_contents)
: inspected_contents_(inspected_contents), weak_ptr_factory_(this) {
DCHECK(inspected_contents_);
}
CefDevToolsController::~CefDevToolsController() {
if (agent_host_) {
agent_host_->DetachClient(this);
AgentHostClosed(agent_host_.get());
}
for (auto& observer : observers_) {
observer.OnDevToolsControllerDestroyed();
}
}
bool CefDevToolsController::SendDevToolsMessage(
const base::StringPiece& message) {
CEF_REQUIRE_UIT();
if (!EnsureAgentHost())
return false;
agent_host_->DispatchProtocolMessage(
this, base::as_bytes(base::make_span(message)));
return true;
}
int CefDevToolsController::ExecuteDevToolsMethod(
int suggested_message_id,
const std::string& method,
const base::DictionaryValue* params) {
CEF_REQUIRE_UIT();
if (!EnsureAgentHost())
return 0;
// Message IDs must always be increasing and unique.
int message_id = suggested_message_id;
if (message_id < next_message_id_)
message_id = next_message_id_++;
else
next_message_id_ = message_id + 1;
base::DictionaryValue message;
message.SetIntKey("id", message_id);
message.SetStringKey("method", method);
if (params)
message.SetKey("params", params->Clone());
std::string protocol_message;
if (!base::JSONWriter::Write(message, &protocol_message))
return 0;
agent_host_->DispatchProtocolMessage(
this, base::as_bytes(base::make_span(protocol_message)));
return message_id;
}
void CefDevToolsController::AgentHostClosed(
content::DevToolsAgentHost* agent_host) {
DCHECK(agent_host == agent_host_.get());
agent_host_ = nullptr;
for (auto& observer : observers_) {
observer.OnDevToolsAgentDetached();
}
}
void CefDevToolsController::AddObserver(Observer* observer) {
CEF_REQUIRE_UIT();
observers_.AddObserver(observer);
}
void CefDevToolsController::RemoveObserver(Observer* observer) {
CEF_REQUIRE_UIT();
observers_.RemoveObserver(observer);
}
void CefDevToolsController::DispatchProtocolMessage(
content::DevToolsAgentHost* agent_host,
base::span<const uint8_t> message) {
if (!observers_.might_have_observers())
return;
base::StringPiece str_message(reinterpret_cast<const char*>(message.data()),
message.size());
if (!devtools_util::ProtocolParser::IsValidMessage(str_message)) {
LOG(WARNING) << "Invalid message: " << str_message.substr(0, 100);
return;
}
devtools_util::ProtocolParser parser;
for (auto& observer : observers_) {
if (observer.OnDevToolsMessage(str_message)) {
continue;
}
// Only perform parsing a single time.
if (parser.Initialize(str_message) && parser.IsFailure()) {
LOG(WARNING) << "Failed to parse message: " << str_message.substr(0, 100);
}
if (parser.IsEvent()) {
observer.OnDevToolsEvent(parser.method_, parser.params_);
} else if (parser.IsResult()) {
observer.OnDevToolsMethodResult(parser.message_id_, parser.success_,
parser.params_);
}
}
}
bool CefDevToolsController::EnsureAgentHost() {
if (!agent_host_) {
agent_host_ =
content::DevToolsAgentHost::GetOrCreateFor(inspected_contents_);
if (agent_host_) {
agent_host_->AttachClient(this);
for (auto& observer : observers_) {
observer.OnDevToolsAgentAttached();
}
}
}
return !!agent_host_;
}

View File

@@ -0,0 +1,79 @@
// Copyright (c) 2020 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
#ifndef CEF_LIBCEF_BROWSER_DEVTOOLS_DEVTOOLS_CONTROLLER_H_
#define CEF_LIBCEF_BROWSER_DEVTOOLS_DEVTOOLS_CONTROLLER_H_
#include <memory>
#include "content/public/browser/devtools_agent_host_client.h"
#include "base/containers/span.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/values.h"
namespace content {
class WebContents;
}
class CefDevToolsController : public content::DevToolsAgentHostClient {
public:
class Observer : public base::CheckedObserver {
public:
// See CefDevToolsMessageObserver documentation.
virtual bool OnDevToolsMessage(const base::StringPiece& message) = 0;
virtual void OnDevToolsMethodResult(int message_id,
bool success,
const base::StringPiece& result) = 0;
virtual void OnDevToolsEvent(const base::StringPiece& method,
const base::StringPiece& params) = 0;
virtual void OnDevToolsAgentAttached() = 0;
virtual void OnDevToolsAgentDetached() = 0;
virtual void OnDevToolsControllerDestroyed() = 0;
protected:
~Observer() override {}
};
// |inspected_contents| will outlive this object.
explicit CefDevToolsController(content::WebContents* inspected_contents);
~CefDevToolsController() override;
// See CefBrowserHost methods of the same name for documentation.
bool SendDevToolsMessage(const base::StringPiece& message);
int ExecuteDevToolsMethod(int message_id,
const std::string& method,
const base::DictionaryValue* params);
// |observer| must outlive this object or be removed.
void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer);
base::WeakPtr<CefDevToolsController> GetWeakPtr() {
return weak_ptr_factory_.GetWeakPtr();
}
private:
// content::DevToolsAgentHostClient implementation:
void AgentHostClosed(content::DevToolsAgentHost* agent_host) override;
void DispatchProtocolMessage(content::DevToolsAgentHost* agent_host,
base::span<const uint8_t> message) override;
bool EnsureAgentHost();
content::WebContents* const inspected_contents_;
scoped_refptr<content::DevToolsAgentHost> agent_host_;
int next_message_id_ = 1;
base::ObserverList<Observer> observers_;
base::WeakPtrFactory<CefDevToolsController> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(CefDevToolsController);
};
#endif // CEF_LIBCEF_BROWSER_DEVTOOLS_DEVTOOLS_CONTROLLER_H_

View File

@@ -6,13 +6,18 @@
#include <stddef.h>
#include <iomanip>
#include <utility>
#include "libcef/browser/browser_context.h"
#include "libcef/browser/content_browser_client.h"
#include "libcef/browser/devtools/devtools_manager_delegate.h"
#include "libcef/browser/net/devtools_scheme_handler.h"
#include "libcef/common/cef_switches.h"
#include "base/base64.h"
#include "base/command_line.h"
#include "base/files/file_util.h"
#include "base/guid.h"
#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
@@ -48,6 +53,13 @@
#include "services/network/public/cpp/simple_url_loader.h"
#include "services/network/public/cpp/simple_url_loader_stream_consumer.h"
#include "services/network/public/mojom/url_response_head.mojom.h"
#include "storage/browser/file_system/native_file_util.h"
#if defined(OS_WIN)
#include <windows.h>
#elif defined(OS_POSIX)
#include <time.h>
#endif
namespace {
@@ -86,6 +98,71 @@ std::unique_ptr<base::DictionaryValue> BuildObjectForResponse(
return response;
}
const int kMaxLogLineLength = 1024;
void WriteTimestamp(std::stringstream& stream) {
#if defined(OS_WIN)
SYSTEMTIME local_time;
GetLocalTime(&local_time);
stream << std::setfill('0') << std::setw(2) << local_time.wMonth
<< std::setw(2) << local_time.wDay << '/' << std::setw(2)
<< local_time.wHour << std::setw(2) << local_time.wMinute
<< std::setw(2) << local_time.wSecond << '.' << std::setw(3)
<< local_time.wMilliseconds;
#elif defined(OS_POSIX)
timeval tv;
gettimeofday(&tv, nullptr);
time_t t = tv.tv_sec;
struct tm local_time;
localtime_r(&t, &local_time);
struct tm* tm_time = &local_time;
stream << std::setfill('0') << std::setw(2) << 1 + tm_time->tm_mon
<< std::setw(2) << tm_time->tm_mday << '/' << std::setw(2)
<< tm_time->tm_hour << std::setw(2) << tm_time->tm_min << std::setw(2)
<< tm_time->tm_sec << '.' << std::setw(6) << tv.tv_usec;
#else
#error Unsupported platform
#endif
}
void LogProtocolMessage(const base::FilePath& log_file,
ProtocolMessageType type,
std::string to_log) {
// Track if logging has failed, in which case we don't keep trying.
static bool log_error = false;
if (log_error)
return;
if (storage::NativeFileUtil::EnsureFileExists(log_file, nullptr) !=
base::File::FILE_OK) {
LOG(ERROR) << "Failed to create file " << log_file.value();
log_error = true;
return;
}
std::string type_label;
switch (type) {
case ProtocolMessageType::METHOD:
type_label = "METHOD";
break;
case ProtocolMessageType::RESULT:
type_label = "RESULT";
break;
case ProtocolMessageType::EVENT:
type_label = "EVENT";
break;
}
std::stringstream stream;
WriteTimestamp(stream);
stream << ": " << type_label << ": " << to_log << "\n";
const std::string& str = stream.str();
if (!base::AppendToFile(log_file, str.c_str(), str.size())) {
LOG(ERROR) << "Failed to write file " << log_file.value();
log_error = true;
}
}
} // namespace
class CefDevToolsFrontend::NetworkResourceLoader
@@ -156,11 +233,12 @@ const size_t kMaxMessageChunkSize = IPC::Channel::kMaximumMessageSize / 4;
// static
CefDevToolsFrontend* CefDevToolsFrontend::Show(
CefRefPtr<CefBrowserHostImpl> inspected_browser,
CefBrowserHostImpl* inspected_browser,
const CefWindowInfo& windowInfo,
CefRefPtr<CefClient> client,
const CefBrowserSettings& settings,
const CefPoint& inspect_element_at) {
const CefPoint& inspect_element_at,
base::OnceClosure frontend_destroyed_callback) {
CefBrowserSettings new_settings = settings;
if (!windowInfo.windowless_rendering_enabled &&
CefColorGetA(new_settings.background_color) != SK_AlphaOPAQUE) {
@@ -187,7 +265,8 @@ CefDevToolsFrontend* CefDevToolsFrontend::Show(
// destroyed.
CefDevToolsFrontend* devtools_frontend = new CefDevToolsFrontend(
static_cast<CefBrowserHostImpl*>(frontend_browser.get()),
inspected_contents, inspect_element_at);
inspected_contents, inspect_element_at,
std::move(frontend_destroyed_callback));
// Need to load the URL after creating the DevTools objects.
frontend_browser->GetMainFrame()->LoadURL(GetFrontendURL());
@@ -216,23 +295,23 @@ void CefDevToolsFrontend::Close() {
frontend_browser_.get(), true));
}
void CefDevToolsFrontend::DisconnectFromTarget() {
if (!agent_host_)
return;
agent_host_->DetachClient(this);
agent_host_ = nullptr;
}
CefDevToolsFrontend::CefDevToolsFrontend(
CefRefPtr<CefBrowserHostImpl> frontend_browser,
CefBrowserHostImpl* frontend_browser,
content::WebContents* inspected_contents,
const CefPoint& inspect_element_at)
const CefPoint& inspect_element_at,
base::OnceClosure frontend_destroyed_callback)
: content::WebContentsObserver(frontend_browser->web_contents()),
frontend_browser_(frontend_browser),
inspected_contents_(inspected_contents),
inspect_element_at_(inspect_element_at),
file_manager_(frontend_browser.get(), GetPrefs()),
weak_factory_(this) {}
frontend_destroyed_callback_(std::move(frontend_destroyed_callback)),
file_manager_(frontend_browser, GetPrefs()),
protocol_log_file_(
base::CommandLine::ForCurrentProcess()->GetSwitchValuePath(
switches::kDevToolsProtocolLogFile)),
weak_factory_(this) {
DCHECK(!frontend_destroyed_callback_.is_null());
}
CefDevToolsFrontend::~CefDevToolsFrontend() {}
@@ -279,6 +358,7 @@ void CefDevToolsFrontend::WebContentsDestroyed() {
agent_host_->DetachClient(this);
agent_host_ = nullptr;
}
std::move(frontend_destroyed_callback_).Run();
delete this;
}
@@ -300,6 +380,9 @@ void CefDevToolsFrontend::HandleMessageFromDevToolsFrontend(
std::string protocol_message;
if (!agent_host_ || !params->GetString(0, &protocol_message))
return;
if (ProtocolLoggingEnabled()) {
LogProtocolMessage(ProtocolMessageType::METHOD, protocol_message);
}
agent_host_->DispatchProtocolMessage(
this, base::as_bytes(base::make_span(protocol_message)));
} else if (method == "loadCompleted") {
@@ -451,6 +534,14 @@ void CefDevToolsFrontend::DispatchProtocolMessage(
base::span<const uint8_t> message) {
base::StringPiece str_message(reinterpret_cast<const char*>(message.data()),
message.size());
if (ProtocolLoggingEnabled()) {
// Quick check to avoid parsing the JSON object. Events begin with a
// "method" value whereas method results begin with an "id" value.
LogProtocolMessage(str_message.starts_with("{\"method\":")
? ProtocolMessageType::EVENT
: ProtocolMessageType::RESULT,
str_message);
}
if (str_message.length() < kMaxMessageChunkSize) {
std::string param;
base::EscapeJSONString(str_message, true, &param);
@@ -504,6 +595,23 @@ void CefDevToolsFrontend::SendMessageAck(int request_id,
CallClientFunction("DevToolsAPI.embedderMessageAck", &id_value, arg, nullptr);
}
bool CefDevToolsFrontend::ProtocolLoggingEnabled() const {
return !protocol_log_file_.empty();
}
void CefDevToolsFrontend::LogProtocolMessage(ProtocolMessageType type,
const base::StringPiece& message) {
DCHECK(ProtocolLoggingEnabled());
std::string to_log = message.substr(0, kMaxLogLineLength).as_string();
// Execute in an ordered context that allows blocking.
auto task_runner = CefContentBrowserClient::Get()->background_task_runner();
task_runner->PostTask(
FROM_HERE, base::BindOnce(::LogProtocolMessage, protocol_log_file_, type,
std::move(to_log)));
}
void CefDevToolsFrontend::AgentHostClosed(
content::DevToolsAgentHost* agent_host) {
DCHECK(agent_host == agent_host_.get());

View File

@@ -11,6 +11,7 @@
#include "libcef/browser/devtools/devtools_file_manager.h"
#include "base/compiler_specific.h"
#include "base/files/file_path.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
@@ -31,36 +32,38 @@ class WebContents;
class PrefService;
enum class ProtocolMessageType {
METHOD,
RESULT,
EVENT,
};
class CefDevToolsFrontend : public content::WebContentsObserver,
public content::DevToolsAgentHostClient {
public:
static CefDevToolsFrontend* Show(
CefRefPtr<CefBrowserHostImpl> inspected_browser,
CefBrowserHostImpl* inspected_browser,
const CefWindowInfo& windowInfo,
CefRefPtr<CefClient> client,
const CefBrowserSettings& settings,
const CefPoint& inspect_element_at);
const CefPoint& inspect_element_at,
base::OnceClosure frontend_destroyed_callback);
void Activate();
void Focus();
void InspectElementAt(int x, int y);
void Close();
void DisconnectFromTarget();
void CallClientFunction(const std::string& function_name,
const base::Value* arg1,
const base::Value* arg2,
const base::Value* arg3);
CefRefPtr<CefBrowserHostImpl> frontend_browser() const {
return frontend_browser_;
}
private:
CefDevToolsFrontend(CefRefPtr<CefBrowserHostImpl> frontend_browser,
CefDevToolsFrontend(CefBrowserHostImpl* frontend_browser,
content::WebContents* inspected_contents,
const CefPoint& inspect_element_at);
const CefPoint& inspect_element_at,
base::OnceClosure destroyed_callback);
~CefDevToolsFrontend() override;
// content::DevToolsAgentHostClient implementation.
@@ -78,12 +81,17 @@ class CefDevToolsFrontend : public content::WebContentsObserver,
void SendMessageAck(int request_id, const base::Value* arg1);
bool ProtocolLoggingEnabled() const;
void LogProtocolMessage(ProtocolMessageType type,
const base::StringPiece& message);
PrefService* GetPrefs() const;
CefRefPtr<CefBrowserHostImpl> frontend_browser_;
content::WebContents* inspected_contents_;
scoped_refptr<content::DevToolsAgentHost> agent_host_;
CefPoint inspect_element_at_;
base::OnceClosure frontend_destroyed_callback_;
std::unique_ptr<content::DevToolsFrontendHost> frontend_host_;
class NetworkResourceLoader;
@@ -93,6 +101,9 @@ class CefDevToolsFrontend : public content::WebContentsObserver,
using ExtensionsAPIs = std::map<std::string, std::string>;
ExtensionsAPIs extensions_api_;
CefDevToolsFileManager file_manager_;
const base::FilePath protocol_log_file_;
base::WeakPtrFactory<CefDevToolsFrontend> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(CefDevToolsFrontend);

View File

@@ -0,0 +1,200 @@
// Copyright (c) 2020 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
#include "libcef/browser/devtools/devtools_manager.h"
#include "libcef/browser/devtools/devtools_controller.h"
#include "libcef/browser/devtools/devtools_frontend.h"
#include "content/public/browser/web_contents.h"
namespace {
// May be created on any thread but will be destroyed on the UI thread.
class CefDevToolsRegistrationImpl : public CefRegistration,
public CefDevToolsController::Observer {
public:
explicit CefDevToolsRegistrationImpl(
CefRefPtr<CefDevToolsMessageObserver> observer)
: observer_(observer) {
DCHECK(observer_);
}
~CefDevToolsRegistrationImpl() override {
CEF_REQUIRE_UIT();
// May be null if OnDevToolsControllerDestroyed was called.
if (!controller_)
return;
controller_->RemoveObserver(this);
}
void Initialize(CefBrowserHostImpl* browser,
base::WeakPtr<CefDevToolsController> controller) {
CEF_REQUIRE_UIT();
DCHECK(browser && controller);
DCHECK(!browser_ && !controller_);
browser_ = browser;
controller_ = controller;
controller_->AddObserver(this);
}
private:
// CefDevToolsController::Observer methods:
bool OnDevToolsMessage(const base::StringPiece& message) override {
CEF_REQUIRE_UIT();
return observer_->OnDevToolsMessage(browser_, message.data(),
message.size());
}
void OnDevToolsMethodResult(int message_id,
bool success,
const base::StringPiece& result) override {
CEF_REQUIRE_UIT();
observer_->OnDevToolsMethodResult(browser_, message_id, success,
result.data(), result.size());
}
void OnDevToolsEvent(const base::StringPiece& method,
const base::StringPiece& params) override {
CEF_REQUIRE_UIT();
observer_->OnDevToolsEvent(browser_, method.as_string(), params.data(),
params.size());
}
void OnDevToolsAgentAttached() override {
CEF_REQUIRE_UIT();
observer_->OnDevToolsAgentAttached(browser_);
}
void OnDevToolsAgentDetached() override {
CEF_REQUIRE_UIT();
observer_->OnDevToolsAgentDetached(browser_);
}
void OnDevToolsControllerDestroyed() override {
CEF_REQUIRE_UIT();
browser_ = nullptr;
controller_.reset();
}
CefRefPtr<CefDevToolsMessageObserver> observer_;
CefBrowserHostImpl* browser_ = nullptr;
base::WeakPtr<CefDevToolsController> controller_;
IMPLEMENT_REFCOUNTING_DELETE_ON_UIT(CefDevToolsRegistrationImpl);
DISALLOW_COPY_AND_ASSIGN(CefDevToolsRegistrationImpl);
};
} // namespace
CefDevToolsManager::CefDevToolsManager(CefBrowserHostImpl* inspected_browser)
: inspected_browser_(inspected_browser), weak_ptr_factory_(this) {
CEF_REQUIRE_UIT();
}
CefDevToolsManager::~CefDevToolsManager() {
CEF_REQUIRE_UIT();
}
void CefDevToolsManager::ShowDevTools(const CefWindowInfo& windowInfo,
CefRefPtr<CefClient> client,
const CefBrowserSettings& settings,
const CefPoint& inspect_element_at) {
CEF_REQUIRE_UIT();
if (devtools_frontend_) {
if (!inspect_element_at.IsEmpty()) {
devtools_frontend_->InspectElementAt(inspect_element_at.x,
inspect_element_at.y);
}
devtools_frontend_->Focus();
return;
}
devtools_frontend_ = CefDevToolsFrontend::Show(
inspected_browser_, windowInfo, client, settings, inspect_element_at,
base::BindOnce(&CefDevToolsManager::OnFrontEndDestroyed,
weak_ptr_factory_.GetWeakPtr()));
}
void CefDevToolsManager::CloseDevTools() {
CEF_REQUIRE_UIT();
if (!devtools_frontend_)
return;
devtools_frontend_->Close();
}
bool CefDevToolsManager::HasDevTools() {
CEF_REQUIRE_UIT();
return !!devtools_frontend_;
}
bool CefDevToolsManager::SendDevToolsMessage(const void* message,
size_t message_size) {
CEF_REQUIRE_UIT();
if (!message || message_size == 0)
return false;
if (!EnsureController())
return false;
return devtools_controller_->SendDevToolsMessage(
base::StringPiece(static_cast<const char*>(message), message_size));
}
int CefDevToolsManager::ExecuteDevToolsMethod(
int message_id,
const CefString& method,
CefRefPtr<CefDictionaryValue> params) {
CEF_REQUIRE_UIT();
if (method.empty())
return 0;
if (!EnsureController())
return 0;
if (params && params->IsValid()) {
CefDictionaryValueImpl* impl =
static_cast<CefDictionaryValueImpl*>(params.get());
CefValueController::AutoLock lock_scope(impl->controller());
return devtools_controller_->ExecuteDevToolsMethod(message_id, method,
impl->GetValueUnsafe());
} else {
return devtools_controller_->ExecuteDevToolsMethod(message_id, method,
nullptr);
}
}
// static
CefRefPtr<CefRegistration> CefDevToolsManager::CreateRegistration(
CefRefPtr<CefDevToolsMessageObserver> observer) {
DCHECK(observer);
return new CefDevToolsRegistrationImpl(observer);
}
void CefDevToolsManager::InitializeRegistrationOnUIThread(
CefRefPtr<CefRegistration> registration) {
CEF_REQUIRE_UIT();
if (!EnsureController())
return;
static_cast<CefDevToolsRegistrationImpl*>(registration.get())
->Initialize(inspected_browser_, devtools_controller_->GetWeakPtr());
}
void CefDevToolsManager::OnFrontEndDestroyed() {
devtools_frontend_ = nullptr;
}
bool CefDevToolsManager::EnsureController() {
if (!devtools_controller_) {
devtools_controller_.reset(
new CefDevToolsController(inspected_browser_->web_contents()));
}
return true;
}

View File

@@ -0,0 +1,69 @@
// Copyright (c) 2020 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
#ifndef CEF_LIBCEF_BROWSER_DEVTOOLS_DEVTOOLS_MANAGER_H_
#define CEF_LIBCEF_BROWSER_DEVTOOLS_DEVTOOLS_MANAGER_H_
#pragma once
#include "include/cef_browser.h"
#include "base/memory/weak_ptr.h"
class CefBrowserHostImpl;
class CefDevToolsController;
class CefDevToolsFrontend;
namespace content {
class WebContents;
}
// Manages DevTools instances. Methods must be called on the UI thread unless
// otherwise indicated.
class CefDevToolsManager {
public:
// |inspected_browser| will outlive this object.
explicit CefDevToolsManager(CefBrowserHostImpl* inspected_browser);
~CefDevToolsManager();
// See CefBrowserHost methods of the same name for documentation.
void ShowDevTools(const CefWindowInfo& windowInfo,
CefRefPtr<CefClient> client,
const CefBrowserSettings& settings,
const CefPoint& inspect_element_at);
void CloseDevTools();
bool HasDevTools();
bool SendDevToolsMessage(const void* message, size_t message_size);
int ExecuteDevToolsMethod(int message_id,
const CefString& method,
CefRefPtr<CefDictionaryValue> param);
// These methods are used to implement
// CefBrowserHost::AddDevToolsMessageObserver. CreateRegistration is safe to
// call on any thread. InitializeRegistrationOnUIThread should be called
// immediately afterwards on the UI thread.
static CefRefPtr<CefRegistration> CreateRegistration(
CefRefPtr<CefDevToolsMessageObserver> observer);
void InitializeRegistrationOnUIThread(
CefRefPtr<CefRegistration> registration);
private:
void OnFrontEndDestroyed();
bool EnsureController();
CefBrowserHostImpl* const inspected_browser_;
// CefDevToolsFrontend will delete itself when the frontend WebContents is
// destroyed.
CefDevToolsFrontend* devtools_frontend_ = nullptr;
// Used for sending DevTools protocol messages without an active frontend.
std::unique_ptr<CefDevToolsController> devtools_controller_;
base::WeakPtrFactory<CefDevToolsManager> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(CefDevToolsManager);
};
#endif // CEF_LIBCEF_BROWSER_DEVTOOLS_DEVTOOLS_MANAGER_H_

View File

@@ -132,9 +132,8 @@ CefDevToolsManagerDelegate::CreateNewTarget(const GURL& url) {
}
std::string CefDevToolsManagerDelegate::GetDiscoveryPageHTML() {
return ui::ResourceBundle::GetSharedInstance()
.GetRawDataResource(IDR_CEF_DEVTOOLS_DISCOVERY_PAGE)
.as_string();
return ui::ResourceBundle::GetSharedInstance().LoadDataResourceString(
IDR_CEF_DEVTOOLS_DISCOVERY_PAGE);
}
bool CefDevToolsManagerDelegate::HasBundledFrontendResources() {

View File

@@ -0,0 +1,131 @@
// Copyright (c) 2020 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
#include "libcef/browser/devtools/devtools_util.h"
#include "base/strings/string_number_conversions.h"
namespace devtools_util {
namespace {
bool IsValidDictionary(const base::StringPiece& str, bool allow_empty) {
return str.length() >= (allow_empty ? 2 : 3) && str[0] == '{' &&
str[str.length() - 1] == '}';
}
// Example:
// {"method":"Target.targetDestroyed","params":{"targetId":"1234..."}}
bool ParseEvent(const base::StringPiece& message,
base::StringPiece& method,
base::StringPiece& params) {
static const char kMethodStart[] = "{\"method\":\"";
static const char kMethodEnd[] = "\"";
static const char kParamsStart[] = ",\"params\":";
if (!message.starts_with(kMethodStart))
return false;
const size_t method_start = sizeof(kMethodStart) - 1;
const size_t method_end = message.find(kMethodEnd, method_start);
if (method_end < 0U)
return false;
method = message.substr(method_start, method_end - method_start);
if (method.empty())
return false;
size_t remainder_start = method_end + sizeof(kMethodEnd) - 1;
if (remainder_start == message.size() - 1) {
// No more contents.
params = base::StringPiece();
} else {
const base::StringPiece& remainder = message.substr(remainder_start);
if (remainder.starts_with(kParamsStart)) {
// Stop immediately before the message closing bracket.
remainder_start += sizeof(kParamsStart) - 1;
params =
message.substr(remainder_start, message.size() - 1 - remainder_start);
} else {
// Invalid format.
return false;
}
if (!IsValidDictionary(params, /*allow_empty=*/true))
return false;
}
return true;
}
// Examples:
// {"id":3,"result":{}}
// {"id":4,"result":{"debuggerId":"-2193881606781505058.81393575456727957"}}
// {"id":5,"error":{"code":-32000,"message":"Not supported"}}
bool ParseResult(const base::StringPiece& message,
int& message_id,
bool& success,
base::StringPiece& result) {
static const char kIdStart[] = "{\"id\":";
static const char kIdEnd[] = ",";
static const char kResultStart[] = "\"result\":";
static const char kErrorStart[] = "\"error\":";
if (!message.starts_with(kIdStart))
return false;
const size_t id_start = sizeof(kIdStart) - 1;
const size_t id_end = message.find(kIdEnd, id_start);
if (id_end < 0U)
return false;
const base::StringPiece& id_str = message.substr(id_start, id_end - id_start);
if (id_str.empty() || !base::StringToInt(id_str, &message_id))
return false;
size_t remainder_start = id_end + sizeof(kIdEnd) - 1;
const base::StringPiece& remainder = message.substr(remainder_start);
if (remainder.starts_with(kResultStart)) {
// Stop immediately before the message closing bracket.
remainder_start += sizeof(kResultStart) - 1;
result =
message.substr(remainder_start, message.size() - 1 - remainder_start);
success = true;
} else if (remainder.starts_with(kErrorStart)) {
// Stop immediately before the message closing bracket.
remainder_start += sizeof(kErrorStart) - 1;
result =
message.substr(remainder_start, message.size() - 1 - remainder_start);
success = false;
} else {
// Invalid format.
return false;
}
if (!IsValidDictionary(result, /*allow_empty=*/true))
return false;
return true;
}
} // namespace
// static
bool ProtocolParser::IsValidMessage(const base::StringPiece& message) {
return IsValidDictionary(message, /*allow_empty=*/false);
}
bool ProtocolParser::Initialize(const base::StringPiece& message) {
if (status_ != UNINITIALIZED)
return false;
if (ParseEvent(message, method_, params_)) {
status_ = EVENT;
} else if (ParseResult(message, message_id_, success_, params_)) {
status_ = RESULT;
} else {
status_ = FAILURE;
}
return true;
}
} // namespace devtools_util

View File

@@ -0,0 +1,72 @@
// Copyright (c) 2020 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
#ifndef CEF_LIBCEF_BROWSER_DEVTOOLS_DEVTOOLS_UTIL_H_
#define CEF_LIBCEF_BROWSER_DEVTOOLS_DEVTOOLS_UTIL_H_
#pragma once
#include "base/strings/string_piece.h"
namespace devtools_util {
// Fast parser for DevTools JSON protocol messages. This implementation makes
// certain assumptions about the JSON object structure (value order and
// formatting) to avoid stateful parsing of messages that may be large
// (sometimes > 1MB in size). The message must be a JSON dictionary that starts
// with a "method" or "id" value which is non-empty and of the expected data
// type. Messages that have a "method" value (event message) may optionally have
// a "params" dictionary. Messages that have an "id" value (result message) must
// have a "result" or "error" dictionary. The dictionary contents are not
// validated and may be empty ("{}").
//
// Example event message:
// {"method":"Target.targetDestroyed","params":{"targetId":"1234..."}}
//
// Example result messages:
// {"id":3,"result":{}}
// {"id":4,"result":{"debuggerId":"-2193881606781505058.81393575456727957"}}
// {"id":5,"error":{"code":-32000,"message":"Not supported"}}
struct ProtocolParser {
ProtocolParser() = default;
// Checks for a non-empty JSON dictionary.
static bool IsValidMessage(const base::StringPiece& message);
// Returns false if already initialized.
bool Initialize(const base::StringPiece& message);
bool IsInitialized() const { return status_ != UNINITIALIZED; }
bool IsEvent() const { return status_ == EVENT; }
bool IsResult() const { return status_ == RESULT; }
bool IsFailure() const { return status_ == FAILURE; }
void Reset() { status_ = UNINITIALIZED; }
// For event messages:
// "method" string:
base::StringPiece method_;
// For result messages:
// "id" int:
int message_id_ = 0;
// true if "result" value, false if "error" value:
bool success_ = false;
// For both:
// "params", "result" or "error" dictionary:
base::StringPiece params_;
private:
enum Status {
UNINITIALIZED,
EVENT, // Event message.
RESULT, // Result message.
FAILURE, // Parsing failure.
};
Status status_ = UNINITIALIZED;
};
} // namespace devtools_util
#endif // CEF_LIBCEF_BROWSER_DEVTOOLS_DEVTOOLS_UTIL_H_

View File

@@ -0,0 +1,204 @@
// Copyright (c) 2020 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
#include "libcef/browser/devtools/devtools_util.h"
#include "testing/gtest/include/gtest/gtest.h"
using namespace devtools_util;
TEST(DevToolsUtil, ProtocolParser_IsValidMessage) {
// Empty dictionary is not valid.
EXPECT_FALSE(ProtocolParser::IsValidMessage(""));
EXPECT_FALSE(ProtocolParser::IsValidMessage("{}"));
// Incorrectly formatted dictionary is not valid.
EXPECT_FALSE(ProtocolParser::IsValidMessage("{ ]"));
// Everything else is valid (we don't verify JSON structure).
EXPECT_TRUE(ProtocolParser::IsValidMessage("{ }"));
EXPECT_TRUE(ProtocolParser::IsValidMessage("{blah blah}"));
EXPECT_TRUE(ProtocolParser::IsValidMessage("{method:\"foobar\"}"));
}
TEST(DevToolsUtil, ProtocolParser_Initialize_IsFailure_Unknown) {
ProtocolParser parser;
EXPECT_FALSE(parser.IsInitialized());
// Empty message is invalid.
EXPECT_TRUE(parser.Initialize(""));
EXPECT_TRUE(parser.IsInitialized());
EXPECT_TRUE(parser.IsFailure());
parser.Reset();
EXPECT_FALSE(parser.IsInitialized());
// Empty dictionary is invalid.
EXPECT_TRUE(parser.Initialize("{}"));
EXPECT_TRUE(parser.IsInitialized());
EXPECT_TRUE(parser.IsFailure());
parser.Reset();
EXPECT_FALSE(parser.IsInitialized());
// Unrecognized dictionary type is invalid.
EXPECT_TRUE(parser.Initialize("{blah blah}"));
EXPECT_TRUE(parser.IsInitialized());
EXPECT_TRUE(parser.IsFailure());
}
TEST(DevToolsUtil, ProtocolParser_Initialize_IsFailure_EventMalformed) {
ProtocolParser parser;
EXPECT_FALSE(parser.IsInitialized());
// Empty method is invalid.
EXPECT_TRUE(parser.Initialize("{\"method\":\"\"}"));
EXPECT_TRUE(parser.IsInitialized());
EXPECT_TRUE(parser.IsFailure());
parser.Reset();
EXPECT_FALSE(parser.IsInitialized());
// Unrecognized value is invalid.
EXPECT_TRUE(parser.Initialize("{\"method\":\"foo\",oops:false}"));
EXPECT_TRUE(parser.IsInitialized());
EXPECT_TRUE(parser.IsFailure());
parser.Reset();
EXPECT_FALSE(parser.IsInitialized());
// Params must be a dictionary.
EXPECT_TRUE(parser.Initialize("{\"method\":\",params:[]}"));
EXPECT_TRUE(parser.IsInitialized());
EXPECT_TRUE(parser.IsFailure());
}
TEST(DevToolsUtil, ProtocolParser_Initialize_IsEvent) {
ProtocolParser parser;
EXPECT_FALSE(parser.IsInitialized());
// Method without params is valid.
std::string message = "{\"method\":\"Test.myMethod\"}";
EXPECT_TRUE(parser.Initialize(message));
EXPECT_TRUE(parser.IsInitialized());
EXPECT_TRUE(parser.IsEvent());
EXPECT_STREQ("Test.myMethod", parser.method_.as_string().data());
EXPECT_TRUE(parser.params_.empty());
parser.Reset();
EXPECT_FALSE(parser.IsInitialized());
// Method with empty params dictionary is valid.
message = "{\"method\":\"Test.myMethod2\",\"params\":{}}";
EXPECT_TRUE(parser.Initialize(message));
EXPECT_TRUE(parser.IsInitialized());
EXPECT_TRUE(parser.IsEvent());
EXPECT_STREQ("Test.myMethod2", parser.method_.as_string().data());
EXPECT_STREQ("{}", parser.params_.as_string().data());
parser.Reset();
EXPECT_FALSE(parser.IsInitialized());
// Method with non-empty params dictionary is valid.
message = "{\"method\":\"Test.myMethod3\",\"params\":{\"foo\":\"bar\"}}";
EXPECT_TRUE(parser.Initialize(message));
EXPECT_TRUE(parser.IsInitialized());
EXPECT_TRUE(parser.IsEvent());
EXPECT_STREQ("Test.myMethod3", parser.method_.as_string().data());
EXPECT_STREQ("{\"foo\":\"bar\"}", parser.params_.as_string().data());
}
TEST(DevToolsUtil, ProtocolParser_Initialize_IsFailure_ResultMalformed) {
ProtocolParser parser;
EXPECT_FALSE(parser.IsInitialized());
// Empty ID is invalid.
EXPECT_TRUE(parser.Initialize("{\"id\":,result:{}}"));
EXPECT_TRUE(parser.IsInitialized());
EXPECT_TRUE(parser.IsFailure());
parser.Reset();
EXPECT_FALSE(parser.IsInitialized());
// Missing result or error value is invalid.
EXPECT_TRUE(parser.Initialize("{\"id\":1}"));
EXPECT_TRUE(parser.IsInitialized());
EXPECT_TRUE(parser.IsFailure());
parser.Reset();
EXPECT_FALSE(parser.IsInitialized());
// Unrecognized value is invalid.
EXPECT_TRUE(parser.Initialize("{\"id\":1,oops:false}"));
EXPECT_TRUE(parser.IsInitialized());
EXPECT_TRUE(parser.IsFailure());
parser.Reset();
EXPECT_FALSE(parser.IsInitialized());
// Result must be a dictionary.
EXPECT_TRUE(parser.Initialize("{\"id\":1,\"result\":[]}"));
EXPECT_TRUE(parser.IsInitialized());
EXPECT_TRUE(parser.IsFailure());
parser.Reset();
EXPECT_FALSE(parser.IsInitialized());
// Error must be a dictionary.
EXPECT_TRUE(parser.Initialize("{\"id\":1,\"error\":[]}"));
EXPECT_TRUE(parser.IsInitialized());
EXPECT_TRUE(parser.IsFailure());
}
TEST(DevToolsUtil, ProtocolParser_Initialize_IsResult_Result) {
ProtocolParser parser;
EXPECT_FALSE(parser.IsInitialized());
// Id with empty result dictionary is valid.
std::string message = "{\"id\":1,\"result\":{}}";
EXPECT_TRUE(parser.Initialize(message));
EXPECT_TRUE(parser.IsInitialized());
EXPECT_TRUE(parser.IsResult());
EXPECT_EQ(1, parser.message_id_);
EXPECT_TRUE(parser.success_);
EXPECT_STREQ("{}", parser.params_.as_string().data());
parser.Reset();
EXPECT_FALSE(parser.IsInitialized());
// Id with non-empty result dictionary is valid.
message = "{\"id\":2,\"result\":{\"foo\":\"bar\"}}";
EXPECT_TRUE(parser.Initialize(message));
EXPECT_TRUE(parser.IsInitialized());
EXPECT_TRUE(parser.IsResult());
EXPECT_EQ(2, parser.message_id_);
EXPECT_TRUE(parser.success_);
EXPECT_STREQ("{\"foo\":\"bar\"}", parser.params_.as_string().data());
}
TEST(DevToolsUtil, ProtocolParser_Initialize_IsResult_Error) {
ProtocolParser parser;
EXPECT_FALSE(parser.IsInitialized());
// Id with empty error dictionary is valid.
std::string message = "{\"id\":1,\"error\":{}}";
EXPECT_TRUE(parser.Initialize(message));
EXPECT_TRUE(parser.IsInitialized());
EXPECT_TRUE(parser.IsResult());
EXPECT_EQ(1, parser.message_id_);
EXPECT_FALSE(parser.success_);
EXPECT_STREQ("{}", parser.params_.as_string().data());
parser.Reset();
EXPECT_FALSE(parser.IsInitialized());
// Id with non-empty error dictionary is valid.
message = "{\"id\":2,\"error\":{\"foo\":\"bar\"}}";
EXPECT_TRUE(parser.Initialize(message));
EXPECT_TRUE(parser.IsInitialized());
EXPECT_TRUE(parser.IsResult());
EXPECT_EQ(2, parser.message_id_);
EXPECT_FALSE(parser.success_);
EXPECT_STREQ("{\"foo\":\"bar\"}", parser.params_.as_string().data());
}

View File

@@ -492,6 +492,12 @@ void CefExtensionSystem::InstallUpdate(
base::DeleteFile(temp_dir, true /* recursive */);
}
void CefExtensionSystem::PerformActionBasedOnOmahaAttributes(
const std::string& extension_id,
const base::Value& attributes) {
NOTREACHED();
}
bool CefExtensionSystem::FinishDelayedInstallationIfReady(
const std::string& extension_id,
bool install_immediately) {

View File

@@ -115,6 +115,9 @@ class CefExtensionSystem : public ExtensionSystem {
const base::FilePath& temp_dir,
bool install_immediately,
InstallUpdateCallback install_update_callback) override;
void PerformActionBasedOnOmahaAttributes(
const std::string& extension_id,
const base::Value& attributes) override;
bool FinishDelayedInstallationIfReady(const std::string& extension_id,
bool install_immediately) override;

View File

@@ -32,6 +32,7 @@
#include "extensions/browser/extension_host_delegate.h"
#include "extensions/browser/extensions_browser_interface_binders.h"
#include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h"
#include "extensions/browser/kiosk/kiosk_delegate.h"
#include "extensions/browser/url_request_util.h"
#include "extensions/common/api/mime_handler.mojom.h"
#include "extensions/common/constants.h"
@@ -74,6 +75,18 @@ void BindBeforeUnloadControl(
guest_view->FuseBeforeUnloadControl(std::move(receiver));
}
// Dummy KiosDelegate that always returns false
class CefKioskDelegate : public extensions::KioskDelegate {
public:
CefKioskDelegate() = default;
~CefKioskDelegate() override = default;
// KioskDelegate overrides:
bool IsAutoLaunchedKioskApp(const ExtensionId& id) const override {
return false;
}
};
} // namespace
CefExtensionsBrowserClient::CefExtensionsBrowserClient()
@@ -295,7 +308,7 @@ CefExtensionsBrowserClient::GetExtensionSystemFactory() {
}
void CefExtensionsBrowserClient::RegisterBrowserInterfaceBindersForFrame(
service_manager::BinderMapWithContext<content::RenderFrameHost*>* map,
mojo::BinderMapWithContext<content::RenderFrameHost*>* map,
content::RenderFrameHost* render_frame_host,
const Extension* extension) const {
PopulateExtensionFrameBinders(map, render_frame_host, extension);
@@ -351,8 +364,9 @@ CefExtensionsBrowserClient::GetExtensionWebContentsObserver(
}
KioskDelegate* CefExtensionsBrowserClient::GetKioskDelegate() {
NOTREACHED();
return nullptr;
if (!kiosk_delegate_)
kiosk_delegate_.reset(new CefKioskDelegate());
return kiosk_delegate_.get();
}
bool CefExtensionsBrowserClient::IsLockScreenContext(

View File

@@ -82,8 +82,7 @@ class CefExtensionsBrowserClient : public ExtensionsBrowserClient {
bool IsLoggedInAsPublicAccount() override;
ExtensionSystemProvider* GetExtensionSystemFactory() override;
void RegisterBrowserInterfaceBindersForFrame(
service_manager::BinderMapWithContext<content::RenderFrameHost*>*
binder_map,
mojo::BinderMapWithContext<content::RenderFrameHost*>* binder_map,
content::RenderFrameHost* render_frame_host,
const Extension* extension) const override;
std::unique_ptr<RuntimeAPIDelegate> CreateRuntimeAPIDelegate(
@@ -111,6 +110,8 @@ class CefExtensionsBrowserClient : public ExtensionsBrowserClient {
// Resource manager used to supply resources from pak files.
std::unique_ptr<ComponentExtensionResourceManager> resource_manager_;
std::unique_ptr<KioskDelegate> kiosk_delegate_;
DISALLOW_COPY_AND_ASSIGN(CefExtensionsBrowserClient);
};

View File

@@ -32,9 +32,9 @@ const char kPdfResourceIdentifier[] = "chromium-pdf";
const char kPdfPluginName[] = "Chrome PDF Viewer";
std::string GetManifest() {
std::string manifest_contents = ui::ResourceBundle::GetSharedInstance()
.GetRawDataResource(IDR_PDF_MANIFEST)
.as_string();
std::string manifest_contents =
ui::ResourceBundle::GetSharedInstance().LoadDataResourceString(
IDR_PDF_MANIFEST);
DCHECK(manifest_contents.find(kNameTag) != std::string::npos);
base::ReplaceFirstSubstringAfterOffset(&manifest_contents, 0, kNameTag,
kPdfPluginName);

View File

@@ -4,6 +4,84 @@
#include "libcef/browser/media_router/media_sink_impl.h"
#include "libcef/browser/thread_util.h"
#include "base/strings/string_number_conversions.h"
#include "chrome/browser/media/router/discovery/dial/dial_media_sink_service_impl.h"
#include "chrome/browser/media/router/providers/cast/dual_media_sink_service.h"
#include "chrome/common/media_router/discovery/media_sink_internal.h"
#include "chrome/common/media_router/discovery/media_sink_service_base.h"
namespace {
using SinkServiceVector = std::vector<media_router::MediaSinkServiceBase*>;
SinkServiceVector GetSinkServices() {
CEF_REQUIRE_UIT();
auto sink_service = media_router::DualMediaSinkService::GetInstance();
return {sink_service->GetCastMediaSinkServiceImpl(),
sink_service->GetDialMediaSinkServiceImpl()};
}
void GetSinkInternalAndContinue(
SinkServiceVector services,
const media_router::MediaSink::Id& sink_id,
CefRefPtr<CefMediaSinkDeviceInfoCallback> callback) {
CEF_REQUIRE_IOT();
CefMediaSinkDeviceInfo device_info;
const media_router::MediaSinkInternal* sink_internal = nullptr;
for (auto service : services) {
sink_internal = service->GetSinkById(sink_id);
if (sink_internal)
break;
}
if (sink_internal) {
if (sink_internal->is_cast_sink()) {
const auto& cast_data = sink_internal->cast_data();
CefString(&device_info.ip_address) =
cast_data.ip_endpoint.ToStringWithoutPort();
device_info.port = cast_data.ip_endpoint.port();
CefString(&device_info.model_name) = cast_data.model_name;
} else if (sink_internal->is_dial_sink()) {
const auto& dial_data = sink_internal->dial_data();
CefString(&device_info.ip_address) = dial_data.ip_address.ToString();
if (dial_data.app_url.is_valid() && dial_data.app_url.has_port()) {
base::StringToInt(dial_data.app_url.port_piece(), &device_info.port);
}
CefString(&device_info.model_name) = dial_data.model_name;
}
}
// Execute the callback on the UI thread.
CEF_POST_TASK(
CEF_UIT,
base::BindOnce(&CefMediaSinkDeviceInfoCallback::OnMediaSinkDeviceInfo,
callback, device_info));
}
void GetDeviceInfo(const media_router::MediaSink::Id& sink_id,
CefRefPtr<CefMediaSinkDeviceInfoCallback> callback) {
auto next_step = base::BindOnce(
[](const media_router::MediaSink::Id& sink_id,
CefRefPtr<CefMediaSinkDeviceInfoCallback> callback) {
CEF_POST_TASK(CEF_IOT,
base::BindOnce(GetSinkInternalAndContinue,
GetSinkServices(), sink_id, callback));
},
sink_id, callback);
if (CEF_CURRENTLY_ON(CEF_UIT)) {
std::move(next_step).Run();
} else {
CEF_POST_TASK(CEF_UIT, std::move(next_step));
}
}
} // namespace
CefMediaSinkImpl::CefMediaSinkImpl(const media_router::MediaSink& sink)
: sink_(sink) {}
@@ -27,6 +105,20 @@ CefString CefMediaSinkImpl::GetDescription() {
return sink_.description().value_or("");
}
CefMediaSink::IconType CefMediaSinkImpl::GetIconType() {
// Verify that our enum matches Chromium's values.
static_assert(static_cast<int>(CEF_MSIT_TOTAL_COUNT) ==
static_cast<int>(media_router::SinkIconType::TOTAL_COUNT),
"enum mismatch");
return static_cast<CefMediaSink::IconType>(sink_.icon_type());
}
void CefMediaSinkImpl::GetDeviceInfo(
CefRefPtr<CefMediaSinkDeviceInfoCallback> callback) {
::GetDeviceInfo(sink_.id(), callback);
}
bool CefMediaSinkImpl::IsCastSink() {
return sink_.provider_id() == media_router::CAST;
}

View File

@@ -22,6 +22,9 @@ class CefMediaSinkImpl : public CefMediaSink {
bool IsValid() override;
CefString GetName() override;
CefString GetDescription() override;
IconType GetIconType() override;
void GetDeviceInfo(
CefRefPtr<CefMediaSinkDeviceInfoCallback> callback) override;
bool IsCastSink() override;
bool IsDialSink() override;
bool IsCompatibleWith(CefRefPtr<CefMediaSource> source) override;

View File

@@ -15,7 +15,9 @@
#include "base/message_loop/message_loop.h"
#include "content/public/common/menu_item.h"
#include "ui/base/accelerators/accelerator.h"
#include "ui/base/models/image_model.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/image/image.h"
namespace {
@@ -104,7 +106,9 @@ class CefSimpleMenuModel : public ui::MenuModel {
return impl_->GetGroupIdAt(index);
}
bool GetIconAt(int index, gfx::Image* icon) const override { return false; }
ui::ImageModel GetIconAt(int index) const override {
return ui::ImageModel();
}
ui::ButtonMenuItemModel* GetButtonMenuItemAt(int index) const override {
return nullptr;

View File

@@ -394,9 +394,9 @@ gfx::Size CefBrowserPlatformDelegateNativeMac::GetMaximumDialogSize() {
content::NativeWebKeyboardEvent
CefBrowserPlatformDelegateNativeMac::TranslateWebKeyEvent(
const CefKeyEvent& key_event) const {
content::NativeWebKeyboardEvent result(blink::WebInputEvent::kUndefined,
blink::WebInputEvent::kNoModifiers,
ui::EventTimeForNow());
content::NativeWebKeyboardEvent result(
blink::WebInputEvent::Type::kUndefined,
blink::WebInputEvent::Modifiers::kNoModifiers, ui::EventTimeForNow());
// Use a synthetic NSEvent in order to obtain the windowsKeyCode member from
// the NativeWebKeyboardEvent constructor. This is the only member which can
@@ -444,7 +444,7 @@ CefBrowserPlatformDelegateNativeMac::TranslateWebKeyEvent(
result = content::NativeWebKeyboardEvent(synthetic_event);
if (key_event.type == KEYEVENT_CHAR)
result.SetType(blink::WebInputEvent::kChar);
result.SetType(blink::WebInputEvent::Type::kChar);
result.is_system_key = key_event.is_system_key;
@@ -462,18 +462,18 @@ CefBrowserPlatformDelegateNativeMac::TranslateWebClickEvent(
switch (type) {
case MBT_LEFT:
result.SetType(mouseUp ? blink::WebInputEvent::kMouseUp
: blink::WebInputEvent::kMouseDown);
result.SetType(mouseUp ? blink::WebInputEvent::Type::kMouseUp
: blink::WebInputEvent::Type::kMouseDown);
result.button = blink::WebMouseEvent::Button::kLeft;
break;
case MBT_MIDDLE:
result.SetType(mouseUp ? blink::WebInputEvent::kMouseUp
: blink::WebInputEvent::kMouseDown);
result.SetType(mouseUp ? blink::WebInputEvent::Type::kMouseUp
: blink::WebInputEvent::Type::kMouseDown);
result.button = blink::WebMouseEvent::Button::kMiddle;
break;
case MBT_RIGHT:
result.SetType(mouseUp ? blink::WebInputEvent::kMouseUp
: blink::WebInputEvent::kMouseDown);
result.SetType(mouseUp ? blink::WebInputEvent::Type::kMouseUp
: blink::WebInputEvent::Type::kMouseDown);
result.button = blink::WebMouseEvent::Button::kRight;
break;
default:
@@ -492,7 +492,7 @@ blink::WebMouseEvent CefBrowserPlatformDelegateNativeMac::TranslateWebMoveEvent(
TranslateWebMouseEvent(result, mouse_event);
if (!mouseLeave) {
result.SetType(blink::WebInputEvent::kMouseMove);
result.SetType(blink::WebInputEvent::Type::kMouseMove);
if (mouse_event.modifiers & EVENTFLAG_LEFT_MOUSE_BUTTON)
result.button = blink::WebMouseEvent::Button::kLeft;
else if (mouse_event.modifiers & EVENTFLAG_MIDDLE_MOUSE_BUTTON)
@@ -502,7 +502,7 @@ blink::WebMouseEvent CefBrowserPlatformDelegateNativeMac::TranslateWebMoveEvent(
else
result.button = blink::WebMouseEvent::Button::kNoButton;
} else {
result.SetType(blink::WebInputEvent::kMouseLeave);
result.SetType(blink::WebInputEvent::Type::kMouseLeave);
result.button = blink::WebMouseEvent::Button::kNoButton;
}
@@ -519,7 +519,7 @@ CefBrowserPlatformDelegateNativeMac::TranslateWebWheelEvent(
blink::WebMouseWheelEvent result;
TranslateWebMouseEvent(result, mouse_event);
result.SetType(blink::WebInputEvent::kMouseWheel);
result.SetType(blink::WebInputEvent::Type::kMouseWheel);
static const double scrollbarPixelsPerCocoaTick = 40.0;
result.delta_x = deltaX;

View File

@@ -374,13 +374,13 @@ bool CefBrowserPlatformDelegateNativeWin::HandleKeyboardEvent(
return false;
switch (event.GetType()) {
case blink::WebInputEvent::kRawKeyDown:
case blink::WebInputEvent::Type::kRawKeyDown:
msg.message = event.is_system_key ? WM_SYSKEYDOWN : WM_KEYDOWN;
break;
case blink::WebInputEvent::kKeyUp:
case blink::WebInputEvent::Type::kKeyUp:
msg.message = event.is_system_key ? WM_SYSKEYUP : WM_KEYUP;
break;
case blink::WebInputEvent::kChar:
case blink::WebInputEvent::Type::kChar:
msg.message = event.is_system_key ? WM_SYSCHAR : WM_CHAR;
break;
default:

View File

@@ -79,6 +79,31 @@ std::wstring FormatFilterForExtensions(
std::wstring result;
// Create all supported .ext filter if more than one filter.
if (file_ext.size() > 1) {
std::set<base::WStringPiece> unique_exts;
for (const auto& exts : file_ext) {
for (const auto& ext : base::SplitStringPiece(
exts, L";", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY)) {
unique_exts.insert(ext);
}
}
if (unique_exts.size() > 1) {
std::wstring ext;
auto it = unique_exts.cbegin();
ext = it->as_string();
for (++it; it != unique_exts.cend(); ++it) {
ext += L";" + it->as_string();
}
std::wstring desc =
l10n_util::GetStringUTF16(IDS_CUSTOM_FILES) + L" (" + ext + L")";
result.append(desc.c_str(), desc.size() + 1); // Append NULL too.
result.append(ext.c_str(), ext.size() + 1);
}
}
for (size_t i = 0; i < file_ext.size(); ++i) {
std::wstring ext = file_ext[i];
std::wstring desc;

View File

@@ -20,6 +20,7 @@
#include "ui/base/accelerators/accelerator.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/l10n/l10n_util_win.h"
#include "ui/base/models/image_model.h"
#include "ui/base/models/menu_model.h"
#include "ui/events/keycodes/keyboard_codes.h"
#include "ui/gfx/canvas.h"
@@ -30,6 +31,7 @@
#include "ui/gfx/text_utils.h"
#include "ui/gfx/win/hwnd_util.h"
#include "ui/native_theme/native_theme.h"
#include "ui/native_theme/themed_vector_icon.h"
#include "ui/views/controls/menu/menu_config.h"
#include "ui/views/controls/menu/menu_insertion_delegate_win.h"
@@ -288,10 +290,18 @@ class CefNativeMenuWin::MenuHostWindow {
// Draw the icon after the label, otherwise it would be covered
// by the label.
gfx::Image icon;
if (data->native_menu_win->model_->GetIconAt(data->model_index, &icon)) {
ui::ImageModel icon =
data->native_menu_win->model_->GetIconAt(data->model_index);
if (icon.IsImage() || icon.IsVectorIcon()) {
ui::NativeTheme* native_theme =
ui::NativeTheme::GetInstanceForNativeUi();
// We currently don't support items with both icons and checkboxes.
const gfx::ImageSkia skia_icon = icon.AsImageSkia();
const gfx::ImageSkia skia_icon =
icon.IsImage() ? icon.GetImage().AsImageSkia()
: ui::ThemedVectorIcon(icon.GetVectorIcon())
.GetImageSkia(native_theme, 16);
DCHECK(type != ui::MenuModel::TYPE_CHECK);
std::unique_ptr<SkCanvas> canvas = skia::CreatePlatformCanvas(
skia_icon.width(), skia_icon.height(), false);

View File

@@ -9,8 +9,8 @@
#include "ui/base/x/x11_util.h"
#include "ui/events/platform/platform_event_source.h"
#include "ui/events/x/x11_event_translation.h"
#include "ui/platform_window/x11/x11_topmost_window_finder.h"
#include "ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h"
#include "ui/views/widget/desktop_aura/x11_topmost_window_finder.h"
#include <X11/Xatom.h>
#include <X11/Xlib.h>

View File

@@ -43,6 +43,7 @@
#include "content/public/common/url_utils.h"
#include "content/public/common/user_agent.h"
#include "ipc/ipc_channel.h"
#include "ui/base/resource/resource_bundle.h"
#include "v8/include/v8.h"
using extensions::api::cef::kSupportedAPIs;
@@ -74,6 +75,7 @@ const char* kAllowedWebUIHosts[] = {
content::kChromeUIAppCacheInternalsHost,
chrome::kChromeUIAccessibilityHost,
content::kChromeUIBlobInternalsHost,
chrome::kChromeUIChromeURLsHost,
chrome::kChromeUICreditsHost,
kChromeUIExtensionsSupportHost,
content::kChromeUIGpuHost,
@@ -118,6 +120,7 @@ const struct {
const char* host;
ChromeHostId host_id;
} kAllowedCefHosts[] = {
{chrome::kChromeUIChromeURLsHost, CHROME_WEBUI_HOSTS},
{kChromeUIExtensionsSupportHost, CHROME_EXTENSIONS_SUPPORT},
{kChromeUILicenseHost, CHROME_LICENSE},
{chrome::kChromeUIVersionHost, CHROME_VERSION},
@@ -341,16 +344,17 @@ bool OnExtensionsSupportUI(std::string* mime_type, std::string* output) {
}
bool OnLicenseUI(std::string* mime_type, std::string* output) {
base::StringPiece piece = CefContentClient::Get()->GetDataResource(
IDR_CEF_LICENSE_TXT, ui::SCALE_FACTOR_NONE);
std::string piece =
ui::ResourceBundle::GetSharedInstance().LoadDataResourceString(
IDR_CEF_LICENSE_TXT);
if (piece.empty()) {
NOTREACHED() << "Failed to load license txt resource.";
return false;
}
*mime_type = "text/html";
*output = "<html><head><title>License</title></head><body><pre>" +
piece.as_string() + "</pre></body></html>";
*output = "<html><head><title>License</title></head><body><pre>" + piece +
"</pre></body></html>";
return true;
}
@@ -358,9 +362,10 @@ bool OnLicenseUI(std::string* mime_type, std::string* output) {
bool OnVersionUI(Profile* profile,
std::string* mime_type,
std::string* output) {
base::StringPiece piece = CefContentClient::Get()->GetDataResource(
IDR_CEF_VERSION_HTML, ui::SCALE_FACTOR_NONE);
if (piece.empty()) {
std::string tmpl =
ui::ResourceBundle::GetSharedInstance().LoadDataResourceString(
IDR_CEF_VERSION_HTML);
if (tmpl.empty()) {
NOTREACHED() << "Failed to load version html resource.";
return false;
}
@@ -381,7 +386,6 @@ bool OnVersionUI(Profile* profile,
parser.Add("MODULEPATH", GetModulePath());
parser.Add("CACHEPATH", CefString(profile->GetPath().value()));
std::string tmpl = piece.as_string();
parser.Parse(&tmpl);
*mime_type = "text/html";
@@ -392,8 +396,8 @@ bool OnVersionUI(Profile* profile,
bool OnWebUIHostsUI(std::string* mime_type, std::string* output) {
std::string html =
"<html>\n<head><title>WebUI Hosts</title></head>\n"
"<body bgcolor=\"white\"><h3>WebUI Hosts</h3>\n<ul>\n";
"<html>\n<head><title>Chrome URLs</title></head>\n"
"<body bgcolor=\"white\"><h3>List of Chrome URLs</h3>\n<ul>\n";
std::vector<std::string> list;
GetAllowedHosts(&list);

View File

@@ -158,13 +158,15 @@ class InternalHandlerFactory : public CefSchemeHandlerFactory {
action.mime_type = GetMimeType(url.path());
if (!action.bytes && action.resource_id >= 0) {
action.bytes =
CefContentClient::Get()->GetDataResourceBytes(action.resource_id);
if (!action.bytes) {
std::string str =
ui::ResourceBundle::GetSharedInstance().LoadDataResourceString(
action.resource_id);
if (str.empty()) {
NOTREACHED() << "Failed to load internal resource for id: "
<< action.resource_id << " URL: " << url.spec().c_str();
return nullptr;
}
action.bytes = base::RefCountedString::TakeString(&str);
}
if (action.bytes) {

View File

@@ -31,6 +31,7 @@
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "services/network/public/cpp/simple_url_loader.h"
#include "services/network/public/cpp/simple_url_loader_stream_consumer.h"
#include "third_party/blink/public/mojom/loader/resource_load_info.mojom.h"
namespace {
@@ -254,6 +255,21 @@ class CefBrowserURLRequest::Context
resource_request->render_frame_id = render_frame_id;
// Behave the same as a subresource load.
resource_request->resource_type =
static_cast<int>(blink::mojom::ResourceType::kSubResource);
// Set the origin to match the request.
const GURL& url = GURL(request_->GetURL().ToString());
resource_request->request_initiator = url::Origin::Create(url);
if (request_flags & UR_FLAG_ALLOW_STORED_CREDENTIALS) {
// Include SameSite cookies.
resource_request->force_ignore_site_for_cookies = true;
resource_request->site_for_cookies =
net::SiteForCookies::FromOrigin(*resource_request->request_initiator);
}
// SimpleURLLoader is picky about the body contents. Try to populate them
// correctly below.
auto request_body = resource_request->request_body;

View File

@@ -125,7 +125,7 @@ void SaveCookiesOnUIThread(content::BrowserContext* browser_context,
for (const auto& cookie : cookies) {
progress->num_cookie_lines_left_++;
cookie_manager->SetCanonicalCookie(
cookie, url.scheme(), options,
cookie, url, options,
base::BindOnce(&SetCanonicalCookieCallback, base::Unretained(progress),
cookie));
}
@@ -158,7 +158,7 @@ void LoadCookies(content::BrowserContext* browser_context,
options.set_same_site_cookie_context(
net::cookie_util::ComputeSameSiteContextForRequest(
request.method, request.url, request.site_for_cookies,
request.request_initiator, request.attach_same_site_cookies));
request.request_initiator, request.force_ignore_site_for_cookies));
CEF_POST_TASK(
CEF_UIT,
@@ -192,7 +192,7 @@ void SaveCookies(content::BrowserContext* browser_context,
options.set_same_site_cookie_context(
net::cookie_util::ComputeSameSiteContextForRequest(
request.method, request.url, request.site_for_cookies,
request.request_initiator, request.attach_same_site_cookies));
request.request_initiator, request.force_ignore_site_for_cookies));
const base::StringPiece name(net_service::kHTTPSetCookieHeaderName);
std::string cookie_string;

View File

@@ -47,6 +47,9 @@ void SetCookieCallbackImpl(CefRefPtr<CefSetCookieCallback> callback,
net::CanonicalCookie::CookieInclusionStatus status) {
if (!callback.get())
return;
if (!status.IsInclude()) {
LOG(WARNING) << "SetCookie failed with reason: " << status.GetDebugString();
}
CEF_POST_TASK(CEF_UIT, base::Bind(&CefSetCookieCallback::OnComplete,
callback.get(), status.IsInclude()));
}
@@ -203,6 +206,8 @@ bool CefCookieManagerImpl::VisitUrlCookies(
net::CookieOptions options;
if (includeHttpOnly)
options.set_include_httponly();
options.set_same_site_cookie_context(
net::CookieOptions::SameSiteCookieContext::MakeInclusive());
auto browser_context = GetBrowserContext(browser_context_getter_);
if (!browser_context)
@@ -239,13 +244,18 @@ bool CefCookieManagerImpl::SetCookie(const CefString& url,
if (cookie.has_expires)
cef_time_to_basetime(cookie.expires, expiration_time);
net::CookieSameSite same_site =
net_service::MakeCookieSameSite(cookie.same_site);
net::CookiePriority priority =
net_service::MakeCookiePriority(cookie.priority);
auto canonical_cookie = net::CanonicalCookie::CreateSanitizedCookie(
gurl, name, value, domain, path,
base::Time(), // Creation time.
expiration_time,
base::Time(), // Last access time.
cookie.secure ? true : false, cookie.httponly ? true : false,
net::CookieSameSite::UNSPECIFIED, net::COOKIE_PRIORITY_DEFAULT);
cookie.secure ? true : false, cookie.httponly ? true : false, same_site,
priority);
if (!canonical_cookie) {
SetCookieCallbackImpl(callback,
@@ -258,13 +268,15 @@ bool CefCookieManagerImpl::SetCookie(const CefString& url,
net::CookieOptions options;
if (cookie.httponly)
options.set_include_httponly();
options.set_same_site_cookie_context(
net::CookieOptions::SameSiteCookieContext::MakeInclusive());
auto browser_context = GetBrowserContext(browser_context_getter_);
if (!browser_context)
return false;
GetCookieManager(browser_context)
->SetCanonicalCookie(*canonical_cookie, gurl.scheme(), options,
->SetCanonicalCookie(*canonical_cookie, gurl, options,
base::Bind(SetCookieCallbackImpl, callback));
return true;
}

View File

@@ -158,9 +158,11 @@ class InterceptedRequest : public network::mojom::URLLoader,
void OnComplete(const network::URLLoaderCompletionStatus& status) override;
// mojom::URLLoader methods:
void FollowRedirect(const std::vector<std::string>& removed_headers,
const net::HttpRequestHeaders& modified_headers,
const base::Optional<GURL>& new_url) override;
void FollowRedirect(
const std::vector<std::string>& removed_headers,
const net::HttpRequestHeaders& modified_headers,
const net::HttpRequestHeaders& modified_cors_exempt_headers,
const base::Optional<GURL>& new_url) override;
void SetPriority(net::RequestPriority priority,
int32_t intra_priority_value) override;
void PauseReadingBodyFromNet() override;
@@ -227,6 +229,7 @@ class InterceptedRequest : public network::mojom::URLLoader,
const uint32_t options_;
bool input_stream_previously_failed_ = false;
bool request_was_redirected_ = false;
int redirect_limit_ = net::URLRequest::kMaxRedirects;
// To avoid sending multiple OnReceivedError callbacks.
bool sent_error_callback_ = false;
@@ -475,13 +478,19 @@ void InterceptedRequest::OnReceiveRedirect(
if (current_request_uses_header_client_) {
// Use the headers we got from OnHeadersReceived as that'll contain
// Set-Cookie if it existed. May be null for synthetic redirects.
DCHECK(current_headers_);
current_response_->headers = current_headers_;
current_headers_ = nullptr;
if (current_headers_) {
current_response_->headers = current_headers_;
current_headers_ = nullptr;
}
} else {
needs_callback = true;
}
if (--redirect_limit_ == 0) {
SendErrorAndCompleteImmediately(net::ERR_TOO_MANY_REDIRECTS);
return;
}
net::RedirectInfo new_redirect_info;
// When we redirect via ContinueToHandleOverrideHeaders the |redirect_info|
@@ -560,6 +569,7 @@ void InterceptedRequest::OnComplete(
void InterceptedRequest::FollowRedirect(
const std::vector<std::string>& removed_headers_ext,
const net::HttpRequestHeaders& modified_headers_ext,
const net::HttpRequestHeaders& modified_cors_exempt_headers,
const base::Optional<GURL>& new_url) {
std::vector<std::string> removed_headers = removed_headers_ext;
net::HttpRequestHeaders modified_headers = modified_headers_ext;
@@ -641,14 +651,14 @@ void InterceptedRequest::InterceptResponseReceived(
if (request_.headers.GetHeader(net::HttpRequestHeaders::kOrigin, &origin) &&
origin != url::Origin().Serialize()) {
// Allow redirects of cross-origin resource loads.
headers->AddHeader(MakeHeader(
network::cors::header_names::kAccessControlAllowOrigin, origin));
headers->AddHeader(network::cors::header_names::kAccessControlAllowOrigin,
origin);
}
if (request_.credentials_mode ==
network::mojom::CredentialsMode::kInclude) {
headers->AddHeader(MakeHeader(
network::cors::header_names::kAccessControlAllowCredentials, "true"));
headers->AddHeader(
network::cors::header_names::kAccessControlAllowCredentials, "true");
}
const net::RedirectInfo& redirect_info =
@@ -940,7 +950,7 @@ void InterceptedRequest::OnURLLoaderClientError() {
void InterceptedRequest::OnURLLoaderError(uint32_t custom_reason,
const std::string& description) {
if (custom_reason == network::mojom::URLLoader::kClientDisconnectReason)
SendErrorCallback(safe_browsing::GetNetErrorCodeForSafeBrowsing(), true);
SendErrorCallback(safe_browsing::kNetErrorCodeForSafeBrowsing, true);
got_loader_error_ = true;

View File

@@ -557,6 +557,7 @@ void StreamReaderURLLoader::ContinueWithRequestHeaders(
void StreamReaderURLLoader::FollowRedirect(
const std::vector<std::string>& removed_headers,
const net::HttpRequestHeaders& modified_headers,
const net::HttpRequestHeaders& modified_cors_exempt_headers,
const base::Optional<GURL>& new_url) {
NOTREACHED();
}
@@ -610,9 +611,12 @@ void StreamReaderURLLoader::OnReaderSkipCompleted(int64_t bytes_skipped) {
HeadersComplete(net::HTTP_OK, -1);
} else if (bytes_skipped == byte_range_.first_byte_position()) {
// We skipped the expected number of bytes.
int64_t expected_content_length = byte_range_.last_byte_position() -
byte_range_.first_byte_position() + 1;
DCHECK_GE(expected_content_length, 0);
int64_t expected_content_length = -1;
if (byte_range_.HasLastBytePosition()) {
expected_content_length = byte_range_.last_byte_position() -
byte_range_.first_byte_position() + 1;
DCHECK_GE(expected_content_length, 0);
}
HeadersComplete(net::HTTP_OK, expected_content_length);
} else {
RequestComplete(bytes_skipped < 0 ? bytes_skipped : net::ERR_FAILED);

View File

@@ -171,9 +171,11 @@ class StreamReaderURLLoader : public network::mojom::URLLoader {
void ContinueResponse(bool was_redirected);
// network::mojom::URLLoader methods:
void FollowRedirect(const std::vector<std::string>& removed_headers,
const net::HttpRequestHeaders& modified_headers,
const base::Optional<GURL>& new_url) override;
void FollowRedirect(
const std::vector<std::string>& removed_headers,
const net::HttpRequestHeaders& modified_headers,
const net::HttpRequestHeaders& modified_cors_exempt_headers,
const base::Optional<GURL>& new_url) override;
void SetPriority(net::RequestPriority priority,
int intra_priority_value) override;
void PauseReadingBodyFromNet() override;

View File

@@ -66,6 +66,20 @@ void CefBrowserPlatformDelegateOsr::BrowserCreated(
}
}
void CefBrowserPlatformDelegateOsr::NotifyBrowserDestroyed() {
content::WebContents* web_contents = browser_->web_contents();
content::RenderViewHost* host = web_contents->GetRenderViewHost();
if (host) {
CefRenderWidgetHostViewOSR* view =
static_cast<CefRenderWidgetHostViewOSR*>(host->GetWidget()->GetView());
if (view) {
view->ReleaseCompositor();
}
}
CefBrowserPlatformDelegate::NotifyBrowserDestroyed();
}
void CefBrowserPlatformDelegateOsr::BrowserDestroyed(
CefBrowserHostImpl* browser) {
CefBrowserPlatformDelegate::BrowserDestroyed(browser);

View File

@@ -26,6 +26,7 @@ class CefBrowserPlatformDelegateOsr
content::RenderViewHostDelegateView** delegate_view) override;
void WebContentsCreated(content::WebContents* web_contents) override;
void BrowserCreated(CefBrowserHostImpl* browser) override;
void NotifyBrowserDestroyed() override;
void BrowserDestroyed(CefBrowserHostImpl* browser) override;
SkColor GetBackgroundColor() const override;
bool CanUseSharedTexture() const override;

View File

@@ -123,11 +123,11 @@ void CefMotionEventOSR::MarkUnchangedTouchPointsAsStationary(
blink::WebTouchEvent* event,
const CefTouchEvent& cef_event) {
int id = LookupId(cef_event.id);
if (event->GetType() == blink::WebInputEvent::kTouchMove ||
event->GetType() == blink::WebInputEvent::kTouchCancel) {
if (event->GetType() == blink::WebInputEvent::Type::kTouchMove ||
event->GetType() == blink::WebInputEvent::Type::kTouchCancel) {
for (size_t i = 0; i < event->touches_length; ++i) {
if (event->touches[i].id != id)
event->touches[i].state = blink::WebTouchPoint::kStateStationary;
event->touches[i].state = blink::WebTouchPoint::State::kStateStationary;
}
}
}

View File

@@ -118,7 +118,7 @@ struct PopulateAxNodeAttributes {
case ax::mojom::IntAttribute::kDefaultActionVerb:
attributes->SetString(
ToString(attr.first),
ui::ActionVerbToUnlocalizedString(
ui::ToString(
static_cast<ax::mojom::DefaultActionVerb>(attr.second)));
break;
case ax::mojom::IntAttribute::kInvalidState: {

View File

@@ -25,6 +25,7 @@
#include "components/viz/common/frame_sinks/begin_frame_args.h"
#include "components/viz/common/frame_sinks/copy_output_request.h"
#include "components/viz/common/frame_sinks/delay_based_time_source.h"
#include "components/viz/common/surfaces/frame_sink_id_allocator.h"
#include "components/viz/common/switches.h"
#include "content/browser/bad_message.h"
#include "content/browser/gpu/gpu_data_manager_impl.h"
@@ -275,6 +276,23 @@ CefRenderWidgetHostViewOSR::CefRenderWidgetHostViewOSR(
}
CefRenderWidgetHostViewOSR::~CefRenderWidgetHostViewOSR() {
ReleaseCompositor();
root_layer_.reset(nullptr);
DCHECK(!parent_host_view_);
DCHECK(!popup_host_view_);
DCHECK(!child_host_view_);
DCHECK(guest_host_views_.empty());
if (text_input_manager_)
text_input_manager_->RemoveObserver(this);
}
void CefRenderWidgetHostViewOSR::ReleaseCompositor() {
if (!compositor_) {
return; // already released
}
// Marking the DelegatedFrameHost as removed from the window hierarchy is
// necessary to remove all connections to its old ui::Compositor.
if (is_showing_) {
@@ -285,15 +303,6 @@ CefRenderWidgetHostViewOSR::~CefRenderWidgetHostViewOSR() {
delegated_frame_host_.reset(nullptr);
compositor_.reset(nullptr);
root_layer_.reset(nullptr);
DCHECK(!parent_host_view_);
DCHECK(!popup_host_view_);
DCHECK(!child_host_view_);
DCHECK(guest_host_views_.empty());
if (text_input_manager_)
text_input_manager_->RemoveObserver(this);
}
// Called for full-screen widgets.
@@ -335,7 +344,9 @@ bool CefRenderWidgetHostViewOSR::HasFocus() {
}
bool CefRenderWidgetHostViewOSR::IsSurfaceAvailableForCopy() {
return delegated_frame_host_->CanCopyFromCompositingSurface();
return delegated_frame_host_
? delegated_frame_host_->CanCopyFromCompositingSurface()
: false;
}
void CefRenderWidgetHostViewOSR::Show() {
@@ -364,10 +375,12 @@ void CefRenderWidgetHostViewOSR::Show() {
base::nullopt /* record_tab_switch_time_request */);
}
delegated_frame_host_->AttachToCompositor(compositor_.get());
delegated_frame_host_->WasShown(
GetLocalSurfaceIdAllocation().local_surface_id(), GetViewBounds().size(),
base::nullopt);
if (delegated_frame_host_) {
delegated_frame_host_->AttachToCompositor(compositor_.get());
delegated_frame_host_->WasShown(
GetLocalSurfaceIdAllocation().local_surface_id(),
GetViewBounds().size(), base::nullopt);
}
if (!content::GpuDataManagerImpl::GetInstance()->IsGpuCompositingDisabled()) {
// Start generating frames when we're visible and at the correct size.
@@ -402,9 +415,11 @@ void CefRenderWidgetHostViewOSR::Hide() {
if (render_widget_host_)
render_widget_host_->WasHidden();
delegated_frame_host_->WasHidden(
content::DelegatedFrameHost::HiddenCause::kOther);
delegated_frame_host_->DetachFromCompositor();
if (delegated_frame_host_) {
delegated_frame_host_->WasHidden(
content::DelegatedFrameHost::HiddenCause::kOther);
delegated_frame_host_->DetachFromCompositor();
}
}
bool CefRenderWidgetHostViewOSR::IsShowing() {
@@ -538,7 +553,9 @@ void CefRenderWidgetHostViewOSR::AddDamageRect(uint32_t sequence,
}
void CefRenderWidgetHostViewOSR::ResetFallbackToFirstNavigationSurface() {
delegated_frame_host_->ResetFallbackToFirstNavigationSurface();
if (delegated_frame_host_) {
delegated_frame_host_->ResetFallbackToFirstNavigationSurface();
}
}
void CefRenderWidgetHostViewOSR::InitAsPopup(
@@ -702,8 +719,10 @@ void CefRenderWidgetHostViewOSR::CopyFromSurface(
const gfx::Rect& src_rect,
const gfx::Size& output_size,
base::OnceCallback<void(const SkBitmap&)> callback) {
delegated_frame_host_->CopyFromCompositingSurface(src_rect, output_size,
std::move(callback));
if (delegated_frame_host_) {
delegated_frame_host_->CopyFromCompositingSurface(src_rect, output_size,
std::move(callback));
}
}
void CefRenderWidgetHostViewOSR::GetScreenInfo(content::ScreenInfo* results) {
@@ -878,11 +897,13 @@ CefRenderWidgetHostViewOSR::GetLocalSurfaceIdAllocation() const {
}
const viz::FrameSinkId& CefRenderWidgetHostViewOSR::GetFrameSinkId() const {
return delegated_frame_host_->frame_sink_id();
return delegated_frame_host_
? delegated_frame_host_->frame_sink_id()
: viz::FrameSinkIdAllocator::InvalidFrameSinkId();
}
viz::FrameSinkId CefRenderWidgetHostViewOSR::GetRootFrameSinkId() {
return compositor_->frame_sink_id();
return compositor_ ? compositor_->frame_sink_id() : viz::FrameSinkId();
}
void CefRenderWidgetHostViewOSR::OnRenderFrameMetadataChangedAfterActivation() {
@@ -1061,10 +1082,12 @@ void CefRenderWidgetHostViewOSR::SendExternalBeginFrame() {
if (render_widget_host_)
render_widget_host_->ProgressFlingIfNeeded(frame_time);
compositor_->IssueExternalBeginFrame(
begin_frame_args, /* force= */ true,
base::BindOnce(&CefRenderWidgetHostViewOSR::OnFrameComplete,
weak_ptr_factory_.GetWeakPtr()));
if (compositor_) {
compositor_->IssueExternalBeginFrame(
begin_frame_args, /* force= */ true,
base::BindOnce(&CefRenderWidgetHostViewOSR::OnFrameComplete,
weak_ptr_factory_.GetWeakPtr()));
}
if (!IsPopupWidget() && popup_host_view_) {
popup_host_view_->SendExternalBeginFrame();
@@ -1074,14 +1097,24 @@ void CefRenderWidgetHostViewOSR::SendExternalBeginFrame() {
void CefRenderWidgetHostViewOSR::SendKeyEvent(
const content::NativeWebKeyboardEvent& event) {
TRACE_EVENT0("cef", "CefRenderWidgetHostViewOSR::SendKeyEvent");
if (render_widget_host_ && render_widget_host_->GetView()) {
content::RenderWidgetHostImpl* target_host = render_widget_host_;
// If there are multiple widgets on the page (such as when there are
// out-of-process iframes), pick the one that should process this event.
if (render_widget_host_ && render_widget_host_->delegate()) {
target_host = render_widget_host_->delegate()->GetFocusedRenderWidgetHost(
render_widget_host_);
}
if (target_host && target_host->GetView()) {
// Direct routing requires that events go directly to the View.
render_widget_host_->ForwardKeyboardEventWithLatencyInfo(
event, ui::LatencyInfo(event.GetType() == blink::WebInputEvent::kChar ||
event.GetType() ==
blink::WebInputEvent::kRawKeyDown
? ui::SourceEventType::KEY_PRESS
: ui::SourceEventType::OTHER));
target_host->ForwardKeyboardEventWithLatencyInfo(
event,
ui::LatencyInfo(event.GetType() == blink::WebInputEvent::Type::kChar ||
event.GetType() ==
blink::WebInputEvent::Type::kRawKeyDown
? ui::SourceEventType::KEY_PRESS
: ui::SourceEventType::OTHER));
}
}
@@ -1090,7 +1123,7 @@ void CefRenderWidgetHostViewOSR::SendMouseEvent(
TRACE_EVENT0("cef", "CefRenderWidgetHostViewOSR::SendMouseEvent");
if (!IsPopupWidget()) {
if (browser_impl_.get() &&
event.GetType() == blink::WebMouseEvent::kMouseDown) {
event.GetType() == blink::WebMouseEvent::Type::kMouseDown) {
browser_impl_->CancelContextMenu();
}
@@ -1273,8 +1306,9 @@ void CefRenderWidgetHostViewOSR::SendTouchEvent(const CefTouchEvent& event) {
latency_info);
}
bool touch_end = touch_event.GetType() == blink::WebInputEvent::kTouchEnd ||
touch_event.GetType() == blink::WebInputEvent::kTouchCancel;
bool touch_end =
touch_event.GetType() == blink::WebInputEvent::Type::kTouchEnd ||
touch_event.GetType() == blink::WebInputEvent::Type::kTouchCancel;
if (touch_end && IsPopupWidget() && parent_host_view_ &&
parent_host_view_->popup_host_view_ == this) {
@@ -1342,9 +1376,9 @@ void CefRenderWidgetHostViewOSR::OnUpdateTextInputStateCalled(
void CefRenderWidgetHostViewOSR::ProcessAckedTouchEvent(
const content::TouchEventWithLatencyInfo& touch,
content::InputEventAckState ack_result) {
blink::mojom::InputEventResultState ack_result) {
const bool event_consumed =
ack_result == content::INPUT_EVENT_ACK_STATE_CONSUMED;
ack_result == blink::mojom::InputEventResultState::kConsumed;
gesture_provider_.OnTouchEventAck(touch.event.unique_touch_event_id,
event_consumed, false);
}
@@ -1362,7 +1396,7 @@ void CefRenderWidgetHostViewOSR::OnGestureEvent(
ui::CreateWebGestureEventFromGestureEventData(gesture);
// without this check, forwarding gestures does not work!
if (web_event.GetType() == blink::WebInputEvent::kUndefined)
if (web_event.GetType() == blink::WebInputEvent::Type::kUndefined)
return;
ui::LatencyInfo latency_info = CreateLatencyInfo(web_event);
@@ -1390,8 +1424,8 @@ void CefRenderWidgetHostViewOSR::UpdateFrameRate() {
}
gfx::Size CefRenderWidgetHostViewOSR::SizeInPixels() {
return gfx::ConvertSizeToPixel(current_device_scale_factor_,
GetViewBounds().size());
return gfx::ScaleToCeiledSize(GetViewBounds().size(),
current_device_scale_factor_);
}
#if defined(OS_MACOSX)

View File

@@ -28,7 +28,7 @@
#include "content/browser/renderer_host/render_widget_host_view_base.h"
#include "content/browser/renderer_host/text_input_manager.h"
#include "content/public/common/widget_type.h"
#include "ui/base/mojom/cursor_type.mojom-shared.h"
#include "ui/base/cursor/mojom/cursor_type.mojom-shared.h"
#include "ui/compositor/compositor.h"
#include "ui/events/base_event_utils.h"
#include "ui/events/gesture_detection/filtered_gesture_provider.h"
@@ -197,8 +197,9 @@ class CefRenderWidgetHostViewOSR : public content::RenderWidgetHostViewBase,
bool did_update_state) override;
// ui::GestureProviderClient implementation.
void ProcessAckedTouchEvent(const content::TouchEventWithLatencyInfo& touch,
content::InputEventAckState ack_result) override;
void ProcessAckedTouchEvent(
const content::TouchEventWithLatencyInfo& touch,
blink::mojom::InputEventResultState ack_result) override;
void OnGestureEvent(const ui::GestureEventData& gesture) override;
bool InstallTransparency();
@@ -264,6 +265,8 @@ class CefRenderWidgetHostViewOSR : public content::RenderWidgetHostViewBase,
void OnDidUpdateVisualPropertiesComplete(
const cc::RenderFrameMetadata& metadata);
void ReleaseCompositor();
private:
void SetFrameRate();
bool SetDeviceScaleFactor();

View File

@@ -104,8 +104,6 @@ LPCWSTR ToCursorID(ui::mojom::CursorType type) {
return MAKEINTRESOURCE(IDC_VERTICALTEXT);
case ui::mojom::CursorType::kCell:
return MAKEINTRESOURCE(IDC_CELL);
case ui::mojom::CursorType::kContextMenu:
return IDC_ARROW;
case ui::mojom::CursorType::kAlias:
return MAKEINTRESOURCE(IDC_ALIAS);
case ui::mojom::CursorType::kProgress:
@@ -114,8 +112,6 @@ LPCWSTR ToCursorID(ui::mojom::CursorType type) {
return IDC_NO;
case ui::mojom::CursorType::kCopy:
return MAKEINTRESOURCE(IDC_COPYCUR);
case ui::mojom::CursorType::kNone:
return MAKEINTRESOURCE(IDC_CURSOR_NONE);
case ui::mojom::CursorType::kNotAllowed:
return IDC_NO;
case ui::mojom::CursorType::kZoomIn:
@@ -141,8 +137,11 @@ LPCWSTR ToCursorID(ui::mojom::CursorType type) {
return IDC_ARROW;
case ui::mojom::CursorType::kDndLink:
return IDC_ARROW;
case ui::mojom::CursorType::kContextMenu:
case ui::mojom::CursorType::kCustom:
break;
case ui::mojom::CursorType::kNone:
NOTIMPLEMENTED();
return IDC_ARROW;
}
NOTREACHED();
return NULL;
@@ -156,6 +155,13 @@ bool IsSystemCursorID(LPCWSTR cursor_id) {
ui::PlatformCursor CefRenderWidgetHostViewOSR::GetPlatformCursor(
ui::mojom::CursorType type) {
// Using a dark 1x1 bit bmp kNone cursor may still cause DWM to do composition
// work unnecessarily. Better to totally remove it from the screen.
// crbug.com/1069698
if (type == ui::mojom::CursorType::kNone) {
return nullptr;
}
HMODULE module_handle = NULL;
const wchar_t* cursor_id = ToCursorID(type);
if (!IsSystemCursorID(cursor_id)) {

View File

@@ -134,3 +134,5 @@ void CefVideoConsumerOSR::OnFrameCaptured(
}
void CefVideoConsumerOSR::OnStopped() {}
void CefVideoConsumerOSR::OnLog(const std::string& message) {}

View File

@@ -27,6 +27,7 @@ class CefVideoConsumerOSR : public viz::mojom::FrameSinkVideoConsumer {
mojo::PendingRemote<viz::mojom::FrameSinkVideoConsumerFrameCallbacks>
callbacks) override;
void OnStopped() override;
void OnLog(const std::string& message) override;
CefRenderWidgetHostViewOSR* const view_;
std::unique_ptr<viz::ClientFrameSinkVideoCapturer> video_capturer_;

View File

@@ -29,11 +29,7 @@ void CefWebContentsViewOSR::WebContentsCreated(
DCHECK(!web_contents_);
web_contents_ = web_contents;
auto host = web_contents_->GetRenderViewHost();
CefRenderWidgetHostViewOSR* view =
static_cast<CefRenderWidgetHostViewOSR*>(host->GetWidget()->GetView());
if (view)
view->InstallTransparency();
RenderViewReady();
}
gfx::NativeView CefWebContentsViewOSR::GetNativeView() const {
@@ -52,8 +48,6 @@ void CefWebContentsViewOSR::GetContainerBounds(gfx::Rect* out) const {
*out = GetViewBounds();
}
void CefWebContentsViewOSR::SizeContents(const gfx::Size& size) {}
void CefWebContentsViewOSR::Focus() {}
void CefWebContentsViewOSR::SetInitialFocus() {}
@@ -126,7 +120,15 @@ CefWebContentsViewOSR::CreateViewForChildWidget(
void CefWebContentsViewOSR::SetPageTitle(const base::string16& title) {}
void CefWebContentsViewOSR::RenderViewReady() {}
void CefWebContentsViewOSR::RenderViewReady() {
if (web_contents_) {
auto host = web_contents_->GetRenderViewHost();
CefRenderWidgetHostViewOSR* view =
static_cast<CefRenderWidgetHostViewOSR*>(host->GetWidget()->GetView());
if (view)
view->InstallTransparency();
}
}
void CefWebContentsViewOSR::RenderViewHostChanged(
content::RenderViewHost* old_host,

View File

@@ -36,7 +36,6 @@ class CefWebContentsViewOSR : public content::WebContentsView,
gfx::NativeView GetContentNativeView() const override;
gfx::NativeWindow GetTopLevelNativeWindow() const override;
void GetContainerBounds(gfx::Rect* out) const override;
void SizeContents(const gfx::Size& size) override;
void Focus() override;
void SetInitialFocus() override;
void StoreFocus() override;

View File

@@ -203,7 +203,7 @@ std::unique_ptr<PrefService> CreatePrefService(Profile* profile,
// From Chrome::RegisterBrowserUserPrefs.
registry->RegisterBooleanPref(prefs::kPrintPreviewUseSystemDefaultPrinter,
true);
false);
if (command_line->HasSwitch(switches::kEnablePreferenceTesting)) {
// Preferences used with unit tests.

View File

@@ -65,6 +65,11 @@ void CefPrefStore::SetValueSilently(const std::string& key,
committed_ = false;
}
void CefPrefStore::RemoveValuesByPrefixSilently(const std::string& prefix) {
prefs_.ClearWithPrefix(prefix);
committed_ = false;
}
void CefPrefStore::RemoveValue(const std::string& key, uint32_t flags) {
if (prefs_.RemoveValue(key)) {
committed_ = false;

View File

@@ -40,6 +40,7 @@ class CefPrefStore : public PersistentPrefStore {
void SetValueSilently(const std::string& key,
std::unique_ptr<base::Value> value,
uint32_t flags) override;
void RemoveValuesByPrefixSilently(const std::string& prefix) override;
void RemoveValue(const std::string& key, uint32_t flags) override;
bool ReadOnly() const override;
PrefReadError GetReadError() const override;

View File

@@ -6,6 +6,8 @@
#include "base/logging.h"
#include "printing/mojom/print.mojom.h"
CefPrintSettingsImpl::CefPrintSettingsImpl(
std::unique_ptr<printing::PrintSettings> settings,
bool read_only)
@@ -140,7 +142,8 @@ int CefPrintSettingsImpl::GetCopies() {
void CefPrintSettingsImpl::SetDuplexMode(DuplexMode mode) {
CEF_VALUE_VERIFY_RETURN_VOID(true);
mutable_value()->set_duplex_mode(static_cast<printing::DuplexMode>(mode));
mutable_value()->set_duplex_mode(
static_cast<printing::mojom::DuplexMode>(mode));
}
CefPrintSettings::DuplexMode CefPrintSettingsImpl::GetDuplexMode() {

View File

@@ -58,9 +58,11 @@ void FillInDictionaryFromPdfPrintSettings(
int request_id,
base::DictionaryValue& print_settings) {
// Fixed settings.
print_settings.SetIntKey(kSettingPrinterType, kPdfPrinter);
print_settings.SetIntKey(kSettingPrinterType,
static_cast<int>(PrinterType::kPdf));
print_settings.SetInteger(kSettingColor, GRAY);
print_settings.SetInteger(kSettingDuplexMode, SIMPLEX);
print_settings.SetInteger(kSettingDuplexMode,
static_cast<int>(mojom::DuplexMode::kSimplex));
print_settings.SetInteger(kSettingCopies, 1);
print_settings.SetBoolean(kSettingCollate, false);
print_settings.SetString(kSettingDeviceName, "");
@@ -116,10 +118,10 @@ void FillInDictionaryFromPdfPrintSettings(
print_settings.SetInteger(kSettingMarginsType, margin_type);
if (margin_type == CUSTOM_MARGINS) {
std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue);
dict->SetDouble(kSettingMarginTop, pdf_settings.margin_top);
dict->SetDouble(kSettingMarginRight, pdf_settings.margin_right);
dict->SetDouble(kSettingMarginBottom, pdf_settings.margin_bottom);
dict->SetDouble(kSettingMarginLeft, pdf_settings.margin_left);
dict->SetInteger(kSettingMarginTop, pdf_settings.margin_top);
dict->SetInteger(kSettingMarginRight, pdf_settings.margin_right);
dict->SetInteger(kSettingMarginBottom, pdf_settings.margin_bottom);
dict->SetInteger(kSettingMarginLeft, pdf_settings.margin_left);
print_settings.Set(kSettingMarginsCustom, std::move(dict));
}

View File

@@ -100,7 +100,7 @@ class ResolveHostHelper : public network::ResolveHostClientBase {
host_resolver_->ResolveHost(
net::HostPortPair::FromURL(GURL(origin.ToString())),
net::NetworkIsolationKey::Todo(), nullptr,
net::NetworkIsolationKey::CreateTransient(), nullptr,
receiver_.BindNewPipeAndPassRemote());
}
@@ -645,9 +645,15 @@ void CefRequestContextImpl::Initialize() {
// Share storage with |config_.other|.
browser_context_ =
CefBrowserContext::GetForContext(config_.other->GetBrowserContext());
DCHECK(browser_context_);
}
if (!browser_context_) {
if (!config_.is_global) {
// User-specified settings need to be normalized.
CefContext::Get()->NormalizeRequestContextSettings(&config_.settings);
}
const base::FilePath& cache_path =
base::FilePath(CefString(&config_.settings.cache_path));
if (!cache_path.empty()) {
@@ -661,17 +667,17 @@ void CefRequestContextImpl::Initialize() {
// 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 "incongento mode" context.
// be a completely isolated "incognito mode" context.
browser_context_ = new CefBrowserContext(config_.settings);
browser_context_->Initialize();
} else {
// Share the same settings as the existing context.
config_.settings = browser_context_->GetSettings();
}
// We'll disassociate from |browser_context_| on destruction.
browser_context_->AddCefRequestContext(this);
// Force our settings to match |browser_context_|.
config_.settings = browser_context_->GetSettings();
if (config_.other) {
// Clear the reference to |config_.other| after setting
// |request_context_getter_|. This is the reverse order of checks in

View File

@@ -211,7 +211,7 @@ bool CefBrowserViewImpl::HandleAccelerator(
// Previous calls to TranslateMessage can generate Char events as well as
// RawKeyDown events, even if the latter triggered an accelerator. In these
// cases, we discard the Char events.
if (event.GetType() == blink::WebInputEvent::kChar &&
if (event.GetType() == blink::WebInputEvent::Type::kChar &&
ignore_next_char_event_) {
ignore_next_char_event_ = false;
return true;
@@ -221,7 +221,7 @@ bool CefBrowserViewImpl::HandleAccelerator(
// always generate a Char event.
ignore_next_char_event_ = false;
if (event.GetType() == blink::WebInputEvent::kRawKeyDown) {
if (event.GetType() == blink::WebInputEvent::Type::kRawKeyDown) {
ui::Accelerator accelerator =
ui::GetAcceleratorFromNativeWebKeyboardEvent(event);

View File

@@ -6,6 +6,25 @@
#include "libcef/browser/thread_util.h"
namespace {
static int CefCommandIdToChromeId(cef_text_field_commands_t command_id) {
switch (command_id) {
case cef_text_field_commands_t::CEF_TFC_CUT:
return views::Textfield::kCut;
case cef_text_field_commands_t::CEF_TFC_COPY:
return views::Textfield::kCopy;
case cef_text_field_commands_t::CEF_TFC_PASTE:
return views::Textfield::kPaste;
case cef_text_field_commands_t::CEF_TFC_UNDO:
return views::Textfield::kUndo;
case cef_text_field_commands_t::CEF_TFC_DELETE:
return views::Textfield::kDelete;
case cef_text_field_commands_t::CEF_TFC_SELECT_ALL:
return views::Textfield::kSelectAll;
}
}
} // namespace
// static
CefRefPtr<CefTextfield> CefTextfield::CreateTextfield(
CefRefPtr<CefTextfieldDelegate> delegate) {
@@ -154,15 +173,16 @@ void CefTextfieldImpl::ApplyTextStyle(cef_text_style_t style,
}
}
bool CefTextfieldImpl::IsCommandEnabled(int command_id) {
bool CefTextfieldImpl::IsCommandEnabled(cef_text_field_commands_t command_id) {
CEF_REQUIRE_VALID_RETURN(false);
return root_view()->IsCommandIdEnabled(command_id);
return root_view()->IsCommandIdEnabled(CefCommandIdToChromeId(command_id));
}
void CefTextfieldImpl::ExecuteCommand(int command_id) {
void CefTextfieldImpl::ExecuteCommand(cef_text_field_commands_t command_id) {
CEF_REQUIRE_VALID_RETURN_VOID();
if (root_view()->IsCommandIdEnabled(command_id))
root_view()->ExecuteCommand(command_id, ui::EF_NONE);
if (root_view()->IsCommandIdEnabled(CefCommandIdToChromeId(command_id)))
root_view()->ExecuteCommand(CefCommandIdToChromeId(command_id),
ui::EF_NONE);
}
void CefTextfieldImpl::ClearEditHistory() {

View File

@@ -49,8 +49,8 @@ class CefTextfieldImpl
void ApplyTextStyle(cef_text_style_t style,
bool add,
const CefRange& range) override;
bool IsCommandEnabled(int command_id) override;
void ExecuteCommand(int command_id) override;
bool IsCommandEnabled(cef_text_field_commands_t command_id) override;
void ExecuteCommand(cef_text_field_commands_t command_id) override;
void ClearEditHistory() override;
void SetPlaceholderText(const CefString& text) override;
CefString GetPlaceholderText() override;

View File

@@ -114,11 +114,13 @@ const char kPluginPolicy_Block[] = "block";
const char kEnablePreferenceTesting[] = "enable-preference-testing";
// Enable print preview.
extern const char kEnablePrintPreview[] = "enable-print-preview";
const char kEnablePrintPreview[] = "enable-print-preview";
// Disable the timeout for delivering new browser info to the renderer process.
extern const char kDisableNewBrowserInfoTimeout[] =
"disable-new-browser-info-timeout";
const char kDisableNewBrowserInfoTimeout[] = "disable-new-browser-info-timeout";
// File used for logging DevTools protocol messages.
const char kDevToolsProtocolLogFile[] = "devtools-protocol-log-file";
#if defined(OS_MACOSX)
// Path to the framework directory.

View File

@@ -53,6 +53,7 @@ extern const char kPluginPolicy_Block[];
extern const char kEnablePreferenceTesting[];
extern const char kEnablePrintPreview[];
extern const char kDisableNewBrowserInfoTimeout[];
extern const char kDevToolsProtocolLogFile[];
#if defined(OS_MACOSX)
extern const char kFrameworkDirPath[];

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