mirror of
https://github.com/electron/electron.git
synced 2026-02-19 03:14:51 -05:00
Compare commits
126 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
530bf8b69a | ||
|
|
919d73b2ba | ||
|
|
9b5f40c973 | ||
|
|
4e4c7527c6 | ||
|
|
4e0931dd0b | ||
|
|
fa3680050d | ||
|
|
8181f57c5f | ||
|
|
c83176c2dc | ||
|
|
3d4d645400 | ||
|
|
90173a015e | ||
|
|
13cf7b0bc0 | ||
|
|
2ed6e590a1 | ||
|
|
fa2059438c | ||
|
|
9f3650cc66 | ||
|
|
c70a41275a | ||
|
|
8de59b982b | ||
|
|
0b0f7ed7dc | ||
|
|
36ea114ac0 | ||
|
|
4fa8a866d4 | ||
|
|
da9a917482 | ||
|
|
979dfc7903 | ||
|
|
bc218c6176 | ||
|
|
bc93eed472 | ||
|
|
cdc11e1dc5 | ||
|
|
489e40f763 | ||
|
|
4e1c358d87 | ||
|
|
6a1d3e80c8 | ||
|
|
bfd7412b64 | ||
|
|
09f9c95f8f | ||
|
|
768b4c9757 | ||
|
|
b8162becd7 | ||
|
|
47f5fe6411 | ||
|
|
5bf76ea01a | ||
|
|
b9605cc602 | ||
|
|
b98e06e38e | ||
|
|
bd6a3dd79b | ||
|
|
71cd22605e | ||
|
|
4775c8ec7b | ||
|
|
188a92970b | ||
|
|
1826bbb684 | ||
|
|
21b7dc2717 | ||
|
|
dba476e18a | ||
|
|
e31e98d927 | ||
|
|
6a25f416e0 | ||
|
|
b18a012bfd | ||
|
|
8acf577efa | ||
|
|
52c76fcf11 | ||
|
|
a568e13642 | ||
|
|
65c53cc4fa | ||
|
|
4c468a9efd | ||
|
|
a24efe268d | ||
|
|
140bd753ca | ||
|
|
5f30c61c49 | ||
|
|
5d67ec3da5 | ||
|
|
993b70ee9e | ||
|
|
a35b6d3fa8 | ||
|
|
9e7390f128 | ||
|
|
690e94a329 | ||
|
|
1ae0d41025 | ||
|
|
2dd2566fd5 | ||
|
|
972d45dc09 | ||
|
|
87c0b54788 | ||
|
|
3f4f58130e | ||
|
|
b7c49f7940 | ||
|
|
c9b9a0cd9a | ||
|
|
ee6c91d491 | ||
|
|
b35e35f3ec | ||
|
|
cbc0e46617 | ||
|
|
a6f9b6f72b | ||
|
|
df60a800b9 | ||
|
|
49dc15469d | ||
|
|
0049cee96c | ||
|
|
bbeedafc6e | ||
|
|
3d3d97920e | ||
|
|
7d164b3bcd | ||
|
|
64f32a18f5 | ||
|
|
93ce710f28 | ||
|
|
e15672e13c | ||
|
|
79764942d1 | ||
|
|
ec2418ad7d | ||
|
|
a6117abf4c | ||
|
|
c1b5a1cfc8 | ||
|
|
79d41f5f96 | ||
|
|
2dd3d9ad1b | ||
|
|
86714c0b6f | ||
|
|
fb0c56c946 | ||
|
|
75d27c0810 | ||
|
|
02e325d1ab | ||
|
|
e77b6878a9 | ||
|
|
b763d81d79 | ||
|
|
7521454161 | ||
|
|
36f0583077 | ||
|
|
96391dbb3b | ||
|
|
d5cf2e1244 | ||
|
|
9a665eb5fb | ||
|
|
6b16695ba3 | ||
|
|
ac714a1d02 | ||
|
|
e5e94fce02 | ||
|
|
f65a7983c6 | ||
|
|
d1f5d20098 | ||
|
|
2f67cd5b35 | ||
|
|
3fd0ac6d44 | ||
|
|
4a6cad7ba5 | ||
|
|
eccede0c0d | ||
|
|
9ed83e7512 | ||
|
|
b3ed83055c | ||
|
|
2360f3eb11 | ||
|
|
4175e947bb | ||
|
|
1cbcd05ab7 | ||
|
|
40c7e767ef | ||
|
|
66c5a8362a | ||
|
|
d6ba1421fa | ||
|
|
ccad8ec125 | ||
|
|
d2bff97199 | ||
|
|
46a1ce8117 | ||
|
|
042f24c5b6 | ||
|
|
c3624116ae | ||
|
|
492397b815 | ||
|
|
3a0b72e5dc | ||
|
|
914939c793 | ||
|
|
b8874913f2 | ||
|
|
dc959414a3 | ||
|
|
bcdc4435b4 | ||
|
|
303da32dd3 | ||
|
|
8fd91cc35b | ||
|
|
3001c76483 |
@@ -35,6 +35,7 @@ env-debug-build: &env-debug-build
|
||||
|
||||
env-testing-build: &env-testing-build
|
||||
GN_CONFIG: //electron/build/args/testing.gn
|
||||
CHECK_DIST_MANIFEST: '1'
|
||||
|
||||
env-release-build: &env-release-build
|
||||
GN_CONFIG: //electron/build/args/release.gn
|
||||
@@ -253,6 +254,28 @@ step-electron-dist-build: &step-electron-dist-build
|
||||
command: |
|
||||
cd src
|
||||
ninja -C out/Default electron:electron_dist_zip
|
||||
if [ "$CHECK_DIST_MANIFEST" == "1" ]; then
|
||||
if [ "`uname`" == "Darwin" ]; then
|
||||
target_os=mac
|
||||
target_cpu=x64
|
||||
if [ x"$MAS_BUILD" == x"true" ]; then
|
||||
target_os=mac_mas
|
||||
fi
|
||||
elif [ "`uname`" == "Linux" ]; then
|
||||
target_os=linux
|
||||
if [ x"$TARGET_ARCH" == x ]; then
|
||||
target_cpu=x64
|
||||
elif [ "$TARGET_ARCH" == "ia32" ]; then
|
||||
target_cpu=x86
|
||||
else
|
||||
target_cpu="$TARGET_ARCH"
|
||||
fi
|
||||
else
|
||||
echo "Unknown system: `uname`"
|
||||
exit 1
|
||||
fi
|
||||
electron/script/zip_manifests/check-zip-manifest.py out/Default/dist.zip electron/script/zip_manifests/dist_zip.$target_os.$target_cpu.manifest
|
||||
fi
|
||||
|
||||
step-electron-dist-store: &step-electron-dist-store
|
||||
store_artifacts:
|
||||
@@ -401,25 +424,13 @@ step-mksnapshot-store: &step-mksnapshot-store
|
||||
path: src/out/Default/mksnapshot.zip
|
||||
destination: mksnapshot.zip
|
||||
|
||||
step-maybe-build-dump-syms: &step-maybe-build-dump-syms
|
||||
run:
|
||||
name: Build dump_syms binary
|
||||
command: |
|
||||
if [ "$GENERATE_SYMBOLS" == "true" ]; then
|
||||
cd src
|
||||
# Build needed dump_syms executable
|
||||
ninja -C out/Default third_party/breakpad:dump_syms
|
||||
fi
|
||||
|
||||
step-maybe-generate-breakpad-symbols: &step-maybe-generate-breakpad-symbols
|
||||
run:
|
||||
name: Generate breakpad symbols
|
||||
command: |
|
||||
if [ "$GENERATE_SYMBOLS" == "true" ]; then
|
||||
cd src
|
||||
export BUILD_PATH="$PWD/out/Default"
|
||||
export DEST_PATH="$BUILD_PATH/breakpad_symbols"
|
||||
electron/script/dump-symbols.py -b $BUILD_PATH -d $DEST_PATH -v
|
||||
ninja -C out/Default electron:electron_symbols
|
||||
fi
|
||||
|
||||
step-maybe-zip-symbols: &step-maybe-zip-symbols
|
||||
@@ -490,6 +501,39 @@ step-maybe-generate-typescript-defs: &step-maybe-generate-typescript-defs
|
||||
fi
|
||||
|
||||
# Lists of steps.
|
||||
steps-lint: &steps-lint
|
||||
steps:
|
||||
- *step-checkout-electron
|
||||
- run:
|
||||
name: Setup third_party Depot Tools
|
||||
command: |
|
||||
# "depot_tools" has to be checkout into "//third_party/depot_tools" so pylint.py can a "pylintrc" file.
|
||||
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git src/third_party/depot_tools
|
||||
echo 'export PATH="$PATH:'"$PWD"'/src/third_party/depot_tools"' >> $BASH_ENV
|
||||
- run:
|
||||
name: Download GN Binary
|
||||
command: |
|
||||
chromium_revision="$(grep -A1 chromium_version src/electron/DEPS | tr -d '\n' | cut -d\' -f4)"
|
||||
buildtools_revision="$(curl -sL "https://chromium.googlesource.com/chromium/src/+/${chromium_revision}/DEPS?format=TEXT" | base64 -d | grep buildtools_revision -A1 | tr -d '\n' | cut -d\' -f4)"
|
||||
|
||||
git clone https://chromium.googlesource.com/chromium/buildtools "buildtools"
|
||||
(cd "buildtools" && git checkout "$buildtools_revision")
|
||||
echo 'export CHROMIUM_BUILDTOOLS_PATH="'"$PWD"'/buildtools"' >> $BASH_ENV
|
||||
|
||||
download_from_google_storage --bucket chromium-gn -s "buildtools/linux64/gn.sha1"
|
||||
- run:
|
||||
name: Run Lint
|
||||
command: |
|
||||
# gn.py tries to find a gclient root folder starting from the current dir.
|
||||
# When it fails and returns "None" path, the whole script fails. Let's "fix" it.
|
||||
touch .gclient
|
||||
# Another option would be to checkout "buildtools" inside the Electron checkout,
|
||||
# but then we would lint its contents (at least gn format), and it doesn't pass it.
|
||||
|
||||
cd src/electron
|
||||
npm install
|
||||
npm run lint
|
||||
|
||||
steps-checkout: &steps-checkout
|
||||
steps:
|
||||
- *step-checkout-electron
|
||||
@@ -594,7 +638,6 @@ steps-electron-build-for-tests: &steps-electron-build-for-tests
|
||||
# Save all data needed for a further tests run.
|
||||
- *step-persist-data-for-tests
|
||||
|
||||
- *step-maybe-build-dump-syms
|
||||
- *step-maybe-generate-breakpad-symbols
|
||||
- *step-maybe-zip-symbols
|
||||
|
||||
@@ -619,7 +662,6 @@ steps-electron-build-for-publish: &steps-electron-build-for-publish
|
||||
- *step-maybe-electron-dist-strip
|
||||
- *step-electron-dist-build
|
||||
- *step-electron-dist-store
|
||||
- *step-maybe-build-dump-syms
|
||||
- *step-maybe-generate-breakpad-symbols
|
||||
- *step-maybe-zip-symbols
|
||||
|
||||
@@ -776,6 +818,13 @@ chromium-upgrade-branches: &chromium-upgrade-branches
|
||||
# List of all jobs.
|
||||
version: 2
|
||||
jobs:
|
||||
# Layer 0: Lint. Standalone.
|
||||
lint:
|
||||
<<: *machine-linux-medium
|
||||
environment:
|
||||
<<: *env-linux-medium
|
||||
<<: *steps-lint
|
||||
|
||||
# Layer 1: Checkout.
|
||||
linux-checkout:
|
||||
<<: *machine-linux-2xlarge
|
||||
@@ -1300,6 +1349,10 @@ jobs:
|
||||
|
||||
workflows:
|
||||
version: 2
|
||||
lint:
|
||||
jobs:
|
||||
- lint
|
||||
|
||||
build-linux:
|
||||
jobs:
|
||||
- linux-checkout
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# These env vars are only necessary for creating Electron releases.
|
||||
# See docs/development/releasing.md
|
||||
|
||||
APPVEYOR_TOKEN=
|
||||
APPVEYOR_CLOUD_TOKEN=
|
||||
CIRCLE_TOKEN=
|
||||
ELECTRON_GITHUB_TOKEN=
|
||||
VSTS_TOKEN=
|
||||
33
.github/CODEOWNERS
vendored
33
.github/CODEOWNERS
vendored
@@ -3,19 +3,24 @@
|
||||
# https://help.github.com/articles/about-codeowners
|
||||
# https://git-scm.com/docs/gitignore
|
||||
|
||||
# Everything that falls through the cracks:
|
||||
* @electron/reviewers
|
||||
# Most stuff in here is owned by the Community & Safety WG...
|
||||
/.github/* @electron/wg-community
|
||||
|
||||
# filename patterns
|
||||
*browser_view* @electron/browserview
|
||||
*notification* @electron/notifications
|
||||
*pdf* @electron/printing
|
||||
*printing* @electron/printing
|
||||
*updater* @electron/updater
|
||||
# ...except the Admin WG maintains this file.
|
||||
/.github/CODEOWNERS @electron/wg-admin
|
||||
|
||||
# directories
|
||||
/.github/ @electron/electrocats
|
||||
/default_app/ @electron/docs
|
||||
/docs/ @electron/docs
|
||||
/docs-translations/ @electron/i18n
|
||||
/npm/ @electron/electrocats
|
||||
# Upgrades WG
|
||||
/patches/ @electron/wg-upgrades
|
||||
|
||||
# Releases WG
|
||||
/npm/ @electron/wg-releases
|
||||
/script/release-notes @electron/wg-releases
|
||||
/script/prepare-release.js @electron/wg-releases
|
||||
/script/bump-version.js @electron/wg-releases
|
||||
/script/ci-release-build.js @electron/wg-releases
|
||||
/script/release.js @electron/wg-releases
|
||||
/script/upload-to-github.js @electron/wg-releases
|
||||
/script/release-artifact-cleanup.js @electron/wg-releases
|
||||
/script/get-last-major-for-master.js @electron/wg-releases
|
||||
/script/find-release.js @electron/wg-releases
|
||||
/script/download-circleci-artifacts.js @electron/wg-releases
|
||||
@@ -1,31 +0,0 @@
|
||||
pool:
|
||||
vmImage: 'Ubuntu 16.04'
|
||||
|
||||
steps:
|
||||
- bash: |
|
||||
# "depot_tools" has to be checkout into "//third_party/depot_tools" so pylint.py can a "pylintrc" file.
|
||||
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git "${AGENT_BUILDDIRECTORY}/third_party/depot_tools"
|
||||
echo "##vso[task.setvariable variable=PATH]$PATH:${AGENT_BUILDDIRECTORY}/third_party/depot_tools"
|
||||
displayName: Setup Depot Tools
|
||||
|
||||
- bash: |
|
||||
chromium_revision="$(grep -A1 chromium_version DEPS | tr -d '\n' | cut -d\' -f4)"
|
||||
buildtools_revision="$(curl -sL "https://chromium.googlesource.com/chromium/src/+/${chromium_revision}/DEPS?format=TEXT" | base64 -d | grep buildtools_revision -A1 | tr -d '\n' | cut -d\' -f4)"
|
||||
|
||||
git clone https://chromium.googlesource.com/chromium/buildtools "${AGENT_TEMPDIRECTORY}/buildtools"
|
||||
(cd "${AGENT_TEMPDIRECTORY}/buildtools" && git checkout "$buildtools_revision")
|
||||
echo "##vso[task.setvariable variable=CHROMIUM_BUILDTOOLS_PATH]$AGENT_TEMPDIRECTORY/buildtools"
|
||||
|
||||
download_from_google_storage --bucket chromium-gn -s "${AGENT_TEMPDIRECTORY}/buildtools/linux64/gn.sha1"
|
||||
displayName: Download gn binary
|
||||
|
||||
- bash: |
|
||||
# gn.py tries to find a gclient root folder starting from the current dir.
|
||||
# When it fails and returns "None" path, the whole script fails. Let's "fix" it.
|
||||
touch .gclient
|
||||
# Another option would be to checkout "buildtools" inside the Electron checkout,
|
||||
# but then we would lint its contents (at least gn format), and it doesn't pass it.
|
||||
|
||||
npm install
|
||||
npm run lint
|
||||
displayName: Run Lint
|
||||
100
BUILD.gn
100
BUILD.gn
@@ -13,6 +13,7 @@ import("//tools/grit/grit_rule.gni")
|
||||
import("//tools/grit/repack.gni")
|
||||
import("//tools/v8_context_snapshot/v8_context_snapshot.gni")
|
||||
import("//v8/snapshot_toolchain.gni")
|
||||
import("build/extract_symbols.gni")
|
||||
|
||||
if (is_mac) {
|
||||
import("//build/config/mac/rules.gni")
|
||||
@@ -478,6 +479,7 @@ if (is_mac) {
|
||||
electron_helper_name = "$electron_product_name Helper"
|
||||
electron_login_helper_name = "$electron_product_name Login Helper"
|
||||
electron_framework_version = "A"
|
||||
electron_version = read_file("VERSION", "trim string")
|
||||
|
||||
mac_xib_bundle_data("electron_xibs") {
|
||||
sources = [
|
||||
@@ -560,7 +562,6 @@ if (is_mac) {
|
||||
}
|
||||
info_plist = "atom/common/resources/mac/Info.plist"
|
||||
|
||||
electron_version = read_file("VERSION", "trim string")
|
||||
extra_substitutions = [
|
||||
"ATOM_BUNDLE_ID=$electron_mac_bundle_id.framework",
|
||||
"ELECTRON_VERSION=$electron_version",
|
||||
@@ -716,6 +717,56 @@ if (is_mac) {
|
||||
"@executable_path/../Frameworks",
|
||||
]
|
||||
}
|
||||
|
||||
if (enable_dsyms) {
|
||||
extract_symbols("electron_framework_syms") {
|
||||
binary = "$root_out_dir/$electron_framework_name.framework/Versions/$electron_framework_version/$electron_framework_name"
|
||||
symbol_dir = "$root_out_dir/breakpad_symbols"
|
||||
dsym_file = "$root_out_dir/$electron_framework_name.dSYM/Contents/Resources/DWARF/$electron_framework_name"
|
||||
deps = [
|
||||
":electron_framework",
|
||||
]
|
||||
}
|
||||
|
||||
extract_symbols("electron_helper_syms") {
|
||||
binary = "$root_out_dir/$electron_helper_name.app/Contents/MacOS/$electron_helper_name"
|
||||
symbol_dir = "$root_out_dir/breakpad_symbols"
|
||||
dsym_file = "$root_out_dir/$electron_helper_name.dSYM/Contents/Resources/DWARF/$electron_helper_name"
|
||||
deps = [
|
||||
":electron_helper_app",
|
||||
]
|
||||
}
|
||||
|
||||
extract_symbols("electron_app_syms") {
|
||||
binary = "$root_out_dir/$electron_product_name.app/Contents/MacOS/$electron_product_name"
|
||||
symbol_dir = "$root_out_dir/breakpad_symbols"
|
||||
dsym_file = "$root_out_dir/$electron_product_name.dSYM/Contents/Resources/DWARF/$electron_product_name"
|
||||
deps = [
|
||||
":electron_app",
|
||||
]
|
||||
}
|
||||
|
||||
extract_symbols("crashpad_handler_syms") {
|
||||
binary = "$root_out_dir/crashpad_handler"
|
||||
symbol_dir = "$root_out_dir/breakpad_symbols"
|
||||
dsym_file = "$root_out_dir/crashpad_handler.dSYM/Contents/Resources/DWARF/crashpad_handler"
|
||||
deps = [
|
||||
"//third_party/crashpad/crashpad/handler:crashpad_handler",
|
||||
]
|
||||
}
|
||||
|
||||
group("electron_symbols") {
|
||||
deps = [
|
||||
":crashpad_handler_syms",
|
||||
":electron_app_syms",
|
||||
":electron_framework_syms",
|
||||
":electron_helper_syms",
|
||||
]
|
||||
}
|
||||
} else {
|
||||
group("electron_symbols") {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
windows_manifest("electron_app_manifest") {
|
||||
sources = [
|
||||
@@ -813,6 +864,53 @@ if (is_mac) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (is_official_build) {
|
||||
if (is_linux) {
|
||||
_target_executable_suffix = ""
|
||||
_target_shared_library_suffix = ".so"
|
||||
} else if (is_win) {
|
||||
_target_executable_suffix = ".exe"
|
||||
_target_shared_library_suffix = ".dll"
|
||||
}
|
||||
|
||||
extract_symbols("electron_app_symbols") {
|
||||
binary = "$root_out_dir/$electron_project_name$_target_executable_suffix"
|
||||
symbol_dir = "$root_out_dir/breakpad_symbols"
|
||||
deps = [
|
||||
":electron_app",
|
||||
]
|
||||
}
|
||||
|
||||
extract_symbols("swiftshader_egl_symbols") {
|
||||
binary = "$root_out_dir/swiftshader/libEGL$_target_shared_library_suffix"
|
||||
symbol_dir = "$root_out_dir/breakpad_symbols"
|
||||
deps = [
|
||||
"//third_party/swiftshader/src/OpenGL/libEGL:swiftshader_libEGL",
|
||||
]
|
||||
}
|
||||
|
||||
extract_symbols("swiftshader_gles_symbols") {
|
||||
binary =
|
||||
"$root_out_dir/swiftshader/libGLESv2$_target_shared_library_suffix"
|
||||
symbol_dir = "$root_out_dir/breakpad_symbols"
|
||||
deps = [
|
||||
"//third_party/swiftshader/src/OpenGL/libGLESv2:swiftshader_libGLESv2",
|
||||
]
|
||||
}
|
||||
|
||||
group("electron_symbols") {
|
||||
deps = [
|
||||
":electron_app_symbols",
|
||||
]
|
||||
if (target_cpu == "x86" || target_cpu == "x64") {
|
||||
deps += [
|
||||
":swiftshader_egl_symbols",
|
||||
":swiftshader_gles_symbols",
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
group("electron_tests") {
|
||||
|
||||
@@ -16,7 +16,7 @@ RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \
|
||||
locales \
|
||||
lsb-release \
|
||||
nano \
|
||||
python-dbusmock \
|
||||
python-dbus \
|
||||
python-pip \
|
||||
python-setuptools \
|
||||
sudo \
|
||||
@@ -33,6 +33,9 @@ RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - \
|
||||
# crcmod is required by gsutil, which is used for filling the gclient git cache
|
||||
RUN pip install -U crcmod
|
||||
|
||||
# dbusmock is needed for Electron tests
|
||||
RUN pip install python-dbusmock
|
||||
|
||||
RUN mkdir /tmp/workspace
|
||||
RUN chown builduser:builduser /tmp/workspace
|
||||
|
||||
|
||||
@@ -32,6 +32,9 @@ environment:
|
||||
ELECTRON_OUT_DIR: Default
|
||||
build_script:
|
||||
- ps: >-
|
||||
if($env:APPVEYOR_PROJECT_NAME -eq "electron-woa-testing") {
|
||||
Write-warning "WOA builds not supported on older versions of Electron"; Exit-AppveyorBuild
|
||||
}
|
||||
if(($env:APPVEYOR_PULL_REQUEST_HEAD_REPO_NAME -split "/")[0] -eq ($env:APPVEYOR_REPO_NAME -split "/")[0]) {
|
||||
Write-warning "Skipping PR build for branch"; Exit-AppveyorBuild
|
||||
}
|
||||
@@ -68,14 +71,16 @@ build_script:
|
||||
- appveyor PushArtifact out/ffmpeg/ffmpeg.zip
|
||||
- ps: >-
|
||||
if ($env:GN_CONFIG -eq 'release') {
|
||||
ninja -C out/Default third_party/breakpad:dump_syms
|
||||
# Needed for msdia140.dll on 64-bit windows
|
||||
$env:Path += ";$pwd\third_party\llvm-build\Release+Asserts\bin"
|
||||
ninja -C out/Default electron:electron_symbols
|
||||
}
|
||||
- if "%GN_CONFIG%"=="release" ( python electron\script\dump-symbols.py -d %cd%\out\Default\breakpad_symbols -v)
|
||||
- ps: >-
|
||||
if ($env:GN_CONFIG -eq 'release') {
|
||||
python electron\script\zip-symbols.py
|
||||
appveyor PushArtifact out/Default/symbols.zip
|
||||
}
|
||||
- python electron/script/zip_manifests/check-zip-manifest.py out/Default/dist.zip electron/script/zip_manifests/dist_zip.win.%TARGET_ARCH%.manifest
|
||||
test_script:
|
||||
- ps: >-
|
||||
if ((-Not (Test-Path Env:\ELECTRON_RELEASE)) -And ($env:GN_CONFIG -in "testing", "release")) {
|
||||
|
||||
@@ -5,8 +5,10 @@
|
||||
#include "atom/app/atom_content_client.h"
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/common/atom_version.h"
|
||||
#include "atom/common/chrome_version.h"
|
||||
#include "atom/common/options_switches.h"
|
||||
@@ -14,8 +16,10 @@
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/strings/string_split.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/strings/stringprintf.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "content/public/common/content_constants.h"
|
||||
#include "content/public/common/content_switches.h"
|
||||
#include "content/public/common/pepper_plugin_info.h"
|
||||
#include "content/public/common/user_agent.h"
|
||||
#include "electron/buildflags/buildflags.h"
|
||||
@@ -163,14 +167,40 @@ void ComputeBuiltInPlugins(std::vector<content::PepperPluginInfo>* plugins) {
|
||||
#endif // BUILDFLAG(ENABLE_PDF_VIEWER)
|
||||
}
|
||||
|
||||
void ConvertStringWithSeparatorToVector(std::vector<std::string>* vec,
|
||||
const char* separator,
|
||||
const char* cmd_switch) {
|
||||
void AppendDelimitedSwitchToVector(const base::StringPiece cmd_switch,
|
||||
std::vector<std::string>* append_me) {
|
||||
auto* command_line = base::CommandLine::ForCurrentProcess();
|
||||
auto string_with_separator = command_line->GetSwitchValueASCII(cmd_switch);
|
||||
if (!string_with_separator.empty())
|
||||
*vec = base::SplitString(string_with_separator, separator,
|
||||
base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
|
||||
auto switch_value = command_line->GetSwitchValueASCII(cmd_switch);
|
||||
if (!switch_value.empty()) {
|
||||
constexpr base::StringPiece delimiter(",", 1);
|
||||
auto tokens =
|
||||
base::SplitString(switch_value, delimiter, base::TRIM_WHITESPACE,
|
||||
base::SPLIT_WANT_NONEMPTY);
|
||||
append_me->reserve(append_me->size() + tokens.size());
|
||||
std::move(std::begin(tokens), std::end(tokens),
|
||||
std::back_inserter(*append_me));
|
||||
}
|
||||
}
|
||||
|
||||
std::string RemoveWhitespace(const std::string& str) {
|
||||
std::string trimmed;
|
||||
if (base::RemoveChars(str, " ", &trimmed))
|
||||
return trimmed;
|
||||
else
|
||||
return str;
|
||||
}
|
||||
|
||||
bool IsBrowserProcess() {
|
||||
const base::CommandLine* command_line =
|
||||
base::CommandLine::ForCurrentProcess();
|
||||
std::string process_type =
|
||||
command_line->GetSwitchValueASCII(::switches::kProcessType);
|
||||
return process_type.empty();
|
||||
}
|
||||
|
||||
std::string BuildDefaultUserAgent() {
|
||||
return "Chrome/" CHROME_VERSION_STRING " " ATOM_PRODUCT_NAME
|
||||
"/" ATOM_VERSION_STRING;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@@ -184,9 +214,35 @@ std::string AtomContentClient::GetProduct() const {
|
||||
}
|
||||
|
||||
std::string AtomContentClient::GetUserAgent() const {
|
||||
return content::BuildUserAgentFromProduct("Chrome/" CHROME_VERSION_STRING
|
||||
" " ATOM_PRODUCT_NAME
|
||||
"/" ATOM_VERSION_STRING);
|
||||
if (IsBrowserProcess()) {
|
||||
if (user_agent_override_.empty()) {
|
||||
auto* browser = Browser::Get();
|
||||
std::string name = RemoveWhitespace(browser->GetName());
|
||||
std::string user_agent;
|
||||
if (name == ATOM_PRODUCT_NAME) {
|
||||
user_agent = BuildDefaultUserAgent();
|
||||
} else {
|
||||
user_agent = base::StringPrintf(
|
||||
"%s/%s Chrome/%s " ATOM_PRODUCT_NAME "/" ATOM_VERSION_STRING,
|
||||
name.c_str(), browser->GetVersion().c_str(), CHROME_VERSION_STRING);
|
||||
}
|
||||
return content::BuildUserAgentFromProduct(user_agent);
|
||||
}
|
||||
return user_agent_override_;
|
||||
}
|
||||
// In a renderer process the user agent should be provided on the CLI
|
||||
// If it's not we just fallback to the default one, this should never happen
|
||||
// but we want to handle it gracefully
|
||||
const base::CommandLine* command_line =
|
||||
base::CommandLine::ForCurrentProcess();
|
||||
std::string cli_user_agent = command_line->GetSwitchValueASCII("user-agent");
|
||||
if (cli_user_agent.empty())
|
||||
return BuildDefaultUserAgent();
|
||||
return cli_user_agent;
|
||||
}
|
||||
|
||||
void AtomContentClient::SetUserAgent(const std::string& user_agent) {
|
||||
user_agent_override_ = user_agent;
|
||||
}
|
||||
|
||||
base::string16 AtomContentClient::GetLocalizedString(int message_id) const {
|
||||
@@ -194,18 +250,13 @@ base::string16 AtomContentClient::GetLocalizedString(int message_id) const {
|
||||
}
|
||||
|
||||
void AtomContentClient::AddAdditionalSchemes(Schemes* schemes) {
|
||||
AppendDelimitedSwitchToVector(switches::kRegisterServiceWorkerSchemes,
|
||||
&schemes->service_worker_schemes);
|
||||
AppendDelimitedSwitchToVector(switches::kSecureSchemes,
|
||||
&schemes->secure_schemes);
|
||||
|
||||
schemes->standard_schemes.push_back("chrome-extension");
|
||||
|
||||
std::vector<std::string> splited;
|
||||
ConvertStringWithSeparatorToVector(&splited, ",",
|
||||
switches::kRegisterServiceWorkerSchemes);
|
||||
for (const std::string& scheme : splited)
|
||||
schemes->service_worker_schemes.push_back(scheme);
|
||||
schemes->service_worker_schemes.push_back(url::kFileScheme);
|
||||
|
||||
ConvertStringWithSeparatorToVector(&splited, ",", switches::kSecureSchemes);
|
||||
for (const std::string& scheme : splited)
|
||||
schemes->secure_schemes.push_back(scheme);
|
||||
}
|
||||
|
||||
void AtomContentClient::AddPepperPlugins(
|
||||
|
||||
@@ -18,10 +18,12 @@ class AtomContentClient : public brightray::ContentClient {
|
||||
AtomContentClient();
|
||||
~AtomContentClient() override;
|
||||
|
||||
std::string GetUserAgent() const override;
|
||||
void SetUserAgent(const std::string& user_agent);
|
||||
|
||||
protected:
|
||||
// content::ContentClient:
|
||||
std::string GetProduct() const override;
|
||||
std::string GetUserAgent() const override;
|
||||
base::string16 GetLocalizedString(int message_id) const override;
|
||||
void AddAdditionalSchemes(Schemes* schemes) override;
|
||||
void AddPepperPlugins(
|
||||
@@ -31,6 +33,8 @@ class AtomContentClient : public brightray::ContentClient {
|
||||
std::vector<media::CdmHostFilePath>* cdm_host_file_paths) override;
|
||||
|
||||
private:
|
||||
std::string user_agent_override_ = "";
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomContentClient);
|
||||
};
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/app/atom_content_client.h"
|
||||
#include "atom/browser/api/atom_api_menu.h"
|
||||
#include "atom/browser/api/atom_api_session.h"
|
||||
#include "atom/browser/api/atom_api_web_contents.h"
|
||||
@@ -43,6 +44,7 @@
|
||||
#include "content/public/browser/client_certificate_delegate.h"
|
||||
#include "content/public/browser/gpu_data_manager.h"
|
||||
#include "content/public/browser/render_frame_host.h"
|
||||
#include "content/public/common/content_client.h"
|
||||
#include "content/public/common/content_switches.h"
|
||||
#include "media/audio/audio_manager.h"
|
||||
#include "native_mate/object_template_builder.h"
|
||||
@@ -1236,6 +1238,18 @@ void App::EnableMixedSandbox(mate::Arguments* args) {
|
||||
command_line->AppendSwitch(switches::kEnableMixedSandbox);
|
||||
}
|
||||
|
||||
void App::SetUserAgentFallback(const std::string& user_agent) {
|
||||
AtomContentClient* client =
|
||||
static_cast<AtomContentClient*>(content::GetContentClient());
|
||||
client->SetUserAgent(user_agent);
|
||||
}
|
||||
|
||||
std::string App::GetUserAgentFallback() {
|
||||
AtomContentClient* client =
|
||||
static_cast<AtomContentClient*>(content::GetContentClient());
|
||||
return client->GetUserAgent();
|
||||
}
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
bool App::MoveToApplicationsFolder(mate::Arguments* args) {
|
||||
return ui::cocoa::AtomBundleMover::Move(args);
|
||||
@@ -1342,6 +1356,8 @@ void App::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("startAccessingSecurityScopedResource",
|
||||
&App::StartAccessingSecurityScopedResource)
|
||||
#endif
|
||||
.SetProperty("userAgentFallback", &App::GetUserAgentFallback,
|
||||
&App::SetUserAgentFallback)
|
||||
.SetMethod("enableSandbox", &App::EnableSandbox)
|
||||
.SetMethod("enableMixedSandbox", &App::EnableMixedSandbox);
|
||||
}
|
||||
|
||||
@@ -205,6 +205,8 @@ class App : public AtomBrowserClient::Delegate,
|
||||
const std::string& info_type);
|
||||
void EnableSandbox(mate::Arguments* args);
|
||||
void EnableMixedSandbox(mate::Arguments* args);
|
||||
void SetUserAgentFallback(const std::string& user_agent);
|
||||
std::string GetUserAgentFallback();
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
bool MoveToApplicationsFolder(mate::Arguments* args);
|
||||
|
||||
@@ -66,7 +66,7 @@ BrowserWindow::BrowserWindow(v8::Isolate* isolate,
|
||||
}
|
||||
|
||||
web_contents_.Reset(isolate, web_contents.ToV8());
|
||||
api_web_contents_ = web_contents.get();
|
||||
api_web_contents_ = web_contents->GetWeakPtr();
|
||||
api_web_contents_->AddObserver(this);
|
||||
Observe(api_web_contents_->web_contents());
|
||||
|
||||
@@ -88,8 +88,7 @@ BrowserWindow::BrowserWindow(v8::Isolate* isolate,
|
||||
InitWith(isolate, wrapper);
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
if (!window()->has_frame())
|
||||
OverrideNSWindowContentView(web_contents->managed_web_contents());
|
||||
OverrideNSWindowContentView(web_contents->managed_web_contents());
|
||||
#endif
|
||||
|
||||
// Init window after everything has been setup.
|
||||
@@ -97,7 +96,9 @@ BrowserWindow::BrowserWindow(v8::Isolate* isolate,
|
||||
}
|
||||
|
||||
BrowserWindow::~BrowserWindow() {
|
||||
api_web_contents_->RemoveObserver(this);
|
||||
// FIXME This is a hack rather than a proper fix preventing shutdown crashes.
|
||||
if (api_web_contents_)
|
||||
api_web_contents_->RemoveObserver(this);
|
||||
// Note that the OnWindowClosed will not be called after the destructor runs,
|
||||
// since the window object is managed by the TopLevelWindow class.
|
||||
if (web_contents())
|
||||
|
||||
@@ -113,7 +113,7 @@ class BrowserWindow : public TopLevelWindow,
|
||||
#endif
|
||||
|
||||
v8::Global<v8::Value> web_contents_;
|
||||
api::WebContents* api_web_contents_;
|
||||
base::WeakPtr<api::WebContents> api_web_contents_;
|
||||
|
||||
base::WeakPtrFactory<BrowserWindow> weak_factory_;
|
||||
|
||||
|
||||
@@ -52,6 +52,19 @@ std::vector<std::string> MetricsToArray(uint32_t metrics) {
|
||||
return array;
|
||||
}
|
||||
|
||||
void DelayEmit(Screen* screen,
|
||||
const base::StringPiece& name,
|
||||
const display::Display& display) {
|
||||
screen->Emit(name, display);
|
||||
}
|
||||
|
||||
void DelayEmitWithMetrics(Screen* screen,
|
||||
const base::StringPiece& name,
|
||||
const display::Display& display,
|
||||
const std::vector<std::string>& metrics) {
|
||||
screen->Emit(name, display, metrics);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
Screen::Screen(v8::Isolate* isolate, display::Screen* screen)
|
||||
@@ -101,16 +114,23 @@ static gfx::Rect DIPToScreenRect(atom::NativeWindow* window,
|
||||
#endif
|
||||
|
||||
void Screen::OnDisplayAdded(const display::Display& new_display) {
|
||||
Emit("display-added", new_display);
|
||||
base::ThreadTaskRunnerHandle::Get()->PostNonNestableTask(
|
||||
FROM_HERE, base::Bind(&DelayEmit, base::Unretained(this), "display-added",
|
||||
new_display));
|
||||
}
|
||||
|
||||
void Screen::OnDisplayRemoved(const display::Display& old_display) {
|
||||
Emit("display-removed", old_display);
|
||||
base::ThreadTaskRunnerHandle::Get()->PostNonNestableTask(
|
||||
FROM_HERE, base::Bind(&DelayEmit, base::Unretained(this),
|
||||
"display-removed", old_display));
|
||||
}
|
||||
|
||||
void Screen::OnDisplayMetricsChanged(const display::Display& display,
|
||||
uint32_t changed_metrics) {
|
||||
Emit("display-metrics-changed", display, MetricsToArray(changed_metrics));
|
||||
base::ThreadTaskRunnerHandle::Get()->PostNonNestableTask(
|
||||
FROM_HERE, base::Bind(&DelayEmitWithMetrics, base::Unretained(this),
|
||||
"display-metrics-changed", display,
|
||||
MetricsToArray(changed_metrics)));
|
||||
}
|
||||
|
||||
// static
|
||||
|
||||
@@ -419,6 +419,17 @@ void Session::ResolveProxy(
|
||||
browser_context_->GetResolveProxyHelper()->ResolveProxy(url, callback);
|
||||
}
|
||||
|
||||
void Session::GetCacheSize(const net::CompletionCallback& callback) {
|
||||
content::BrowserContext::GetDefaultStoragePartition(browser_context_.get())
|
||||
->GetNetworkContext()
|
||||
->ComputeHttpCacheSize(
|
||||
base::Time(), base::Time::Max(),
|
||||
base::BindOnce(
|
||||
[](const net::CompletionCallback& cb, bool is_upper_bound,
|
||||
int64_t size_or_error) { cb.Run(size_or_error); },
|
||||
callback));
|
||||
}
|
||||
|
||||
template <Session::CacheAction action>
|
||||
void Session::DoCacheAction(const net::CompletionCallback& callback) {
|
||||
BrowserThread::PostTask(
|
||||
@@ -747,7 +758,7 @@ void Session::BuildPrototype(v8::Isolate* isolate,
|
||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
.MakeDestroyable()
|
||||
.SetMethod("resolveProxy", &Session::ResolveProxy)
|
||||
.SetMethod("getCacheSize", &Session::DoCacheAction<CacheAction::STATS>)
|
||||
.SetMethod("getCacheSize", &Session::GetCacheSize)
|
||||
.SetMethod("clearCache", &Session::DoCacheAction<CacheAction::CLEAR>)
|
||||
.SetMethod("clearStorageData", &Session::ClearStorageData)
|
||||
.SetMethod("flushStorageData", &Session::FlushStorageData)
|
||||
|
||||
@@ -66,6 +66,7 @@ class Session : public mate::TrackableObject<Session>,
|
||||
const ResolveProxyHelper::ResolveProxyCallback& callback);
|
||||
template <CacheAction action>
|
||||
void DoCacheAction(const net::CompletionCallback& callback);
|
||||
void GetCacheSize(const net::CompletionCallback& callback);
|
||||
void ClearStorageData(mate::Arguments* args);
|
||||
void FlushStorageData();
|
||||
void SetProxy(const mate::Dictionary& options, const base::Closure& callback);
|
||||
|
||||
@@ -54,11 +54,11 @@ struct Converter<NSAppearance*> {
|
||||
return v8::Null(isolate);
|
||||
}
|
||||
|
||||
if (val.name == NSAppearanceNameAqua) {
|
||||
if ([val.name isEqualToString:NSAppearanceNameAqua]) {
|
||||
return mate::ConvertToV8(isolate, "light");
|
||||
}
|
||||
if (@available(macOS 10.14, *)) {
|
||||
if (val.name == NSAppearanceNameDarkAqua) {
|
||||
if ([val.name isEqualToString:NSAppearanceNameDarkAqua]) {
|
||||
return mate::ConvertToV8(isolate, "dark");
|
||||
}
|
||||
}
|
||||
@@ -439,6 +439,10 @@ void SystemPreferences::RemoveUserDefault(const std::string& name) {
|
||||
}
|
||||
|
||||
bool SystemPreferences::IsDarkMode() {
|
||||
if (@available(macOS 10.14, *)) {
|
||||
return [[NSApplication sharedApplication].effectiveAppearance.name
|
||||
isEqualToString:NSAppearanceNameDarkAqua];
|
||||
}
|
||||
NSString* mode = [[NSUserDefaults standardUserDefaults]
|
||||
stringForKey:@"AppleInterfaceStyle"];
|
||||
return [mode isEqualToString:@"Dark"];
|
||||
|
||||
@@ -192,7 +192,7 @@ void Tray::DisplayBalloon(mate::Arguments* args,
|
||||
|
||||
#if defined(OS_WIN)
|
||||
tray_icon_->DisplayBalloon(
|
||||
icon.IsEmpty() ? NULL : icon->GetHICON(GetSystemMetrics(SM_CXSMICON)),
|
||||
icon.IsEmpty() ? NULL : icon->GetHICON(GetSystemMetrics(SM_CXICON)),
|
||||
title, content);
|
||||
#else
|
||||
tray_icon_->DisplayBalloon(icon.IsEmpty() ? gfx::Image() : icon->image(),
|
||||
|
||||
@@ -289,7 +289,9 @@ struct WebContents::FrameDispatchHelper {
|
||||
WebContents::WebContents(v8::Isolate* isolate,
|
||||
content::WebContents* web_contents,
|
||||
Type type)
|
||||
: content::WebContentsObserver(web_contents), type_(type) {
|
||||
: content::WebContentsObserver(web_contents),
|
||||
type_(type),
|
||||
weak_factory_(this) {
|
||||
const mate::Dictionary options = mate::Dictionary::CreateEmpty(isolate);
|
||||
if (type == REMOTE) {
|
||||
web_contents->SetUserAgentOverride(GetBrowserContext()->GetUserAgent(),
|
||||
@@ -304,8 +306,8 @@ WebContents::WebContents(v8::Isolate* isolate,
|
||||
}
|
||||
}
|
||||
|
||||
WebContents::WebContents(v8::Isolate* isolate,
|
||||
const mate::Dictionary& options) {
|
||||
WebContents::WebContents(v8::Isolate* isolate, const mate::Dictionary& options)
|
||||
: weak_factory_(this) {
|
||||
// Read options.
|
||||
options.Get("backgroundThrottling", &background_throttling_);
|
||||
|
||||
@@ -1688,6 +1690,19 @@ void WebContents::SendInputEvent(v8::Isolate* isolate,
|
||||
mouse_wheel_event);
|
||||
#endif
|
||||
} else {
|
||||
// Chromium expects phase info in wheel events (and applies a
|
||||
// DCHECK to verify it). See: https://crbug.com/756524.
|
||||
mouse_wheel_event.phase = blink::WebMouseWheelEvent::kPhaseBegan;
|
||||
mouse_wheel_event.dispatch_type = blink::WebInputEvent::kBlocking;
|
||||
rwh->ForwardWheelEvent(mouse_wheel_event);
|
||||
|
||||
// Send a synthetic wheel event with phaseEnded to finish scrolling.
|
||||
mouse_wheel_event.has_synthetic_phase = true;
|
||||
mouse_wheel_event.delta_x = 0;
|
||||
mouse_wheel_event.delta_y = 0;
|
||||
mouse_wheel_event.phase = blink::WebMouseWheelEvent::kPhaseEnded;
|
||||
mouse_wheel_event.dispatch_type =
|
||||
blink::WebInputEvent::kEventNonBlocking;
|
||||
rwh->ForwardWheelEvent(mouse_wheel_event);
|
||||
}
|
||||
return;
|
||||
|
||||
@@ -99,6 +99,8 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype);
|
||||
|
||||
base::WeakPtr<WebContents> GetWeakPtr() { return weak_factory_.GetWeakPtr(); }
|
||||
|
||||
// Destroy the managed content::WebContents instance.
|
||||
//
|
||||
// Note: The |async| should only be |true| when users are expecting to use the
|
||||
@@ -291,7 +293,9 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
observers_.AddObserver(obs);
|
||||
}
|
||||
void RemoveObserver(ExtendedWebContentsObserver* obs) {
|
||||
observers_.RemoveObserver(obs);
|
||||
// Trying to remove from an empty collection leads to an access violation
|
||||
if (observers_.might_have_observers())
|
||||
observers_.RemoveObserver(obs);
|
||||
}
|
||||
|
||||
bool EmitNavigationEvent(const std::string& event,
|
||||
@@ -515,6 +519,8 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
// Observers of this WebContents.
|
||||
base::ObserverList<ExtendedWebContentsObserver> observers_;
|
||||
|
||||
base::WeakPtrFactory<WebContents> weak_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(WebContents);
|
||||
};
|
||||
|
||||
|
||||
@@ -17,12 +17,15 @@ namespace mate {
|
||||
StreamSubscriber::StreamSubscriber(
|
||||
v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> emitter,
|
||||
base::WeakPtr<atom::URLRequestStreamJob> url_job)
|
||||
: isolate_(isolate),
|
||||
base::WeakPtr<atom::URLRequestStreamJob> url_job,
|
||||
scoped_refptr<base::SequencedTaskRunner> ui_task_runner)
|
||||
: base::RefCountedDeleteOnSequence<StreamSubscriber>(ui_task_runner),
|
||||
isolate_(isolate),
|
||||
emitter_(isolate, emitter),
|
||||
url_job_(url_job),
|
||||
weak_factory_(this) {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
DCHECK(ui_task_runner->RunsTasksInCurrentSequence());
|
||||
|
||||
auto weak_self = weak_factory_.GetWeakPtr();
|
||||
On("data", base::Bind(&StreamSubscriber::OnData, weak_self));
|
||||
On("end", base::Bind(&StreamSubscriber::OnEnd, weak_self));
|
||||
@@ -30,13 +33,12 @@ StreamSubscriber::StreamSubscriber(
|
||||
}
|
||||
|
||||
StreamSubscriber::~StreamSubscriber() {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
RemoveAllListeners();
|
||||
}
|
||||
|
||||
void StreamSubscriber::On(const std::string& event,
|
||||
EventCallback&& callback) { // NOLINT
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
DCHECK(owning_task_runner()->RunsTasksInCurrentSequence());
|
||||
DCHECK(js_handlers_.find(event) == js_handlers_.end());
|
||||
|
||||
v8::Locker locker(isolate_);
|
||||
@@ -50,7 +52,7 @@ void StreamSubscriber::On(const std::string& event,
|
||||
}
|
||||
|
||||
void StreamSubscriber::Off(const std::string& event) {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
DCHECK(owning_task_runner()->RunsTasksInCurrentSequence());
|
||||
DCHECK(js_handlers_.find(event) != js_handlers_.end());
|
||||
|
||||
v8::Locker locker(isolate_);
|
||||
@@ -96,6 +98,7 @@ void StreamSubscriber::OnError(mate::Arguments* args) {
|
||||
}
|
||||
|
||||
void StreamSubscriber::RemoveAllListeners() {
|
||||
DCHECK(owning_task_runner()->RunsTasksInCurrentSequence());
|
||||
v8::Locker locker(isolate_);
|
||||
v8::Isolate::Scope isolate_scope(isolate_);
|
||||
v8::HandleScope handle_scope(isolate_);
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
#include <vector>
|
||||
|
||||
#include "base/callback.h"
|
||||
#include "base/memory/ref_counted.h"
|
||||
#include "base/memory/ref_counted_delete_on_sequence.h"
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "v8/include/v8.h"
|
||||
@@ -23,17 +25,25 @@ namespace mate {
|
||||
|
||||
class Arguments;
|
||||
|
||||
class StreamSubscriber {
|
||||
class StreamSubscriber
|
||||
: public base::RefCountedDeleteOnSequence<StreamSubscriber> {
|
||||
public:
|
||||
REQUIRE_ADOPTION_FOR_REFCOUNTED_TYPE();
|
||||
|
||||
StreamSubscriber(v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> emitter,
|
||||
base::WeakPtr<atom::URLRequestStreamJob> url_job);
|
||||
~StreamSubscriber();
|
||||
base::WeakPtr<atom::URLRequestStreamJob> url_job,
|
||||
scoped_refptr<base::SequencedTaskRunner> ui_task_runner);
|
||||
|
||||
private:
|
||||
friend class base::DeleteHelper<StreamSubscriber>;
|
||||
friend class base::RefCountedDeleteOnSequence<StreamSubscriber>;
|
||||
|
||||
using JSHandlersMap = std::map<std::string, v8::Global<v8::Value>>;
|
||||
using EventCallback = base::Callback<void(mate::Arguments* args)>;
|
||||
|
||||
~StreamSubscriber();
|
||||
|
||||
void On(const std::string& event, EventCallback&& callback); // NOLINT
|
||||
void Off(const std::string& event);
|
||||
|
||||
|
||||
@@ -466,11 +466,6 @@ bool AtomBrowserClient::CanCreateWindow(
|
||||
|
||||
int opener_render_process_id = opener->GetProcess()->GetID();
|
||||
|
||||
if (IsRendererSandboxed(opener_render_process_id)) {
|
||||
*no_javascript_access = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (RendererUsesNativeWindowOpen(opener_render_process_id)) {
|
||||
if (RendererDisablesPopups(opener_render_process_id)) {
|
||||
// <webview> without allowpopups attribute should return
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "atom/app/atom_content_client.h"
|
||||
#include "atom/browser/atom_blob_reader.h"
|
||||
#include "atom/browser/atom_browser_main_parts.h"
|
||||
#include "atom/browser/atom_download_manager_delegate.h"
|
||||
@@ -42,6 +43,7 @@
|
||||
#include "components/proxy_config/proxy_config_pref_names.h"
|
||||
#include "content/browser/blob_storage/chrome_blob_storage_context.h"
|
||||
#include "content/public/browser/storage_partition.h"
|
||||
#include "content/public/common/content_client.h"
|
||||
#include "content/public/common/user_agent.h"
|
||||
#include "net/base/escape.h"
|
||||
|
||||
@@ -51,14 +53,6 @@ namespace atom {
|
||||
|
||||
namespace {
|
||||
|
||||
std::string RemoveWhitespace(const std::string& str) {
|
||||
std::string trimmed;
|
||||
if (base::RemoveChars(str, " ", &trimmed))
|
||||
return trimmed;
|
||||
else
|
||||
return str;
|
||||
}
|
||||
|
||||
// Convert string to lower case and escape it.
|
||||
std::string MakePartitionName(const std::string& input) {
|
||||
return net::EscapePath(base::ToLowerASCII(input));
|
||||
@@ -78,19 +72,9 @@ AtomBrowserContext::AtomBrowserContext(const std::string& partition,
|
||||
storage_policy_(new SpecialStoragePolicy),
|
||||
in_memory_(in_memory),
|
||||
weak_factory_(this) {
|
||||
// Construct user agent string.
|
||||
Browser* browser = Browser::Get();
|
||||
std::string name = RemoveWhitespace(browser->GetName());
|
||||
std::string user_agent;
|
||||
if (name == ATOM_PRODUCT_NAME) {
|
||||
user_agent = "Chrome/" CHROME_VERSION_STRING " " ATOM_PRODUCT_NAME
|
||||
"/" ATOM_VERSION_STRING;
|
||||
} else {
|
||||
user_agent = base::StringPrintf(
|
||||
"%s/%s Chrome/%s " ATOM_PRODUCT_NAME "/" ATOM_VERSION_STRING,
|
||||
name.c_str(), browser->GetVersion().c_str(), CHROME_VERSION_STRING);
|
||||
}
|
||||
user_agent_ = content::BuildUserAgentFromProduct(user_agent);
|
||||
AtomContentClient* client =
|
||||
static_cast<AtomContentClient*>(content::GetContentClient());
|
||||
user_agent_ = client->GetUserAgent();
|
||||
|
||||
// Read options.
|
||||
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
|
||||
|
||||
@@ -183,12 +183,14 @@ int AtomPermissionManager::RequestPermissionsWithDetails(
|
||||
const auto callback =
|
||||
base::Bind(&AtomPermissionManager::OnPermissionResponse,
|
||||
base::Unretained(this), request_id, i);
|
||||
if (details == nullptr) {
|
||||
request_handler_.Run(web_contents, permission, callback,
|
||||
base::DictionaryValue());
|
||||
} else {
|
||||
request_handler_.Run(web_contents, permission, callback, *details);
|
||||
}
|
||||
auto mutable_details =
|
||||
details == nullptr ? base::DictionaryValue() : details->Clone();
|
||||
mutable_details.SetKey(
|
||||
"requestingUrl",
|
||||
base::Value(render_frame_host->GetLastCommittedURL().spec()));
|
||||
mutable_details.SetKey(
|
||||
"isMainFrame", base::Value(render_frame_host->GetParent() == nullptr));
|
||||
request_handler_.Run(web_contents, permission, callback, mutable_details);
|
||||
}
|
||||
|
||||
return request_id;
|
||||
@@ -241,8 +243,15 @@ bool AtomPermissionManager::CheckPermissionWithDetails(
|
||||
}
|
||||
auto* web_contents =
|
||||
content::WebContents::FromRenderFrameHost(render_frame_host);
|
||||
auto mutable_details =
|
||||
details == nullptr ? base::DictionaryValue() : details->Clone();
|
||||
mutable_details.SetKey(
|
||||
"requestingUrl",
|
||||
base::Value(render_frame_host->GetLastCommittedURL().spec()));
|
||||
mutable_details.SetKey(
|
||||
"isMainFrame", base::Value(render_frame_host->GetParent() == nullptr));
|
||||
return check_handler_.Run(web_contents, permission, requesting_origin,
|
||||
*details);
|
||||
mutable_details);
|
||||
}
|
||||
|
||||
blink::mojom::PermissionStatus
|
||||
|
||||
@@ -31,11 +31,11 @@ class AtomPermissionManager : public content::PermissionControllerDelegate {
|
||||
using RequestHandler = base::Callback<void(content::WebContents*,
|
||||
content::PermissionType,
|
||||
const StatusCallback&,
|
||||
const base::DictionaryValue&)>;
|
||||
const base::Value&)>;
|
||||
using CheckHandler = base::Callback<bool(content::WebContents*,
|
||||
content::PermissionType,
|
||||
const GURL& requesting_origin,
|
||||
const base::DictionaryValue&)>;
|
||||
const base::Value&)>;
|
||||
|
||||
// Handler to dispatch permission requests in JS.
|
||||
void SetPermissionRequestHandler(const RequestHandler& handler);
|
||||
|
||||
@@ -48,6 +48,8 @@ network::mojom::HttpAuthDynamicParamsPtr CreateHttpAuthDynamicParams(
|
||||
command_line.GetSwitchValueASCII(switches::kAuthServerWhitelist);
|
||||
auth_dynamic_params->delegate_whitelist = command_line.GetSwitchValueASCII(
|
||||
switches::kAuthNegotiateDelegateWhitelist);
|
||||
auth_dynamic_params->enable_negotiate_port =
|
||||
command_line.HasSwitch(atom::switches::kEnableAuthNegotiatePort);
|
||||
|
||||
return auth_dynamic_params;
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
@class AtomPreviewItem;
|
||||
@class AtomTouchBar;
|
||||
@class CustomWindowButtonView;
|
||||
@class FullSizeContentView;
|
||||
|
||||
namespace atom {
|
||||
|
||||
@@ -164,7 +163,7 @@ class NativeWindowMac : public NativeWindow {
|
||||
|
||||
private:
|
||||
// Add custom layers to the content view.
|
||||
void AddContentViewLayers();
|
||||
void AddContentViewLayers(bool minimizable, bool closable);
|
||||
|
||||
void InternalSetParentWindow(NativeWindow* parent, bool attach);
|
||||
void ShowWindowButton(NSWindowButton button);
|
||||
@@ -181,10 +180,12 @@ class NativeWindowMac : public NativeWindow {
|
||||
// Event monitor for scroll wheel event.
|
||||
id wheel_event_monitor_;
|
||||
|
||||
// The view that will fill the whole frameless window.
|
||||
base::scoped_nsobject<FullSizeContentView> container_view_;
|
||||
// The NSView that used as contentView of window.
|
||||
//
|
||||
// For frameless window it would fill the whole window.
|
||||
base::scoped_nsobject<NSView> container_view_;
|
||||
|
||||
// The view that fills the client area.
|
||||
// The views::View that fills the client area.
|
||||
std::unique_ptr<RootViewMac> root_view_;
|
||||
|
||||
bool is_kiosk_ = false;
|
||||
|
||||
@@ -29,9 +29,56 @@
|
||||
#include "ui/gfx/skia_util.h"
|
||||
#include "ui/gl/gpu_switching_manager.h"
|
||||
#include "ui/views/background.h"
|
||||
#include "ui/views/cocoa/bridged_content_view.h"
|
||||
#include "ui/views/cocoa/bridged_native_widget.h"
|
||||
#include "ui/views/widget/widget.h"
|
||||
|
||||
// This view would inform Chromium to resize the hosted views::View.
|
||||
//
|
||||
// The overrided methods should behave the same with BridgedContentView.
|
||||
@interface ElectronAdapatedContentView : NSView {
|
||||
@private
|
||||
views::BridgedNativeWidget* bridged_widget_;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation ElectronAdapatedContentView
|
||||
|
||||
- (id)initWithShell:(atom::NativeWindowMac*)shell {
|
||||
if ((self = [self init])) {
|
||||
bridged_widget_ = views::NativeWidgetMac::GetBridgeForNativeWindow(
|
||||
shell->GetNativeWindow());
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)viewDidMoveToWindow {
|
||||
// When this view is added to a window, AppKit calls setFrameSize before it is
|
||||
// added to the window, so the behavior in setFrameSize is not triggered.
|
||||
NSWindow* window = [self window];
|
||||
if (window)
|
||||
[self setFrameSize:NSZeroSize];
|
||||
}
|
||||
|
||||
- (void)setFrameSize:(NSSize)newSize {
|
||||
// The size passed in here does not always use
|
||||
// -[NSWindow contentRectForFrameRect]. The following ensures that the
|
||||
// contentView for a frameless window can extend over the titlebar of the new
|
||||
// window containing it, since AppKit requires a titlebar to give frameless
|
||||
// windows correct shadows and rounded corners.
|
||||
NSWindow* window = [self window];
|
||||
if (window && [window contentView] == self)
|
||||
newSize = [window contentRectForFrameRect:[window frame]].size;
|
||||
|
||||
[super setFrameSize:newSize];
|
||||
|
||||
views::View* hostedView = [bridged_widget_->ns_view() hostedView];
|
||||
if (hostedView)
|
||||
hostedView->SetSize(gfx::Size(newSize.width, newSize.height));
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
// This view always takes the size of its superview. It is intended to be used
|
||||
// as a NSWindow's contentView. It is needed because NSWindow's implementation
|
||||
// explicitly resizes the contentView at inopportune times.
|
||||
@@ -73,9 +120,11 @@
|
||||
NSButton* close_button =
|
||||
[NSWindow standardWindowButton:NSWindowCloseButton
|
||||
forStyleMask:NSWindowStyleMaskTitled];
|
||||
[close_button setTag:1];
|
||||
NSButton* miniaturize_button =
|
||||
[NSWindow standardWindowButton:NSWindowMiniaturizeButton
|
||||
forStyleMask:NSWindowStyleMaskTitled];
|
||||
[miniaturize_button setTag:2];
|
||||
|
||||
CGFloat x = 0;
|
||||
const CGFloat space_between = 20;
|
||||
@@ -466,7 +515,7 @@ NativeWindowMac::NativeWindowMac(const mate::Dictionary& options,
|
||||
|
||||
// Default content view.
|
||||
SetContentView(new views::View());
|
||||
AddContentViewLayers();
|
||||
AddContentViewLayers(minimizable, closable);
|
||||
|
||||
original_frame_ = [window_ frame];
|
||||
original_level_ = [window_ level];
|
||||
@@ -857,9 +906,9 @@ void NativeWindowMac::SetAlwaysOnTop(bool top,
|
||||
if (newLevel >= minWindowLevel && newLevel <= maxWindowLevel) {
|
||||
[window_ setLevel:newLevel];
|
||||
} else {
|
||||
*error = std::string([
|
||||
[NSString stringWithFormat:@"relativeLevel must be between %d and %d",
|
||||
minWindowLevel, maxWindowLevel] UTF8String]);
|
||||
*error = std::string([[NSString
|
||||
stringWithFormat:@"relativeLevel must be between %d and %d",
|
||||
minWindowLevel, maxWindowLevel] UTF8String]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -950,7 +999,13 @@ void NativeWindowMac::SetSimpleFullScreen(bool simple_fullscreen) {
|
||||
[[window standardWindowButton:NSWindowCloseButton] setHidden:YES];
|
||||
}
|
||||
|
||||
[window setFrame:fullscreenFrame display:YES animate:YES];
|
||||
// There is a bug with Chromium that, after setting window style, calling
|
||||
// setFrame with animation immediately would block window rendering for
|
||||
// a few seconds.
|
||||
// This Chromium bug is fixed in later versions, but it is hard to find
|
||||
// out how to backport the fix or how to work around it, disabling the
|
||||
// animation is the easist fix and most users would not even notice it.
|
||||
[window setFrame:fullscreenFrame display:YES animate:NO];
|
||||
|
||||
// Fullscreen windows can't be resized, minimized, maximized, or moved
|
||||
SetMinimizable(false);
|
||||
@@ -974,7 +1029,7 @@ void NativeWindowMac::SetSimpleFullScreen(bool simple_fullscreen) {
|
||||
[[window standardWindowButton:NSWindowCloseButton]
|
||||
setHidden:window_button_hidden];
|
||||
|
||||
[window setFrame:original_frame_ display:YES animate:YES];
|
||||
[window setFrame:original_frame_ display:YES animate:NO];
|
||||
window.level = original_level_;
|
||||
|
||||
[NSApp setPresentationOptions:simple_fullscreen_options_];
|
||||
@@ -1080,7 +1135,7 @@ void NativeWindowMac::SetBrowserView(NativeBrowserView* view) {
|
||||
|
||||
if (browser_view()) {
|
||||
[browser_view()->GetInspectableWebContentsView()->GetNativeView()
|
||||
removeFromSuperview];
|
||||
removeFromSuperview];
|
||||
set_browser_view(nullptr);
|
||||
}
|
||||
|
||||
@@ -1379,7 +1434,7 @@ views::View* NativeWindowMac::GetContentsView() {
|
||||
return root_view_.get();
|
||||
}
|
||||
|
||||
void NativeWindowMac::AddContentViewLayers() {
|
||||
void NativeWindowMac::AddContentViewLayers(bool minimizable, bool closable) {
|
||||
// Make sure the bottom corner is rounded for non-modal windows:
|
||||
// http://crbug.com/396264. But do not enable it on OS X 10.9 for transparent
|
||||
// window, otherwise a semi-transparent frame would show.
|
||||
@@ -1420,6 +1475,12 @@ void NativeWindowMac::AddContentViewLayers() {
|
||||
[[CustomWindowButtonView alloc] initWithFrame:NSZeroRect]);
|
||||
// NSWindowStyleMaskFullSizeContentView does not work with zoom button
|
||||
SetFullScreenable(false);
|
||||
|
||||
if (!minimizable)
|
||||
[[buttons_view_ viewWithTag:2] removeFromSuperview];
|
||||
if (!closable)
|
||||
[[buttons_view_ viewWithTag:1] removeFromSuperview];
|
||||
|
||||
[[window_ contentView] addSubview:buttons_view_];
|
||||
} else {
|
||||
if (title_bar_style_ != NORMAL) {
|
||||
@@ -1479,12 +1540,17 @@ void NativeWindowMac::OverrideNSWindowContentView() {
|
||||
// `BridgedContentView` as content view, which does not support draggable
|
||||
// regions. In order to make draggable regions work, we have to replace the
|
||||
// content view with a simple NSView.
|
||||
container_view_.reset([[FullSizeContentView alloc] init]);
|
||||
if (has_frame()) {
|
||||
container_view_.reset(
|
||||
[[ElectronAdapatedContentView alloc] initWithShell:this]);
|
||||
} else {
|
||||
container_view_.reset([[FullSizeContentView alloc] init]);
|
||||
[container_view_ setFrame:[[[window_ contentView] superview] bounds]];
|
||||
}
|
||||
[container_view_
|
||||
setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
|
||||
[container_view_ setFrame:[[[window_ contentView] superview] bounds]];
|
||||
[window_ setContentView:container_view_];
|
||||
AddContentViewLayers();
|
||||
AddContentViewLayers(IsMinimizable(), IsClosable());
|
||||
}
|
||||
|
||||
void NativeWindowMac::SetStyleMask(bool on, NSUInteger flag) {
|
||||
|
||||
@@ -349,6 +349,9 @@ void NativeWindowViews::Show() {
|
||||
|
||||
widget()->native_widget_private()->ShowWithWindowState(GetRestoredState());
|
||||
|
||||
// explicitly focus the window
|
||||
widget()->Activate();
|
||||
|
||||
NotifyWindowShow();
|
||||
|
||||
#if defined(USE_X11)
|
||||
|
||||
@@ -13,14 +13,16 @@
|
||||
#include "atom/common/api/event_emitter_caller.h"
|
||||
#include "atom/common/atom_constants.h"
|
||||
#include "atom/common/native_mate_converters/net_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/threading/thread_task_runner_handle.h"
|
||||
#include "base/time/time.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "net/base/net_errors.h"
|
||||
#include "net/filter/gzip_source_stream.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace {
|
||||
@@ -82,14 +84,14 @@ void BeforeStartInUI(base::WeakPtr<URLRequestStreamJob> job,
|
||||
return;
|
||||
}
|
||||
|
||||
auto subscriber = std::make_unique<mate::StreamSubscriber>(
|
||||
args->isolate(), data.GetHandle(), job);
|
||||
auto subscriber = base::MakeRefCounted<mate::StreamSubscriber>(
|
||||
args->isolate(), data.GetHandle(), job,
|
||||
base::ThreadTaskRunnerHandle::Get());
|
||||
|
||||
content::BrowserThread::PostTask(
|
||||
content::BrowserThread::IO, FROM_HERE,
|
||||
base::BindOnce(&URLRequestStreamJob::StartAsync, job,
|
||||
std::move(subscriber), base::RetainedRef(response_headers),
|
||||
ended, error));
|
||||
base::BindOnce(&URLRequestStreamJob::StartAsync, job, subscriber,
|
||||
base::RetainedRef(response_headers), ended, error));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@@ -104,10 +106,7 @@ URLRequestStreamJob::URLRequestStreamJob(net::URLRequest* request,
|
||||
weak_factory_(this) {}
|
||||
|
||||
URLRequestStreamJob::~URLRequestStreamJob() {
|
||||
if (subscriber_) {
|
||||
content::BrowserThread::DeleteSoon(content::BrowserThread::UI, FROM_HERE,
|
||||
std::move(subscriber_));
|
||||
}
|
||||
DCHECK(!subscriber_ || subscriber_->HasOneRef());
|
||||
}
|
||||
|
||||
void URLRequestStreamJob::Start() {
|
||||
@@ -121,7 +120,7 @@ void URLRequestStreamJob::Start() {
|
||||
}
|
||||
|
||||
void URLRequestStreamJob::StartAsync(
|
||||
std::unique_ptr<mate::StreamSubscriber> subscriber,
|
||||
scoped_refptr<mate::StreamSubscriber> subscriber,
|
||||
scoped_refptr<net::HttpResponseHeaders> response_headers,
|
||||
bool ended,
|
||||
int error) {
|
||||
@@ -133,7 +132,7 @@ void URLRequestStreamJob::StartAsync(
|
||||
|
||||
ended_ = ended;
|
||||
response_headers_ = response_headers;
|
||||
subscriber_ = std::move(subscriber);
|
||||
subscriber_ = subscriber;
|
||||
request_start_time_ = base::TimeTicks::Now();
|
||||
NotifyHeadersComplete();
|
||||
}
|
||||
@@ -192,12 +191,13 @@ int URLRequestStreamJob::ReadRawData(net::IOBuffer* dest, int dest_size) {
|
||||
}
|
||||
|
||||
void URLRequestStreamJob::DoneReading() {
|
||||
content::BrowserThread::DeleteSoon(content::BrowserThread::UI, FROM_HERE,
|
||||
std::move(subscriber_));
|
||||
write_buffer_.clear();
|
||||
}
|
||||
|
||||
void URLRequestStreamJob::DoneReadingRedirectResponse() {
|
||||
if (subscriber_) {
|
||||
subscriber_ = nullptr;
|
||||
}
|
||||
DoneReading();
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ class URLRequestStreamJob : public JsAsker, public net::URLRequestJob {
|
||||
net::NetworkDelegate* network_delegate);
|
||||
~URLRequestStreamJob() override;
|
||||
|
||||
void StartAsync(std::unique_ptr<mate::StreamSubscriber> subscriber,
|
||||
void StartAsync(scoped_refptr<mate::StreamSubscriber> subscriber,
|
||||
scoped_refptr<net::HttpResponseHeaders> response_headers,
|
||||
bool ended,
|
||||
int error);
|
||||
@@ -62,7 +62,7 @@ class URLRequestStreamJob : public JsAsker, public net::URLRequestJob {
|
||||
base::TimeTicks request_start_time_;
|
||||
base::TimeTicks response_start_time_;
|
||||
scoped_refptr<net::HttpResponseHeaders> response_headers_;
|
||||
std::unique_ptr<mate::StreamSubscriber> subscriber_;
|
||||
scoped_refptr<mate::StreamSubscriber> subscriber_;
|
||||
|
||||
base::WeakPtrFactory<URLRequestStreamJob> weak_factory_;
|
||||
|
||||
|
||||
@@ -17,9 +17,9 @@
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>electron.icns</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>4.1.2</string>
|
||||
<string>4.2.11</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>4.1.2</string>
|
||||
<string>4.2.11</string>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string>public.app-category.developer-tools</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
|
||||
@@ -50,8 +50,8 @@ END
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 4,1,2,0
|
||||
PRODUCTVERSION 4,1,2,0
|
||||
FILEVERSION 4,2,11,0
|
||||
PRODUCTVERSION 4,2,11,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@@ -68,12 +68,12 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "CompanyName", "GitHub, Inc."
|
||||
VALUE "FileDescription", "Electron"
|
||||
VALUE "FileVersion", "4.1.2"
|
||||
VALUE "FileVersion", "4.2.11"
|
||||
VALUE "InternalName", "electron.exe"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved."
|
||||
VALUE "OriginalFilename", "electron.exe"
|
||||
VALUE "ProductName", "Electron"
|
||||
VALUE "ProductVersion", "4.1.2"
|
||||
VALUE "ProductVersion", "4.2.11"
|
||||
VALUE "SquirrelAwareVersion", "1"
|
||||
END
|
||||
END
|
||||
|
||||
@@ -353,8 +353,11 @@ static NSString* const ImageScrubberItemIdentifier = @"scrubber.image.item";
|
||||
NSButton* button = (NSButton*)item.view;
|
||||
|
||||
std::string backgroundColor;
|
||||
if (settings.Get("backgroundColor", &backgroundColor)) {
|
||||
if (settings.Get("backgroundColor", &backgroundColor) &&
|
||||
!backgroundColor.empty()) {
|
||||
button.bezelColor = [self colorFromHexColorString:backgroundColor];
|
||||
} else {
|
||||
button.bezelColor = nil;
|
||||
}
|
||||
|
||||
std::string label;
|
||||
|
||||
@@ -29,6 +29,7 @@ class TrayIconCocoa : public TrayIcon, public AtomMenuModel::Observer {
|
||||
void SetHighlightMode(TrayIcon::HighlightMode mode) override;
|
||||
void SetIgnoreDoubleClickEvents(bool ignore) override;
|
||||
bool GetIgnoreDoubleClickEvents() override;
|
||||
void PopUpOnUI(AtomMenuModel* menu_model);
|
||||
void PopUpContextMenu(const gfx::Point& pos,
|
||||
AtomMenuModel* menu_model) override;
|
||||
void SetContextMenu(AtomMenuModel* menu_model) override;
|
||||
@@ -48,6 +49,8 @@ class TrayIconCocoa : public TrayIcon, public AtomMenuModel::Observer {
|
||||
// Used for unregistering observer.
|
||||
AtomMenuModel* menu_model_ = nullptr; // weak ref.
|
||||
|
||||
base::WeakPtrFactory<TrayIconCocoa> weak_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(TrayIconCocoa);
|
||||
};
|
||||
|
||||
|
||||
@@ -4,9 +4,14 @@
|
||||
|
||||
#include "atom/browser/ui/tray_icon_cocoa.h"
|
||||
|
||||
#include "atom/browser/mac/atom_application.h"
|
||||
#include "atom/browser/ui/cocoa/NSString+ANSI.h"
|
||||
#include "atom/browser/ui/cocoa/atom_menu_controller.h"
|
||||
#include "base/mac/sdk_forward_declarations.h"
|
||||
#include "base/message_loop/message_loop.h"
|
||||
#include "base/strings/sys_string_conversions.h"
|
||||
#include "base/task_scheduler/post_task.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "ui/display/screen.h"
|
||||
#include "ui/events/cocoa/cocoa_event_utils.h"
|
||||
#include "ui/gfx/image/image.h"
|
||||
@@ -143,6 +148,10 @@ const CGFloat kVerticalTitleMargin = 2;
|
||||
}
|
||||
|
||||
- (BOOL)isDarkMode {
|
||||
if (@available(macOS 10.14, *)) {
|
||||
return [[NSApplication sharedApplication].effectiveAppearance.name
|
||||
isEqualToString:NSAppearanceNameDarkAqua];
|
||||
}
|
||||
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
|
||||
NSString* mode = [defaults stringForKey:@"AppleInterfaceStyle"];
|
||||
return mode && [mode isEqualToString:@"Dark"];
|
||||
@@ -320,13 +329,17 @@ const CGFloat kVerticalTitleMargin = 2;
|
||||
}
|
||||
|
||||
- (void)popUpContextMenu:(atom::AtomMenuModel*)menu_model {
|
||||
// Make sure events can be pumped while the menu is up.
|
||||
base::MessageLoopCurrent::ScopedNestableTaskAllower allow;
|
||||
|
||||
// Show a custom menu.
|
||||
if (menu_model) {
|
||||
base::scoped_nsobject<AtomMenuController> menuController([
|
||||
[AtomMenuController alloc] initWithModel:menu_model
|
||||
useDefaultAccelerator:NO]);
|
||||
base::scoped_nsobject<AtomMenuController> menuController(
|
||||
[[AtomMenuController alloc] initWithModel:menu_model
|
||||
useDefaultAccelerator:NO]);
|
||||
forceHighlight_ = YES; // Should highlight when showing menu.
|
||||
[self setNeedsDisplay:YES];
|
||||
|
||||
[statusItem_ popUpStatusItemMenu:[menuController menu]];
|
||||
forceHighlight_ = NO;
|
||||
[self setNeedsDisplay:YES];
|
||||
@@ -334,8 +347,12 @@ const CGFloat kVerticalTitleMargin = 2;
|
||||
}
|
||||
|
||||
if (menuController_ && ![menuController_ isMenuOpen]) {
|
||||
// Ensure the UI can update while the menu is fading out.
|
||||
base::ScopedPumpMessagesInPrivateModes pump_private;
|
||||
|
||||
// Redraw the tray icon to show highlight if it is enabled.
|
||||
[self setNeedsDisplay:YES];
|
||||
|
||||
[statusItem_ popUpStatusItemMenu:[menuController_ menu]];
|
||||
// The popUpStatusItemMenu returns only after the showing menu is closed.
|
||||
// When it returns, we need to redraw the tray icon to not show highlight.
|
||||
@@ -433,7 +450,7 @@ const CGFloat kVerticalTitleMargin = 2;
|
||||
|
||||
namespace atom {
|
||||
|
||||
TrayIconCocoa::TrayIconCocoa() {
|
||||
TrayIconCocoa::TrayIconCocoa() : weak_factory_(this) {
|
||||
status_item_view_.reset([[StatusItemView alloc] initWithIcon:this]);
|
||||
}
|
||||
|
||||
@@ -471,9 +488,16 @@ bool TrayIconCocoa::GetIgnoreDoubleClickEvents() {
|
||||
return [status_item_view_ getIgnoreDoubleClickEvents];
|
||||
}
|
||||
|
||||
void TrayIconCocoa::PopUpOnUI(AtomMenuModel* menu_model) {
|
||||
[status_item_view_ popUpContextMenu:menu_model];
|
||||
}
|
||||
|
||||
void TrayIconCocoa::PopUpContextMenu(const gfx::Point& pos,
|
||||
AtomMenuModel* menu_model) {
|
||||
[status_item_view_ popUpContextMenu:menu_model];
|
||||
content::BrowserThread::PostTask(
|
||||
content::BrowserThread::UI, FROM_HERE,
|
||||
base::BindOnce(&TrayIconCocoa::PopUpOnUI, weak_factory_.GetWeakPtr(),
|
||||
base::Unretained(menu_model)));
|
||||
}
|
||||
|
||||
void TrayIconCocoa::SetContextMenu(AtomMenuModel* menu_model) {
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "cc/base/switches.h"
|
||||
#include "content/public/browser/render_frame_host.h"
|
||||
#include "content/public/browser/render_process_host.h"
|
||||
#include "content/public/common/content_client.h"
|
||||
#include "content/public/common/content_switches.h"
|
||||
#include "content/public/common/web_preferences.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
@@ -135,6 +136,8 @@ WebContentsPreferences::WebContentsPreferences(
|
||||
#endif
|
||||
SetDefaultBoolIfUndefined(options::kOffscreen, false);
|
||||
|
||||
SetDefaults();
|
||||
|
||||
last_preference_ = preference_.Clone();
|
||||
}
|
||||
|
||||
@@ -143,6 +146,12 @@ WebContentsPreferences::~WebContentsPreferences() {
|
||||
instances_.end());
|
||||
}
|
||||
|
||||
void WebContentsPreferences::SetDefaults() {
|
||||
if (IsEnabled(options::kSandbox)) {
|
||||
SetBool(options::kNativeWindowOpen, true);
|
||||
}
|
||||
}
|
||||
|
||||
bool WebContentsPreferences::SetDefaultBoolIfUndefined(
|
||||
const base::StringPiece& key,
|
||||
bool val) {
|
||||
@@ -156,6 +165,10 @@ bool WebContentsPreferences::SetDefaultBoolIfUndefined(
|
||||
}
|
||||
}
|
||||
|
||||
void WebContentsPreferences::SetBool(const base::StringPiece& key, bool value) {
|
||||
preference_.SetKey(key, base::Value(value));
|
||||
}
|
||||
|
||||
bool WebContentsPreferences::IsEnabled(const base::StringPiece& name,
|
||||
bool default_value) const {
|
||||
auto* current_value =
|
||||
@@ -168,6 +181,8 @@ bool WebContentsPreferences::IsEnabled(const base::StringPiece& name,
|
||||
void WebContentsPreferences::Merge(const base::DictionaryValue& extend) {
|
||||
if (preference_.is_dict())
|
||||
static_cast<base::DictionaryValue*>(&preference_)->MergeDictionary(&extend);
|
||||
|
||||
SetDefaults();
|
||||
}
|
||||
|
||||
void WebContentsPreferences::Clear() {
|
||||
@@ -229,6 +244,9 @@ WebContentsPreferences* WebContentsPreferences::From(
|
||||
|
||||
void WebContentsPreferences::AppendCommandLineSwitches(
|
||||
base::CommandLine* command_line) {
|
||||
// Append UA Override
|
||||
command_line->AppendSwitchASCII("user-agent",
|
||||
content::GetContentClient()->GetUserAgent());
|
||||
// Check if plugins are enabled.
|
||||
if (IsEnabled(options::kPlugins))
|
||||
command_line->AppendSwitch(switches::kEnablePlugins);
|
||||
|
||||
@@ -36,6 +36,9 @@ class WebContentsPreferences
|
||||
const mate::Dictionary& web_preferences);
|
||||
~WebContentsPreferences() override;
|
||||
|
||||
// Set WebPreferences defaults onto the JS object.
|
||||
void SetDefaults();
|
||||
|
||||
// A simple way to know whether a Boolean property is enabled.
|
||||
bool IsEnabled(const base::StringPiece& name,
|
||||
bool default_value = false) const;
|
||||
@@ -75,6 +78,9 @@ class WebContentsPreferences
|
||||
// Set preference value to given bool if user did not provide value
|
||||
bool SetDefaultBoolIfUndefined(const base::StringPiece& key, bool val);
|
||||
|
||||
// Set preference value to given bool
|
||||
void SetBool(const base::StringPiece& key, bool value);
|
||||
|
||||
static std::vector<WebContentsPreferences*> instances_;
|
||||
|
||||
content::WebContents* web_contents_;
|
||||
|
||||
@@ -137,7 +137,7 @@ bool AddImageSkiaRepFromBuffer(gfx::ImageSkia* image,
|
||||
|
||||
SkBitmap bitmap;
|
||||
bitmap.allocN32Pixels(width, height, false);
|
||||
bitmap.setPixels(const_cast<void*>(reinterpret_cast<const void*>(data)));
|
||||
bitmap.writePixels({info, data, bitmap.rowBytes()});
|
||||
|
||||
image->AddRepresentation(gfx::ImageSkiaRep(bitmap, scale_factor));
|
||||
return true;
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
#define ATOM_COMMON_ATOM_VERSION_H_
|
||||
|
||||
#define ATOM_MAJOR_VERSION 4
|
||||
#define ATOM_MINOR_VERSION 1
|
||||
#define ATOM_PATCH_VERSION 2
|
||||
#define ATOM_MINOR_VERSION 2
|
||||
#define ATOM_PATCH_VERSION 11
|
||||
// clang-format off
|
||||
// #define ATOM_PRE_RELEASE_VERSION
|
||||
// clang-format on
|
||||
|
||||
@@ -93,8 +93,13 @@ bool RegisterNonABICompliantCodeRange(void* start, size_t size_in_bytes) {
|
||||
|
||||
// All addresses are 32bit relative offsets to start.
|
||||
record->runtime_function.BeginAddress = 0;
|
||||
#if defined(_M_ARM64)
|
||||
record->runtime_function.FunctionLength =
|
||||
base::checked_cast<DWORD>(size_in_bytes);
|
||||
#else
|
||||
record->runtime_function.EndAddress =
|
||||
base::checked_cast<DWORD>(size_in_bytes);
|
||||
#endif
|
||||
record->runtime_function.UnwindData =
|
||||
offsetof(ExceptionHandlerRecord, unwind_info);
|
||||
|
||||
|
||||
@@ -181,24 +181,45 @@ bool Converter<net::HttpResponseHeaders*>::FromV8(
|
||||
if (!val->IsObject()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto addHeaderFromValue = [&isolate, &out](
|
||||
const std::string& key,
|
||||
const v8::Local<v8::Value>& localVal) {
|
||||
auto context = isolate->GetCurrentContext();
|
||||
v8::Local<v8::String> localStrVal;
|
||||
if (!localVal->ToString(context).ToLocal(&localStrVal)) {
|
||||
return false;
|
||||
}
|
||||
std::string value;
|
||||
mate::ConvertFromV8(isolate, localStrVal, &value);
|
||||
out->AddHeader(key + ": " + value);
|
||||
return true;
|
||||
};
|
||||
|
||||
auto context = isolate->GetCurrentContext();
|
||||
auto headers = v8::Local<v8::Object>::Cast(val);
|
||||
auto keys = headers->GetOwnPropertyNames();
|
||||
for (uint32_t i = 0; i < keys->Length(); i++) {
|
||||
v8::Local<v8::String> key, value;
|
||||
if (!keys->Get(i)->ToString(context).ToLocal(&key)) {
|
||||
v8::Local<v8::String> keyVal;
|
||||
if (!keys->Get(i)->ToString(context).ToLocal(&keyVal)) {
|
||||
return false;
|
||||
}
|
||||
if (!headers->Get(key)->ToString(context).ToLocal(&value)) {
|
||||
return false;
|
||||
std::string key;
|
||||
mate::ConvertFromV8(isolate, keyVal, &key);
|
||||
|
||||
auto localVal = headers->Get(keyVal);
|
||||
if (localVal->IsArray()) {
|
||||
auto values = v8::Local<v8::Array>::Cast(localVal);
|
||||
for (uint32_t j = 0; j < values->Length(); j++) {
|
||||
if (!addHeaderFromValue(key, values->Get(j))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!addHeaderFromValue(key, localVal)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
v8::String::Utf8Value key_utf8(key);
|
||||
v8::String::Utf8Value value_utf8(value);
|
||||
std::string k(*key_utf8, key_utf8.length());
|
||||
std::string v(*value_utf8, value_utf8.length());
|
||||
std::ostringstream tmp;
|
||||
tmp << k << ": " << v;
|
||||
out->AddHeader(tmp.str());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -247,6 +247,9 @@ const char kAuthServerWhitelist[] = "auth-server-whitelist";
|
||||
const char kAuthNegotiateDelegateWhitelist[] =
|
||||
"auth-negotiate-delegate-whitelist";
|
||||
|
||||
// If set, include the port in generated Kerberos SPNs.
|
||||
const char kEnableAuthNegotiatePort[] = "enable-auth-negotiate-port";
|
||||
|
||||
} // namespace switches
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -118,6 +118,7 @@ extern const char kDiskCacheSize[];
|
||||
extern const char kIgnoreConnectionsLimit[];
|
||||
extern const char kAuthServerWhitelist[];
|
||||
extern const char kAuthNegotiateDelegateWhitelist[];
|
||||
extern const char kEnableAuthNegotiatePort[];
|
||||
|
||||
} // namespace switches
|
||||
|
||||
|
||||
@@ -158,6 +158,8 @@ void AtomSandboxedRendererClient::InitializeBindings(
|
||||
process.SetMethod("hang", AtomBindings::Hang);
|
||||
process.SetMethod("getHeapStatistics", &AtomBindings::GetHeapStatistics);
|
||||
process.SetMethod("getSystemMemoryInfo", &AtomBindings::GetSystemMemoryInfo);
|
||||
process.SetMethod("getProcessMemoryInfo",
|
||||
&AtomBindings::GetProcessMemoryInfo);
|
||||
process.SetMethod(
|
||||
"getCPUUsage",
|
||||
base::Bind(&AtomBindings::GetCPUUsage, base::Unretained(metrics_.get())));
|
||||
@@ -230,6 +232,8 @@ void AtomSandboxedRendererClient::DidCreateScriptContext(
|
||||
// Execute the function with proper arguments
|
||||
ignore_result(
|
||||
func->Call(context, v8::Null(isolate), node::arraysize(args), args));
|
||||
|
||||
InvokeIpcCallback(context, "onLoaded", std::vector<v8::Local<v8::Value>>());
|
||||
}
|
||||
|
||||
void AtomSandboxedRendererClient::WillReleaseScriptContext(
|
||||
|
||||
@@ -115,6 +115,8 @@ void CocoaNotification::Dismiss() {
|
||||
NotificationDismissed();
|
||||
|
||||
this->LogAction("dismissed");
|
||||
|
||||
notification_.reset(nil);
|
||||
}
|
||||
|
||||
void CocoaNotification::NotificationDisplayed() {
|
||||
|
||||
@@ -20,10 +20,6 @@ std::string GetProductInternal() {
|
||||
GetApplicationVersion().c_str());
|
||||
}
|
||||
|
||||
std::string GetBrightrayUserAgent() {
|
||||
return content::BuildUserAgentFromProduct(GetProductInternal());
|
||||
}
|
||||
|
||||
ContentClient::ContentClient() {}
|
||||
|
||||
ContentClient::~ContentClient() {}
|
||||
@@ -32,10 +28,6 @@ std::string ContentClient::GetProduct() const {
|
||||
return GetProductInternal();
|
||||
}
|
||||
|
||||
std::string ContentClient::GetUserAgent() const {
|
||||
return GetBrightrayUserAgent();
|
||||
}
|
||||
|
||||
base::string16 ContentClient::GetLocalizedString(int message_id) const {
|
||||
return l10n_util::GetStringUTF16(message_id);
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@ class ContentClient : public content::ContentClient {
|
||||
|
||||
private:
|
||||
std::string GetProduct() const override;
|
||||
std::string GetUserAgent() const override;
|
||||
base::string16 GetLocalizedString(int message_id) const override;
|
||||
base::StringPiece GetDataResource(int resource_id,
|
||||
ui::ScaleFactor) const override;
|
||||
|
||||
@@ -12,5 +12,6 @@ proprietary_codecs = true
|
||||
ffmpeg_branding = "Chrome"
|
||||
|
||||
enable_basic_printing = true
|
||||
angle_enable_vulkan_validation_layers = false
|
||||
|
||||
is_cfi = false
|
||||
|
||||
53
build/dump_syms.py
Normal file
53
build/dump_syms.py
Normal file
@@ -0,0 +1,53 @@
|
||||
from __future__ import print_function
|
||||
|
||||
import collections
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import errno
|
||||
|
||||
# The BINARY_INFO tuple describes a binary as dump_syms identifies it.
|
||||
BINARY_INFO = collections.namedtuple('BINARY_INFO',
|
||||
['platform', 'arch', 'hash', 'name'])
|
||||
|
||||
def get_module_info(header_info):
|
||||
# header info is of the form "MODULE $PLATFORM $ARCH $HASH $BINARY"
|
||||
info_split = header_info.strip().split(' ', 4)
|
||||
if len(info_split) != 5 or info_split[0] != 'MODULE':
|
||||
return None
|
||||
return BINARY_INFO(*info_split[1:])
|
||||
|
||||
def get_symbol_path(symbol_data):
|
||||
module_info = get_module_info(symbol_data[:symbol_data.index('\n')])
|
||||
if not module_info:
|
||||
raise Exception("Couldn't get module info for binary '{}'".format(binary))
|
||||
exe_name = module_info.name.replace('.pdb', '')
|
||||
return os.path.join(module_info.name, module_info.hash, exe_name + ".sym")
|
||||
|
||||
def mkdir_p(path):
|
||||
"""Simulates mkdir -p."""
|
||||
try:
|
||||
os.makedirs(path)
|
||||
except OSError as e:
|
||||
if e.errno == errno.EEXIST and os.path.isdir(path):
|
||||
pass
|
||||
else: raise
|
||||
|
||||
def main(dump_syms, binary, out_dir, stamp_file, dsym_file=None):
|
||||
args = [dump_syms]
|
||||
if dsym_file:
|
||||
args += ["-g", dsym_file]
|
||||
args += [binary]
|
||||
|
||||
symbol_data = subprocess.check_output(args)
|
||||
symbol_path = os.path.join(out_dir, get_symbol_path(symbol_data))
|
||||
mkdir_p(os.path.dirname(symbol_path))
|
||||
|
||||
with open(symbol_path, 'w') as out:
|
||||
out.write(symbol_data)
|
||||
|
||||
with open(stamp_file, 'w'):
|
||||
pass
|
||||
|
||||
if __name__ == '__main__':
|
||||
main(*sys.argv[1:])
|
||||
55
build/extract_symbols.gni
Normal file
55
build/extract_symbols.gni
Normal file
@@ -0,0 +1,55 @@
|
||||
import("//build/toolchain/toolchain.gni")
|
||||
|
||||
# Extracts symbols from a binary into a symbol file using dump_syms.
|
||||
#
|
||||
# Args:
|
||||
# binary: Path to the binary containing symbols to extract, e.g.:
|
||||
# "$root_out_dir/electron"
|
||||
# symbol_dir: Desired output directory for symbols, e.g.:
|
||||
# "$root_out_dir/breakpad_symbols"
|
||||
|
||||
if (host_os == "win") {
|
||||
_host_executable_suffix = ".exe"
|
||||
} else {
|
||||
_host_executable_suffix = ""
|
||||
}
|
||||
|
||||
template("extract_symbols") {
|
||||
action(target_name) {
|
||||
forward_variables_from(invoker,
|
||||
[
|
||||
"deps",
|
||||
"testonly",
|
||||
])
|
||||
assert(defined(invoker.binary), "Need binary to dump")
|
||||
assert(defined(invoker.symbol_dir), "Need directory for symbol output")
|
||||
|
||||
dump_syms_label = "//third_party/breakpad:dump_syms($host_toolchain)"
|
||||
dump_syms_binary = get_label_info(dump_syms_label, "root_out_dir") +
|
||||
"/dump_syms$_host_executable_suffix"
|
||||
|
||||
script = "//electron/build/dump_syms.py"
|
||||
inputs = [
|
||||
invoker.binary,
|
||||
dump_syms_binary,
|
||||
]
|
||||
stamp_file = "${target_gen_dir}/${target_name}.stamp"
|
||||
outputs = [
|
||||
stamp_file,
|
||||
]
|
||||
args = [
|
||||
"./" + rebase_path(dump_syms_binary, root_build_dir),
|
||||
rebase_path(invoker.binary, root_build_dir),
|
||||
rebase_path(invoker.symbol_dir, root_build_dir),
|
||||
rebase_path(stamp_file, root_build_dir),
|
||||
]
|
||||
if (defined(invoker.dsym_file)) {
|
||||
args += [ rebase_path(invoker.dsym_file, root_build_dir) ]
|
||||
}
|
||||
|
||||
if (!defined(deps)) {
|
||||
deps = []
|
||||
}
|
||||
deps += [ dump_syms_label ]
|
||||
}
|
||||
}
|
||||
@@ -5,13 +5,15 @@ import sys
|
||||
import zipfile
|
||||
|
||||
EXTENSIONS_TO_SKIP = [
|
||||
'.pdb'
|
||||
'.pdb',
|
||||
'.mojom.externs.js',
|
||||
'.mojom.js',
|
||||
]
|
||||
|
||||
PATHS_TO_SKIP = [
|
||||
'angledata', #Skipping because it is an output of //ui/gl that we don't need
|
||||
'./libVkLayer_', #Skipping because these are outputs that we don't need
|
||||
'./VkLayerLayer_', #Skipping because these are outputs that we don't need
|
||||
'./libVkICD_mock_', #Skipping because these are outputs that we don't need
|
||||
'./VkICD_mock_', #Skipping because these are outputs that we don't need
|
||||
|
||||
# //chrome/browser:resources depends on this via
|
||||
# //chrome/browser/resources/ssl/ssl_error_assistant, but we don't need to
|
||||
|
||||
@@ -86,6 +86,7 @@ function loadApplicationPackage (packagePath) {
|
||||
// Override app name and version.
|
||||
packagePath = path.resolve(packagePath)
|
||||
const packageJsonPath = path.join(packagePath, 'package.json')
|
||||
let appPath
|
||||
if (fs.existsSync(packageJsonPath)) {
|
||||
let packageJson
|
||||
try {
|
||||
@@ -105,11 +106,12 @@ function loadApplicationPackage (packagePath) {
|
||||
}
|
||||
app.setPath('userData', path.join(app.getPath('appData'), app.getName()))
|
||||
app.setPath('userCache', path.join(app.getPath('cache'), app.getName()))
|
||||
app.setAppPath(packagePath)
|
||||
appPath = packagePath
|
||||
}
|
||||
|
||||
try {
|
||||
Module._resolveFilename(packagePath, module, true)
|
||||
const filePath = Module._resolveFilename(packagePath, module, true)
|
||||
app.setAppPath(appPath || path.dirname(filePath))
|
||||
} catch (e) {
|
||||
showErrorMessage(`Unable to find Electron app at ${packagePath}\n\n${e.message}`)
|
||||
return
|
||||
|
||||
@@ -26,11 +26,18 @@ function initialize () {
|
||||
link.addEventListener('auxclick', openLinkExternally)
|
||||
}
|
||||
|
||||
document.querySelector('.electron-version').innerText = `Electron v${process.versions.electron}`
|
||||
document.querySelector('.chrome-version').innerText = `Chromium v${process.versions.chrome}`
|
||||
document.querySelector('.node-version').innerText = `Node v${process.versions.node}`
|
||||
document.querySelector('.v8-version').innerText = `v8 v${process.versions.v8}`
|
||||
document.querySelector('.command-example').innerText = `${electronPath} path-to-app`
|
||||
function replaceText (selector, text) {
|
||||
const element = document.querySelector(selector)
|
||||
if (element) {
|
||||
element.innerText = text
|
||||
}
|
||||
}
|
||||
|
||||
replaceText('.electron-version', `Electron v${process.versions.electron}`)
|
||||
replaceText('.chrome-version', `Chromium v${process.versions.chrome}`)
|
||||
replaceText('.node-version', `Node v${process.versions.node}`)
|
||||
replaceText('.v8-version', `v8 v${process.versions.v8}`)
|
||||
replaceText('.command-example', `${electronPath} path-to-app`)
|
||||
|
||||
function getOcticonSvg (name) {
|
||||
const octiconPath = path.resolve(__dirname, 'node_modules', 'octicons', 'build', 'svg', `${name}.svg`)
|
||||
|
||||
@@ -1261,6 +1261,15 @@ Sets the `image` associated with this dock icon.
|
||||
|
||||
## Properties
|
||||
|
||||
### `app.userAgentFallback`
|
||||
|
||||
A `String` which is the user agent string Electron will use as a global fallback.
|
||||
|
||||
This is the user agent that will be used when no user agent is set at the
|
||||
`webContents` or `session` level. Useful for ensuring your entire
|
||||
app has the same user agent. Set to a custom value as early as possible
|
||||
in your apps initialization to ensure that your overridden value is used.
|
||||
|
||||
### `app.isPackaged`
|
||||
|
||||
A `Boolean` property that returns `true` if the app is packaged, `false` otherwise. For many apps, this property can be used to distinguish development and production environments.
|
||||
|
||||
@@ -406,9 +406,11 @@ Returns:
|
||||
|
||||
* `event` Event
|
||||
* `title` String
|
||||
* `explicitSet` Boolean
|
||||
|
||||
Emitted when the document changed its title, calling `event.preventDefault()`
|
||||
will prevent the native window's title from changing.
|
||||
`explicitSet` is false when title is synthesized from file url.
|
||||
|
||||
#### Event: 'close'
|
||||
|
||||
@@ -901,17 +903,17 @@ Resizes and moves the window to the supplied bounds. Any properties that are not
|
||||
```javascript
|
||||
const { BrowserWindow } = require('electron')
|
||||
const win = new BrowserWindow()
|
||||
// set all bounds properties
|
||||
// set all bounds properties
|
||||
win.setBounds({ x: 440, y: 225, width: 800, height: 600 })
|
||||
// set a single bounds property
|
||||
// set a single bounds property
|
||||
win.setBounds({ width: 200 })
|
||||
// { x: 440, y: 225, width: 200, height: 600 }
|
||||
// { x: 440, y: 225, width: 200, height: 600 }
|
||||
console.log(win.getBounds())
|
||||
```
|
||||
|
||||
#### `win.getBounds()`
|
||||
|
||||
Returns [`Rectangle`](structures/rectangle.md)
|
||||
Returns [`Rectangle`](structures/rectangle.md) - The `bounds` of the window as `Object`.
|
||||
|
||||
#### `win.setContentBounds(bounds[, animate])`
|
||||
|
||||
@@ -923,7 +925,7 @@ the supplied bounds.
|
||||
|
||||
#### `win.getContentBounds()`
|
||||
|
||||
Returns [`Rectangle`](structures/rectangle.md)
|
||||
Returns [`Rectangle`](structures/rectangle.md) - The `bounds` of the window's client area as `Object`.
|
||||
|
||||
#### `win.getNormalBounds()`
|
||||
|
||||
|
||||
@@ -79,7 +79,7 @@ with `callback(error, cookies)` on complete.
|
||||
* `url` String - The url to associate the cookie with.
|
||||
* `name` String (optional) - The name of the cookie. Empty by default if omitted.
|
||||
* `value` String (optional) - The value of the cookie. Empty by default if omitted.
|
||||
* `domain` String (optional) - The domain of the cookie. Empty by default if omitted.
|
||||
* `domain` String (optional) - The domain of the cookie; this will be normalized with a preceding dot so that it's also valid for subdomains. Empty by default if omitted.
|
||||
* `path` String (optional) - The path of the cookie. Empty by default if omitted.
|
||||
* `secure` Boolean (optional) - Whether the cookie should be marked as Secure. Defaults to
|
||||
false.
|
||||
|
||||
@@ -92,3 +92,9 @@ objects, each `DesktopCapturerSource` represents a screen or an individual windo
|
||||
captured.
|
||||
|
||||
[`navigator.mediaDevices.getUserMedia`]: https://developer.mozilla.org/en/docs/Web/API/MediaDevices/getUserMedia
|
||||
|
||||
### Caveats
|
||||
|
||||
`navigator.mediaDevices.getUserMedia` does not work on macOS for audio capture due to a fundamental limitation whereby apps that want to access the system's audio require a [signed kernel extension](https://developer.apple.com/library/archive/documentation/Security/Conceptual/System_Integrity_Protection_Guide/KernelExtensions/KernelExtensions.html). Chromium, and by extension Electron, does not provide this.
|
||||
|
||||
It is possible to circumvent this limitation by capturing system audio with another macOS app like Soundflower and passing it through a virtual audio input device. This virtual device can then be queried with `navigator.mediaDevices.getUserMedia`.
|
||||
@@ -185,6 +185,12 @@ The `hslShift` is applied to the image with the following rules
|
||||
This means that `[-1, 0, 1]` will make the image completely white and
|
||||
`[-1, 1, 0]` will make the image completely black.
|
||||
|
||||
In some cases, the `NSImageName` doesn't match its string representation; one example of this is `NSFolderImageName`, whose string representation would actually be `NSFolder`. Therefore, you'll need to determine the correct string representation for your image before passing it in. This can be done with the following:
|
||||
|
||||
`echo -e '#import <Cocoa/Cocoa.h>\nint main() { NSLog(@"%@", SYSTEM_IMAGE_NAME); }' | clang -otest -x objective-c -framework Cocoa - && ./test`
|
||||
|
||||
where `SYSTEM_IMAGE_NAME` should be replaced with any value from [this list](https://developer.apple.com/documentation/appkit/nsimagename?language=objc).
|
||||
|
||||
## Class: NativeImage
|
||||
|
||||
> Natively wrap images such as tray, dock, and application icons.
|
||||
|
||||
@@ -59,7 +59,7 @@ Emitted as soon as the systems screen is unlocked.
|
||||
|
||||
The `powerMonitor` module has the following methods:
|
||||
|
||||
#### `powerMonitor.querySystemIdleState(idleThreshold, callback)`
|
||||
### `powerMonitor.querySystemIdleState(idleThreshold, callback)`
|
||||
|
||||
* `idleThreshold` Integer
|
||||
* `callback` Function
|
||||
@@ -70,7 +70,7 @@ before considered idle. `callback` will be called synchronously on some systems
|
||||
and with an `idleState` argument that describes the system's state. `locked` is
|
||||
available on supported systems only.
|
||||
|
||||
#### `powerMonitor.querySystemIdleTime(callback)`
|
||||
### `powerMonitor.querySystemIdleTime(callback)`
|
||||
|
||||
* `callback` Function
|
||||
* `idleTime` Integer - Idle time in seconds
|
||||
|
||||
@@ -288,15 +288,17 @@ win.webContents.session.setCertificateVerifyProc((request, callback) => {
|
||||
#### `ses.setPermissionRequestHandler(handler)`
|
||||
|
||||
* `handler` Function | null
|
||||
* `webContents` [WebContents](web-contents.md) - WebContents requesting the permission.
|
||||
* `webContents` [WebContents](web-contents.md) - WebContents requesting the permission. Please note that if the request comes from a subframe you should use `requestingUrl` to check the request origin.
|
||||
* `permission` String - Enum of 'media', 'geolocation', 'notifications', 'midiSysex',
|
||||
'pointerLock', 'fullscreen', 'openExternal'.
|
||||
* `callback` Function
|
||||
* `permissionGranted` Boolean - Allow or deny the permission.
|
||||
* `details` Object - Some properties are only available on certain permission types.
|
||||
* `externalURL` String - The url of the `openExternal` request.
|
||||
* `mediaTypes` String[] - The types of media access being requested, elements can be `video`
|
||||
* `externalURL` String (Optional) - The url of the `openExternal` request.
|
||||
* `mediaTypes` String[] (Optional) - The types of media access being requested, elements can be `video`
|
||||
or `audio`
|
||||
* `requestingUrl` String - The last URL the requesting frame loaded
|
||||
* `isMainFrame` Boolean - Whether the frame making the request is the main frame
|
||||
|
||||
Sets the handler which can be used to respond to permission requests for the `session`.
|
||||
Calling `callback(true)` will allow the permission and `callback(false)` will reject it.
|
||||
@@ -316,13 +318,15 @@ session.fromPartition('some-partition').setPermissionRequestHandler((webContents
|
||||
#### `ses.setPermissionCheckHandler(handler)`
|
||||
|
||||
* `handler` Function<Boolean> | null
|
||||
* `webContents` [WebContents](web-contents.md) - WebContents checking the permission.
|
||||
* `webContents` [WebContents](web-contents.md) - WebContents checking the permission. Please note that if the request comes from a subframe you should use `requestingUrl` to check the request origin.
|
||||
* `permission` String - Enum of 'media'.
|
||||
* `requestingOrigin` String - The origin URL of the permission check
|
||||
* `details` Object - Some properties are only available on certain permission types.
|
||||
* `securityOrigin` String - The security orign of the `media` check.
|
||||
* `mediaType` String - The type of media access being requested, can be `video`,
|
||||
`audio` or `unknown`
|
||||
* `requestingUrl` String - The last URL the requesting frame loaded
|
||||
* `isMainFrame` Boolean - Whether the frame making the request is the main frame
|
||||
|
||||
Sets the handler which can be used to respond to permission checks for the `session`.
|
||||
Returning `true` will allow the permission and `false` will reject it.
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
* `name` String - The name of the cookie.
|
||||
* `value` String - The value of the cookie.
|
||||
* `domain` String (optional) - The domain of the cookie.
|
||||
* `hostOnly` Boolean (optional) - Whether the cookie is a host-only cookie.
|
||||
* `domain` String (optional) - The domain of the cookie; this will be normalized with a preceding dot so that it's also valid for subdomains.
|
||||
* `hostOnly` Boolean (optional) - Whether the cookie is a host-only cookie; this will only be `true` if no domain was passed.
|
||||
* `path` String (optional) - The path of the cookie.
|
||||
* `secure` Boolean (optional) - Whether the cookie is marked as secure.
|
||||
* `httpOnly` Boolean (optional) - Whether the cookie is marked as HTTP only.
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
# MemoryInfo Object
|
||||
|
||||
* `pid` Integer - Process id of the process.
|
||||
* `workingSetSize` Integer - The amount of memory currently pinned to actual physical RAM.
|
||||
* `peakWorkingSetSize` Integer - The maximum amount of memory that has ever been pinned
|
||||
to actual physical RAM. On macOS its value will always be 0.
|
||||
* `privateBytes` Integer - The amount of memory not shared by other processes, such as
|
||||
JS heap or HTML content.
|
||||
* `sharedBytes` Integer - The amount of memory shared between processes, typically
|
||||
memory consumed by the Electron code itself
|
||||
|
||||
Note that all statistics are reported in Kilobytes.
|
||||
@@ -35,14 +35,6 @@ Returns:
|
||||
* `invertedColorScheme` Boolean - `true` if an inverted color scheme, such as
|
||||
a high contrast theme, is being used, `false` otherwise.
|
||||
|
||||
### Event: 'appearance-changed' _macOS_
|
||||
|
||||
Returns:
|
||||
|
||||
* `newAppearance` String - Can be `dark` or `light`
|
||||
|
||||
**NOTE:** This event is only emitted after you have called `startAppLevelAppearanceTrackingOS`
|
||||
|
||||
## Methods
|
||||
|
||||
### `systemPreferences.isDarkMode()` _macOS_
|
||||
|
||||
@@ -101,6 +101,17 @@ Returns:
|
||||
|
||||
Emitted when the document in the given frame is loaded.
|
||||
|
||||
#### Event: 'page-title-updated'
|
||||
|
||||
Returns:
|
||||
|
||||
* `event` Event
|
||||
* `title` String
|
||||
* `explicitSet` Boolean
|
||||
|
||||
Fired when page title is set during navigation. `explicitSet` is false when
|
||||
title is synthesized from file url.
|
||||
|
||||
#### Event: 'page-favicon-updated'
|
||||
|
||||
Returns:
|
||||
@@ -138,11 +149,16 @@ new [`BrowserWindow`](browser-window.md). If you call `event.preventDefault()` a
|
||||
instance, failing to do so may result in unexpected behavior. For example:
|
||||
|
||||
```javascript
|
||||
myBrowserWindow.webContents.on('new-window', (event, url) => {
|
||||
myBrowserWindow.webContents.on('new-window', (event, url, frameName, disposition, options) => {
|
||||
event.preventDefault()
|
||||
const win = new BrowserWindow({ show: false })
|
||||
const win = new BrowserWindow({
|
||||
webContents: options.webContents, // use existing webContents if provided
|
||||
show: false
|
||||
})
|
||||
win.once('ready-to-show', () => win.show())
|
||||
win.loadURL(url)
|
||||
if (!options.webContents) {
|
||||
win.loadURL(url) // existing webContents will be navigated automatically
|
||||
}
|
||||
event.newGuest = win
|
||||
})
|
||||
```
|
||||
|
||||
@@ -866,10 +866,6 @@ ipcRenderer.on('ping', () => {
|
||||
|
||||
Fired when the renderer process is crashed.
|
||||
|
||||
### Event: 'gpu-crashed'
|
||||
|
||||
Fired when the gpu process is crashed.
|
||||
|
||||
### Event: 'plugin-crashed'
|
||||
|
||||
Returns:
|
||||
|
||||
@@ -36,7 +36,7 @@ Electron is used together with the installation and update framework Squirrel,
|
||||
[shortcuts will automatically be set correctly][squirrel-events]. Furthermore,
|
||||
Electron will detect that Squirrel was used and will automatically call
|
||||
`app.setAppUserModelId()` with the correct value. During development, you may have
|
||||
to call [`app.setAppUserModelId()`][[set-app-user-model-id]] yourself.
|
||||
to call [`app.setAppUserModelId()`][set-app-user-model-id] yourself.
|
||||
|
||||
Furthermore, in Windows 8, the maximum length for the notification body is 250
|
||||
characters, with the Windows team recommending that notifications should be kept
|
||||
|
||||
@@ -33,9 +33,26 @@ tools and resources.
|
||||
|
||||
## Supported Versions
|
||||
|
||||
The latest three release branches are supported by the Electron team.
|
||||
For example, if the latest release is 2.0.x, then the 2-0-x series
|
||||
is supported, as are the two previous release series 1-7-x and 1-8-x.
|
||||
The latest three major versions are supported by the Electron team.
|
||||
For example, if the latest release is 5.0.x, then the 4.x.y series
|
||||
is supported, as are the two previous release series 3.x.y and 2.x.y.
|
||||
|
||||
The latest stable release unilaterally receives all fixes from `master`,
|
||||
and the version prior to that receives the vast majority of those fixes
|
||||
as time and bandwidth warrants. The oldest supported release line will receive
|
||||
only security fixes directly.
|
||||
|
||||
All supported release lines will accept external pull requests to backport
|
||||
fixes previously merged to `master`, though this may be on a case-by-case
|
||||
basis for some older supported lines. All contested decisions around release
|
||||
line backports will be resolved by the [Releases Working Group](https://github.com/electron/governance/tree/master/wg-releases) as an agenda item at their weekly meeting the week the backport PR is raised.
|
||||
|
||||
### Currently supported versions
|
||||
- 5.x
|
||||
- 4.x
|
||||
- 3.x
|
||||
|
||||
### End-of-life
|
||||
|
||||
When a release branch reaches the end of its support cycle, the series
|
||||
will be deprecated in NPM and a final end-of-support release will be
|
||||
|
||||
@@ -40,18 +40,6 @@ Object.assign(app, {
|
||||
}
|
||||
})
|
||||
|
||||
const nativeFn = app.getAppMetrics
|
||||
app.getAppMetrics = () => {
|
||||
const metrics = nativeFn.call(app)
|
||||
for (const metric of metrics) {
|
||||
if ('memory' in metric) {
|
||||
deprecate.removeProperty(metric, 'memory')
|
||||
}
|
||||
}
|
||||
|
||||
return metrics
|
||||
}
|
||||
|
||||
app.isPackaged = (() => {
|
||||
const execFile = path.basename(process.execPath).toLowerCase()
|
||||
if (process.platform === 'win32') {
|
||||
|
||||
@@ -39,9 +39,9 @@ BrowserWindow.prototype._init = function () {
|
||||
})
|
||||
|
||||
// Change window title to page title.
|
||||
this.webContents.on('page-title-updated', (event, title) => {
|
||||
this.webContents.on('page-title-updated', (event, title, ...args) => {
|
||||
// Route the event to BrowserWindow.
|
||||
this.emit('page-title-updated', event, title)
|
||||
this.emit('page-title-updated', event, title, ...args)
|
||||
if (!this.isDestroyed() && !event.defaultPrevented) this.setTitle(title)
|
||||
})
|
||||
|
||||
|
||||
@@ -36,7 +36,6 @@ const supportedWebViewEvents = [
|
||||
'focus-change',
|
||||
'close',
|
||||
'crashed',
|
||||
'gpu-crashed',
|
||||
'plugin-crashed',
|
||||
'destroyed',
|
||||
'page-title-updated',
|
||||
@@ -119,7 +118,6 @@ const createGuest = function (embedder, params) {
|
||||
}
|
||||
this.loadURL(params.src, opts)
|
||||
}
|
||||
guest.allowPopups = params.allowpopups
|
||||
embedder.emit('did-attach-webview', event, guest)
|
||||
})
|
||||
|
||||
@@ -221,6 +219,7 @@ const attachGuest = function (event, embedderFrameId, elementInstanceId, guestIn
|
||||
enableRemoteModule: params.enableremotemodule,
|
||||
plugins: params.plugins,
|
||||
zoomFactor: embedder._getZoomFactor(),
|
||||
disablePopups: !params.allowpopups,
|
||||
webSecurity: !params.disablewebsecurity,
|
||||
enableBlinkFeatures: params.blinkfeatures,
|
||||
disableBlinkFeatures: params.disableblinkfeatures
|
||||
@@ -242,11 +241,6 @@ const attachGuest = function (event, embedderFrameId, elementInstanceId, guestIn
|
||||
webPreferences.preloadURL = params.preload
|
||||
}
|
||||
|
||||
// Return null from native window.open if allowpopups is unset
|
||||
if (webPreferences.nativeWindowOpen === true && !params.allowpopups) {
|
||||
webPreferences.disablePopups = true
|
||||
}
|
||||
|
||||
// Security options that guest will always inherit from embedder
|
||||
const inheritedWebPreferences = new Map([
|
||||
['contextIsolation', true],
|
||||
|
||||
@@ -171,20 +171,27 @@ const getGuestWindow = function (guestContents) {
|
||||
return guestWindow
|
||||
}
|
||||
|
||||
const isChildWindow = function (sender, target) {
|
||||
return target.getLastWebPreferences().openerId === sender.id
|
||||
}
|
||||
|
||||
const isRelatedWindow = function (sender, target) {
|
||||
return isChildWindow(sender, target) || isChildWindow(target, sender)
|
||||
}
|
||||
|
||||
const isScriptableWindow = function (sender, target) {
|
||||
return isRelatedWindow(sender, target) && isSameOrigin(sender.getURL(), target.getURL())
|
||||
}
|
||||
|
||||
const isNodeIntegrationEnabled = function (sender) {
|
||||
return sender.getLastWebPreferences().nodeIntegration === true
|
||||
}
|
||||
|
||||
// Checks whether |sender| can access the |target|:
|
||||
// 1. Check whether |sender| is the parent of |target|.
|
||||
// 2. Check whether |sender| has node integration, if so it is allowed to
|
||||
// do anything it wants.
|
||||
// 3. Check whether the origins match.
|
||||
//
|
||||
// However it allows a child window without node integration but with same
|
||||
// origin to do anything it wants, when its opener window has node integration.
|
||||
// The W3C does not have anything on this, but from my understanding of the
|
||||
// security model of |window.opener|, this should be fine.
|
||||
const canAccessWindow = function (sender, target) {
|
||||
return (target.getLastWebPreferences().openerId === sender.id) ||
|
||||
(sender.getLastWebPreferences().nodeIntegration === true) ||
|
||||
isSameOrigin(sender.getURL(), target.getURL())
|
||||
return isChildWindow(sender, target) ||
|
||||
isScriptableWindow(sender, target) ||
|
||||
isNodeIntegrationEnabled(sender)
|
||||
}
|
||||
|
||||
// Routed window.open messages with raw options
|
||||
@@ -259,7 +266,7 @@ ipcMain.on('ELECTRON_GUEST_WINDOW_MANAGER_INTERNAL_WINDOW_OPEN', function (event
|
||||
options = mergeBrowserWindowOptions(event.sender, options)
|
||||
event.sender.emit('new-window', event, url, frameName, disposition, options, additionalFeatures, referrer)
|
||||
const { newGuest } = event
|
||||
if ((event.sender.isGuest() && !event.sender.allowPopups) || event.defaultPrevented) {
|
||||
if ((event.sender.isGuest() && event.sender.getLastWebPreferences().disablePopups) || event.defaultPrevented) {
|
||||
if (newGuest != null) {
|
||||
if (options.webContents === newGuest.webContents) {
|
||||
// the webContents is not changed, so set defaultPrevented to false to
|
||||
|
||||
@@ -490,20 +490,27 @@ ipcMain.on('ELECTRON_BROWSER_CLIPBOARD_WRITE_FIND_TEXT', function (event, text)
|
||||
setReturnValue(event, () => electron.clipboard.writeFindText(text))
|
||||
})
|
||||
|
||||
ipcMain.on('ELECTRON_BROWSER_SANDBOX_LOAD', function (event) {
|
||||
const preloadPath = event.sender._getPreloadPath()
|
||||
const getPreloadScript = function (preloadPath) {
|
||||
let preloadSrc = null
|
||||
let preloadError = null
|
||||
if (preloadPath) {
|
||||
try {
|
||||
preloadSrc = fs.readFileSync(preloadPath).toString()
|
||||
} catch (err) {
|
||||
preloadError = { stack: err ? err.stack : (new Error(`Failed to load "${preloadPath}"`)).stack }
|
||||
preloadError = errorUtils.serialize(err)
|
||||
}
|
||||
}
|
||||
return { preloadPath, preloadSrc, preloadError }
|
||||
}
|
||||
|
||||
ipcMain.on('ELECTRON_BROWSER_SANDBOX_LOAD', function (event) {
|
||||
const preloadPaths = [
|
||||
...(event.sender.session ? event.sender.session.getPreloads() : []),
|
||||
event.sender._getPreloadPath()
|
||||
]
|
||||
|
||||
event.returnValue = {
|
||||
preloadSrc,
|
||||
preloadError,
|
||||
preloadScripts: preloadPaths.map(path => getPreloadScript(path)),
|
||||
isRemoteModuleEnabled: event.sender._isRemoteModuleEnabled(),
|
||||
process: {
|
||||
arch: process.arch,
|
||||
|
||||
@@ -30,16 +30,20 @@ function wrap (func, wrapper) {
|
||||
|
||||
process.nextTick = wrapWithActivateUvLoop(process.nextTick)
|
||||
|
||||
global.setImmediate = wrapWithActivateUvLoop(timers.setImmediate)
|
||||
global.setImmediate = timers.setImmediate = wrapWithActivateUvLoop(timers.setImmediate)
|
||||
global.clearImmediate = timers.clearImmediate
|
||||
|
||||
// setTimeout needs to update the polling timeout of the event loop, when
|
||||
// called under Chromium's event loop the node's event loop won't get a chance
|
||||
// to update the timeout, so we have to force the node's event loop to
|
||||
// recalculate the timeout in browser process.
|
||||
timers.setTimeout = wrapWithActivateUvLoop(timers.setTimeout)
|
||||
timers.setInterval = wrapWithActivateUvLoop(timers.setInterval)
|
||||
|
||||
// Only override the global setTimeout/setInterval impls in the browser process
|
||||
if (process.type === 'browser') {
|
||||
// setTimeout needs to update the polling timeout of the event loop, when
|
||||
// called under Chromium's event loop the node's event loop won't get a chance
|
||||
// to update the timeout, so we have to force the node's event loop to
|
||||
// recalculate the timeout in browser process.
|
||||
global.setTimeout = wrapWithActivateUvLoop(timers.setTimeout)
|
||||
global.setInterval = wrapWithActivateUvLoop(timers.setInterval)
|
||||
global.setTimeout = timers.setTimeout
|
||||
global.setInterval = timers.setInterval
|
||||
}
|
||||
|
||||
if (process.platform === 'win32') {
|
||||
|
||||
@@ -28,7 +28,6 @@ const WEB_VIEW_EVENTS = {
|
||||
'focus-change': ['focus', 'guestInstanceId'],
|
||||
'close': [],
|
||||
'crashed': [],
|
||||
'gpu-crashed': [],
|
||||
'plugin-crashed': ['name', 'version'],
|
||||
'destroyed': [],
|
||||
'page-title-updated': ['title', 'explicitSet'],
|
||||
|
||||
@@ -58,12 +58,16 @@ ipcNative.onMessage = function (channel, args, senderId) {
|
||||
electron.ipcRenderer.emit(channel, { sender: electron.ipcRenderer, senderId }, ...args)
|
||||
}
|
||||
|
||||
ipcNative.onLoaded = function () {
|
||||
process.emit('loaded')
|
||||
}
|
||||
|
||||
ipcNative.onExit = function () {
|
||||
process.emit('exit')
|
||||
}
|
||||
|
||||
const {
|
||||
preloadSrc, preloadError, isRemoteModuleEnabled, process: processProps
|
||||
preloadScripts, isRemoteModuleEnabled, process: processProps
|
||||
} = ipcRenderer.sendSync('ELECTRON_BROWSER_SANDBOX_LOAD')
|
||||
|
||||
const makePropertyNonConfigurable = function (object, name) {
|
||||
@@ -90,6 +94,7 @@ Object.assign(preloadProcess, processProps)
|
||||
Object.assign(process, binding.process)
|
||||
Object.assign(process, processProps)
|
||||
|
||||
process.on('loaded', () => preloadProcess.emit('loaded'))
|
||||
process.on('exit', () => preloadProcess.emit('exit'))
|
||||
|
||||
// This is the `require` function that will be visible to the preload script
|
||||
@@ -100,7 +105,7 @@ function preloadRequire (module) {
|
||||
if (remoteModules.has(module)) {
|
||||
return require(module)
|
||||
}
|
||||
throw new Error('module not found')
|
||||
throw new Error(`module not found: ${module}`)
|
||||
}
|
||||
|
||||
switch (window.location.protocol) {
|
||||
@@ -126,6 +131,8 @@ if (!process.guestInstanceId && preloadProcess.argv.includes('--webview-tag=true
|
||||
require('@electron/internal/renderer/web-view/web-view').setupWebView(window)
|
||||
}
|
||||
|
||||
const errorUtils = require('@electron/internal/common/error-utils')
|
||||
|
||||
// Wrap the script into a function executed in global scope. It won't have
|
||||
// access to the current scope, so we'll expose a few objects as arguments:
|
||||
//
|
||||
@@ -145,7 +152,7 @@ if (!process.guestInstanceId && preloadProcess.argv.includes('--webview-tag=true
|
||||
// and any `require('electron')` calls in `preload.js` will work as expected
|
||||
// since browserify won't try to include `electron` in the bundle, falling back
|
||||
// to the `preloadRequire` function above.
|
||||
if (preloadSrc) {
|
||||
function runPreloadScript (preloadSrc) {
|
||||
const preloadWrapperSrc = `(function(require, process, Buffer, global, setImmediate, clearImmediate) {
|
||||
${preloadSrc}
|
||||
})`
|
||||
@@ -153,9 +160,21 @@ if (preloadSrc) {
|
||||
// eval in window scope
|
||||
const preloadFn = binding.createPreloadScript(preloadWrapperSrc)
|
||||
const { setImmediate, clearImmediate } = require('timers')
|
||||
|
||||
preloadFn(preloadRequire, preloadProcess, Buffer, global, setImmediate, clearImmediate)
|
||||
} else if (preloadError) {
|
||||
console.error(preloadError.stack)
|
||||
}
|
||||
|
||||
for (const { preloadPath, preloadSrc, preloadError } of preloadScripts) {
|
||||
try {
|
||||
if (preloadSrc) {
|
||||
runPreloadScript(preloadSrc)
|
||||
} else if (preloadError) {
|
||||
throw errorUtils.deserialize(preloadError)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`Unable to load preload script: ${preloadPath}`)
|
||||
console.error(`${error}`)
|
||||
}
|
||||
}
|
||||
|
||||
// Warn about security issues
|
||||
|
||||
9
package-lock.json
generated
9
package-lock.json
generated
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "electron",
|
||||
"version": "4.1.2",
|
||||
"version": "4.2.11",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
@@ -244,6 +244,7 @@
|
||||
"resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz",
|
||||
"integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"kind-of": "^3.0.2",
|
||||
"longest": "^1.0.1",
|
||||
@@ -2142,7 +2143,8 @@
|
||||
"version": "0.3.4",
|
||||
"resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.4.tgz",
|
||||
"integrity": "sha512-+7prCSORpXNeR4/fUP3rL+TzqtiFfhMvTd7uEqMdgPvLPt4+uzFUeufx5RHjGTACCargg/DiEt/moMQmvnfkog==",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"cssstyle": {
|
||||
"version": "0.2.37",
|
||||
@@ -6600,7 +6602,8 @@
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz",
|
||||
"integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"longest-streak": {
|
||||
"version": "2.0.2",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "electron",
|
||||
"version": "4.1.2",
|
||||
"version": "4.2.11",
|
||||
"repository": "https://github.com/electron/electron",
|
||||
"description": "Build cross platform desktop apps with JavaScript, HTML, and CSS",
|
||||
"devDependencies": {
|
||||
|
||||
@@ -3,3 +3,4 @@ expose_ripemd160.patch
|
||||
expose_aes-cfb.patch
|
||||
sync_sorted_ciphers.patch
|
||||
handle_pub_key_null_in_ec_key_set_public_key.patch
|
||||
add_a_compatibility_evp_ciph_ocb_mode_value.patch
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: David Benjamin <davidben@google.com>
|
||||
Date: Sun, 14 Oct 2018 11:01:40 -0500
|
||||
Subject: Add a compatibility EVP_CIPH_OCB_MODE value.
|
||||
|
||||
Node references it these days. Also replace the no-op modes with negative
|
||||
numbers rather than zero. Stream ciphers like RC4 report a "mode" of zero, so
|
||||
code comparing the mode to a dummy value will get confused.
|
||||
|
||||
(I came across https://github.com/nodejs/node/pull/23635, though we'd have run
|
||||
into it sooner or later anyway. Better to just define the value and avoid ifdef
|
||||
proliferation.)
|
||||
|
||||
Change-Id: I223f25663e138480ad83f35aa16f5218f1425563
|
||||
Reviewed-on: https://boringssl-review.googlesource.com/c/32464
|
||||
Reviewed-by: Adam Langley <agl@google.com>
|
||||
Commit-Queue: Adam Langley <agl@google.com>
|
||||
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
|
||||
|
||||
diff --git a/include/openssl/cipher.h b/include/openssl/cipher.h
|
||||
index e2ab9449275a62ee8a93bd48284b39e8df88a14f..7d4d78b3730022fb61ae63c6d3a86a61cb0c91e2 100644
|
||||
--- a/include/openssl/cipher.h
|
||||
+++ b/include/openssl/cipher.h
|
||||
@@ -425,8 +425,9 @@ OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_256_cfb128(void);
|
||||
|
||||
// The following flags do nothing and are included only to make it easier to
|
||||
// compile code with BoringSSL.
|
||||
-#define EVP_CIPH_CCM_MODE 0
|
||||
-#define EVP_CIPH_WRAP_MODE 0
|
||||
+#define EVP_CIPH_CCM_MODE (-1)
|
||||
+#define EVP_CIPH_OCB_MODE (-2)
|
||||
+#define EVP_CIPH_WRAP_MODE (-3)
|
||||
#define EVP_CIPHER_CTX_FLAG_WRAP_ALLOW 0
|
||||
|
||||
// EVP_CIPHER_CTX_set_flags does nothing.
|
||||
@@ -71,7 +71,7 @@ index acc4719b7e9c4c4461fc6142f2ae9156b407915b..8b008a401ec2f2d0673f6876609dd578
|
||||
callback(EVP_aes_256_ecb(), "aes-256-ecb", NULL, arg);
|
||||
callback(EVP_aes_256_ofb(), "aes-256-ofb", NULL, arg);
|
||||
diff --git a/include/openssl/cipher.h b/include/openssl/cipher.h
|
||||
index 59634138cb60237f008eb99e7d8df54da7629c1a..b30b8434b301fb5b8630ae954698b6fee255df77 100644
|
||||
index 7d99d49ba7ae2d8a4eb80681cbd9b41eee86bac7..e2ab9449275a62ee8a93bd48284b39e8df88a14f 100644
|
||||
--- a/include/openssl/cipher.h
|
||||
+++ b/include/openssl/cipher.h
|
||||
@@ -421,6 +421,7 @@ OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_192_ofb(void);
|
||||
|
||||
@@ -80,7 +80,7 @@ index 38b8f9f78f76050174096740596ac59a0fe18757..acc4719b7e9c4c4461fc6142f2ae9156
|
||||
+ callback(EVP_ripemd160(), "ripemd160", NULL, arg);
|
||||
}
|
||||
diff --git a/include/openssl/digest.h b/include/openssl/digest.h
|
||||
index 1a1ca29732afae317c8e8740c629e8922fc83093..48ebdd1eb93b3febecddbc2545b7aae583f21525 100644
|
||||
index 4077d902a07c215659ed61b54a468231536d70ee..f15df35d16402256fa00263e2c2e71d55ce67d1a 100644
|
||||
--- a/include/openssl/digest.h
|
||||
+++ b/include/openssl/digest.h
|
||||
@@ -88,6 +88,9 @@ OPENSSL_EXPORT const EVP_MD *EVP_sha512(void);
|
||||
|
||||
@@ -5,7 +5,7 @@ Subject: handle pub_key == null in EC_KEY_set_public_key
|
||||
|
||||
|
||||
diff --git a/crypto/fipsmodule/ec/ec_key.c b/crypto/fipsmodule/ec/ec_key.c
|
||||
index 4bc12a073650f66f5ae8ba2beabb9a6fb2b21878..7e86ccb0d76c66f32fc05c7093c870d5da7b9994 100644
|
||||
index a6d469767adfad1c9095cc58c567b10c71e95cfa..d1f754afeba102208c668f3678f64abed666cd64 100644
|
||||
--- a/crypto/fipsmodule/ec/ec_key.c
|
||||
+++ b/crypto/fipsmodule/ec/ec_key.c
|
||||
@@ -267,7 +267,7 @@ int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub_key) {
|
||||
|
||||
@@ -14,10 +14,10 @@ Commit-Queue: David Benjamin <davidben@google.com>
|
||||
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
|
||||
|
||||
diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h
|
||||
index ae8b8385fc73701a4346202f213b5974af4e2aed..0f3d1747173ffb09eafd5c7d5d692ae3c35c9874 100644
|
||||
index f693030a8a7c4bf79dd791e1abd0e94f8e97a292..3fee95c0a89dc4a25da527e2ac9cc50bab9c35a6 100644
|
||||
--- a/include/openssl/ssl.h
|
||||
+++ b/include/openssl/ssl.h
|
||||
@@ -4268,6 +4268,14 @@ OPENSSL_EXPORT int OPENSSL_init_ssl(uint64_t opts,
|
||||
@@ -4293,6 +4293,14 @@ OPENSSL_EXPORT int OPENSSL_init_ssl(uint64_t opts,
|
||||
// Use |SSL_enable_ocsp_stapling| instead.
|
||||
OPENSSL_EXPORT int SSL_set_tlsext_status_type(SSL *ssl, int type);
|
||||
|
||||
@@ -33,10 +33,10 @@ index ae8b8385fc73701a4346202f213b5974af4e2aed..0f3d1747173ffb09eafd5c7d5d692ae3
|
||||
// success and zero on error. On success, |ssl| takes ownership of |resp|, which
|
||||
// must have been allocated by |OPENSSL_malloc|.
|
||||
diff --git a/ssl/ssl_lib.cc b/ssl/ssl_lib.cc
|
||||
index 9c16de4958ef29d638e05e0f90b9b15b11b15cac..1f648658b8cb6ae7b82132b276b927e8fb11a47a 100644
|
||||
index c68968a514b76717d4c42448ef4b9c440c330fb2..547be0229e2c60c8aefb4644bc84e96f5a17c7f3 100644
|
||||
--- a/ssl/ssl_lib.cc
|
||||
+++ b/ssl/ssl_lib.cc
|
||||
@@ -2751,6 +2751,19 @@ int SSL_set_tlsext_status_type(SSL *ssl, int type) {
|
||||
@@ -2896,6 +2896,19 @@ int SSL_set_tlsext_status_type(SSL *ssl, int type) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -94,3 +94,21 @@ enable_inputpane_virtual_keyboard_functionality_by_default.patch
|
||||
merge_m72_filereader_make_a_copy_of_the_arraybuffer_when_returning.patch
|
||||
fix_system_tray_icons_being_cropped_under_kde.patch
|
||||
set_proper_permissions_for_package_s_framework_directory.patch
|
||||
intersection-observer.patch
|
||||
keyboard-lock-service-impl.patch
|
||||
make_--explicitly-allowed-ports_work_with_networkservice.patch
|
||||
fix_crashes_in_renderframeimpl_onselectpopupmenuitem_s.patch
|
||||
fix_re-entracy_problem_with_invalidateframesinkid.patch
|
||||
chore_expose_getcontentclient_to_embedders.patch
|
||||
tabbed_window_lagging.patch
|
||||
restore_live_region_changed_events_for_processing_by_jaws_focus_mode.patch
|
||||
enable_quic_proxies_for_https_urls.patch
|
||||
fix_svg_crash_for_v0_distribution_into_foreignobject.patch
|
||||
filesystem_harden_against_overflows_of_operationid_a_bit_better.patch
|
||||
fix_uap_in_imagebitmaploader_filereaderloader.patch
|
||||
fire_caret_location_change_when_focus_moves_from_ui_to_content.patch
|
||||
do_not_show_virtual_keyboard_for_all_mouse_inputs.patch
|
||||
setup_the_observer_before_calling_displayvirtualkeyboard.patch
|
||||
workaround_apparent_data_corruption_in_blockfile_on_os_x_10_14_by.patch
|
||||
mediacontrols_disconnect_observers_when_controls_are_hidden.patch
|
||||
fix_add_more_checks_in_mojocdmservice.patch
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Samuel Attard <sattard@slack-corp.com>
|
||||
Date: Wed, 1 May 2019 18:04:41 -0700
|
||||
Subject: chore: expose GetContentClient to embedders
|
||||
|
||||
|
||||
diff --git a/content/public/common/content_client.h b/content/public/common/content_client.h
|
||||
index 528fd6abf6a623b8076803fddf5616d88f0978e8..e03bfeff5dabd55fe548ba828ae30065ba3f42d6 100644
|
||||
--- a/content/public/common/content_client.h
|
||||
+++ b/content/public/common/content_client.h
|
||||
@@ -58,10 +58,10 @@ struct PepperPluginInfo;
|
||||
// content code is called.
|
||||
CONTENT_EXPORT void SetContentClient(ContentClient* client);
|
||||
|
||||
-#if defined(CONTENT_IMPLEMENTATION)
|
||||
+//#if defined(CONTENT_IMPLEMENTATION)
|
||||
// Content's embedder API should only be used by content.
|
||||
-ContentClient* GetContentClient();
|
||||
-#endif
|
||||
+CONTENT_EXPORT ContentClient* GetContentClient();
|
||||
+//#endif
|
||||
|
||||
// Used for tests to override the relevant embedder interfaces. Each method
|
||||
// returns the old value.
|
||||
@@ -0,0 +1,253 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Lan Wei <lanwei@chromium.org>
|
||||
Date: Tue, 11 Sep 2018 19:41:33 +0000
|
||||
Subject: Do not show virtual keyboard for all mouse inputs
|
||||
|
||||
We have an issue that Windows virtual Keyboard appears whenever a text
|
||||
area is selected with the mouse or keyboard. Since we decide to only
|
||||
show the virtual keyboard when the input type is touch.
|
||||
|
||||
Bug: 871756
|
||||
Change-Id: Ia804afad907341ed478409d223b67f09c6b7f8f3
|
||||
Reviewed-on: https://chromium-review.googlesource.com/1194406
|
||||
Reviewed-by: Pavel Feldman <pfeldman@chromium.org>
|
||||
Reviewed-by: Marc Treib <treib@chromium.org>
|
||||
Reviewed-by: Keigo Oka <oka@chromium.org>
|
||||
Reviewed-by: Lei Zhang <thestig@chromium.org>
|
||||
Reviewed-by: Navid Zolghadr <nzolghadr@chromium.org>
|
||||
Reviewed-by: Sadrul Chowdhury <sadrul@chromium.org>
|
||||
Commit-Queue: Lan Wei <lanwei@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/master@{#590440}
|
||||
|
||||
diff --git a/chrome/browser/renderer_host/site_per_process_text_input_browsertest.cc b/chrome/browser/renderer_host/site_per_process_text_input_browsertest.cc
|
||||
index 5c8bdc8c73dc2047175f16c658428c9f2c038412..f7c8c33b3d6764116e0713244e446356873e015f 100644
|
||||
--- a/chrome/browser/renderer_host/site_per_process_text_input_browsertest.cc
|
||||
+++ b/chrome/browser/renderer_host/site_per_process_text_input_browsertest.cc
|
||||
@@ -1154,6 +1154,9 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessTextInputManagerTest,
|
||||
|
||||
// Set |TextInputState.show_ime_if_needed| to true. Expect IME.
|
||||
sender.SetShowVirtualKeyboardIfEnabled(true);
|
||||
+#if defined(OS_WIN)
|
||||
+ sender.SetLastPointerType(ui::EventPointerType::POINTER_TYPE_TOUCH);
|
||||
+#endif
|
||||
EXPECT_TRUE(send_and_check_show_ime());
|
||||
|
||||
// Send the same message. Expect IME (no change).
|
||||
@@ -1171,6 +1174,12 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessTextInputManagerTest,
|
||||
sender.SetShowVirtualKeyboardIfEnabled(true);
|
||||
EXPECT_TRUE(send_and_check_show_ime());
|
||||
|
||||
+#if defined(OS_WIN)
|
||||
+ // Set input type to mouse. Expect no IME.
|
||||
+ sender.SetLastPointerType(ui::EventPointerType::POINTER_TYPE_MOUSE);
|
||||
+ EXPECT_FALSE(send_and_check_show_ime());
|
||||
+#endif
|
||||
+
|
||||
// Set |TextInputState.type| to ui::TEXT_INPUT_TYPE_NONE. Expect no IME.
|
||||
sender.SetType(ui::TEXT_INPUT_TYPE_NONE);
|
||||
EXPECT_FALSE(send_and_check_show_ime());
|
||||
diff --git a/chrome/browser/ui/search/search_tab_helper.cc b/chrome/browser/ui/search/search_tab_helper.cc
|
||||
index 1445829a89caaeeea602cd050b9c3bf0161f5881..0bb77fbfee6a4c08ce261bbc4846c8ec0755b01a 100644
|
||||
--- a/chrome/browser/ui/search/search_tab_helper.cc
|
||||
+++ b/chrome/browser/ui/search/search_tab_helper.cc
|
||||
@@ -271,7 +271,9 @@ void SearchTabHelper::FocusOmnibox(OmniboxFocusState state) {
|
||||
// visual cue to users who really understand selection state about what
|
||||
// will happen if they start typing.
|
||||
omnibox_view->SelectAll(false);
|
||||
+#if !defined(OS_WIN)
|
||||
omnibox_view->ShowVirtualKeyboardIfEnabled();
|
||||
+#endif
|
||||
break;
|
||||
case OMNIBOX_FOCUS_NONE:
|
||||
// Remove focus only if the popup is closed. This will prevent someone
|
||||
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc
|
||||
index 0eec5c7a6861f189192ab0cf8b3dbb3b452292e0..de9490d94d98afa6812e81b0cf50fb4adc81887c 100644
|
||||
--- a/content/browser/renderer_host/render_widget_host_view_aura.cc
|
||||
+++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
|
||||
@@ -756,9 +756,11 @@ void RenderWidgetHostViewAura::FocusedNodeTouched(bool editable) {
|
||||
return;
|
||||
auto* controller = input_method->GetInputMethodKeyboardController();
|
||||
if (editable && host()->GetView() && host()->delegate()) {
|
||||
- keyboard_observer_.reset(new WinScreenKeyboardObserver(this));
|
||||
- if (!controller->DisplayVirtualKeyboard())
|
||||
- keyboard_observer_.reset(nullptr);
|
||||
+ keyboard_observer_.reset(nullptr);
|
||||
+ if (last_pointer_type_ == ui::EventPointerType::POINTER_TYPE_TOUCH &&
|
||||
+ controller->DisplayVirtualKeyboard()) {
|
||||
+ keyboard_observer_.reset(new WinScreenKeyboardObserver(this));
|
||||
+ }
|
||||
virtual_keyboard_requested_ = keyboard_observer_.get();
|
||||
} else {
|
||||
virtual_keyboard_requested_ = false;
|
||||
@@ -2341,9 +2343,16 @@ void RenderWidgetHostViewAura::OnUpdateTextInputStateCalled(
|
||||
const TextInputState* state = text_input_manager_->GetTextInputState();
|
||||
if (state && state->type != ui::TEXT_INPUT_TYPE_NONE &&
|
||||
state->mode != ui::TEXT_INPUT_MODE_NONE) {
|
||||
+ bool show_virtual_keyboard = true;
|
||||
+#if defined(OS_WIN)
|
||||
+ show_virtual_keyboard =
|
||||
+ last_pointer_type_ == ui::EventPointerType::POINTER_TYPE_TOUCH;
|
||||
+#endif
|
||||
if (state->show_ime_if_needed &&
|
||||
- GetInputMethod()->GetTextInputClient() == this)
|
||||
+ GetInputMethod()->GetTextInputClient() == this &&
|
||||
+ show_virtual_keyboard) {
|
||||
GetInputMethod()->ShowVirtualKeyboardIfEnabled();
|
||||
+ }
|
||||
// Ensure that accessibility events are fired when the selection location
|
||||
// moves from UI back to content.
|
||||
text_input_manager->NotifySelectionBoundsChanged(updated_view);
|
||||
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.h b/content/browser/renderer_host/render_widget_host_view_aura.h
|
||||
index 5f75e19c4a9fa8aaa57882dcbb094a73199f50d0..2257552851e933a06cb9addbee00e511573561ec 100644
|
||||
--- a/content/browser/renderer_host/render_widget_host_view_aura.h
|
||||
+++ b/content/browser/renderer_host/render_widget_host_view_aura.h
|
||||
@@ -342,6 +342,12 @@ class CONTENT_EXPORT RenderWidgetHostViewAura
|
||||
|
||||
void ScrollFocusedEditableNodeIntoRect(const gfx::Rect& rect);
|
||||
|
||||
+ // TODO(lanwei): Use TestApi interface to write functions that are used in
|
||||
+ // tests and remove FRIEND_TEST_ALL_PREFIXES.
|
||||
+ void SetLastPointerType(ui::EventPointerType last_pointer_type) {
|
||||
+ last_pointer_type_ = last_pointer_type;
|
||||
+ }
|
||||
+
|
||||
protected:
|
||||
~RenderWidgetHostViewAura() override;
|
||||
|
||||
@@ -408,6 +414,8 @@ class CONTENT_EXPORT RenderWidgetHostViewAura
|
||||
DiscardDelegatedFramesWithMemoryPressure);
|
||||
FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraKeyboardTest,
|
||||
KeyboardObserverDestroyed);
|
||||
+ FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraKeyboardTest,
|
||||
+ KeyboardObserverForOnlyTouchInput);
|
||||
FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraSurfaceSynchronizationTest,
|
||||
DropFallbackWhenHidden);
|
||||
FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraSurfaceSynchronizationTest,
|
||||
diff --git a/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc b/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc
|
||||
index 9aac9b4c740245727124991a750a36b54f3d7ac5..f7b9e13226b1896028044d389ace5383554b5dce 100644
|
||||
--- a/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc
|
||||
+++ b/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc
|
||||
@@ -6735,6 +6735,7 @@ class RenderWidgetHostViewAuraKeyboardTest
|
||||
};
|
||||
|
||||
TEST_F(RenderWidgetHostViewAuraKeyboardTest, KeyboardObserverDestroyed) {
|
||||
+ parent_view_->SetLastPointerType(ui::EventPointerType::POINTER_TYPE_TOUCH);
|
||||
parent_view_->FocusedNodeTouched(true);
|
||||
EXPECT_NE(parent_view_->keyboard_observer_.get(), nullptr);
|
||||
EXPECT_EQ(keyboard_controller_observer_count(), 1u);
|
||||
@@ -6744,6 +6745,20 @@ TEST_F(RenderWidgetHostViewAuraKeyboardTest, KeyboardObserverDestroyed) {
|
||||
EXPECT_EQ(keyboard_controller_observer_count(), 0u);
|
||||
}
|
||||
|
||||
+TEST_F(RenderWidgetHostViewAuraKeyboardTest,
|
||||
+ KeyboardObserverForOnlyTouchInput) {
|
||||
+ // Show virtual keyboard for touch inputs.
|
||||
+ parent_view_->SetLastPointerType(ui::EventPointerType::POINTER_TYPE_TOUCH);
|
||||
+ parent_view_->FocusedNodeTouched(true);
|
||||
+ EXPECT_NE(parent_view_->keyboard_observer_.get(), nullptr);
|
||||
+ EXPECT_EQ(keyboard_controller_observer_count(), 1u);
|
||||
+ // Do not show virtual keyboard for mouse inputs.
|
||||
+ parent_view_->SetLastPointerType(ui::EventPointerType::POINTER_TYPE_MOUSE);
|
||||
+ parent_view_->FocusedNodeTouched(true);
|
||||
+ EXPECT_EQ(parent_view_->keyboard_observer_.get(), nullptr);
|
||||
+ EXPECT_EQ(keyboard_controller_observer_count(), 0u);
|
||||
+}
|
||||
+
|
||||
#endif // defined(OS_WIN)
|
||||
|
||||
} // namespace content
|
||||
diff --git a/content/public/test/text_input_test_utils.cc b/content/public/test/text_input_test_utils.cc
|
||||
index 3d27041d9cfae4d87e4b2b26983f7a004ffc31d9..2d724b57c213052b184fc3b4c012bb0d8ad25b50 100644
|
||||
--- a/content/public/test/text_input_test_utils.cc
|
||||
+++ b/content/public/test/text_input_test_utils.cc
|
||||
@@ -186,7 +186,7 @@ class TestRenderWidgetHostViewDestructionObserver::InternalObserver
|
||||
DISALLOW_COPY_AND_ASSIGN(InternalObserver);
|
||||
};
|
||||
|
||||
-#ifdef USE_AURA
|
||||
+#if defined(USE_AURA)
|
||||
class InputMethodObserverAura : public TestInputMethodObserver,
|
||||
public ui::InputMethodObserver {
|
||||
public:
|
||||
@@ -453,6 +453,15 @@ void TextInputStateSender::SetShowVirtualKeyboardIfEnabled(
|
||||
text_input_state_->show_ime_if_needed = show_ime_if_needed;
|
||||
}
|
||||
|
||||
+#if defined(USE_AURA)
|
||||
+void TextInputStateSender::SetLastPointerType(
|
||||
+ ui::EventPointerType last_pointer_type) {
|
||||
+ RenderWidgetHostViewAura* rwhva =
|
||||
+ static_cast<RenderWidgetHostViewAura*>(view_);
|
||||
+ rwhva->SetLastPointerType(last_pointer_type);
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
TestInputMethodObserver::TestInputMethodObserver() {}
|
||||
|
||||
TestInputMethodObserver::~TestInputMethodObserver() {}
|
||||
@@ -462,7 +471,7 @@ std::unique_ptr<TestInputMethodObserver> TestInputMethodObserver::Create(
|
||||
WebContents* web_contents) {
|
||||
std::unique_ptr<TestInputMethodObserver> observer;
|
||||
|
||||
-#ifdef USE_AURA
|
||||
+#if defined(USE_AURA)
|
||||
RenderWidgetHostViewAura* view = static_cast<RenderWidgetHostViewAura*>(
|
||||
web_contents->GetRenderWidgetHostView());
|
||||
observer.reset(new InputMethodObserverAura(view->GetInputMethod()));
|
||||
diff --git a/content/public/test/text_input_test_utils.h b/content/public/test/text_input_test_utils.h
|
||||
index d438b72e176adbcb1240848c223596ffef2c558d..2bb337c19de138a106f8f3fe8c631aa8ca717df5 100644
|
||||
--- a/content/public/test/text_input_test_utils.h
|
||||
+++ b/content/public/test/text_input_test_utils.h
|
||||
@@ -17,6 +17,10 @@
|
||||
#include "content/public/browser/browser_message_filter.h"
|
||||
#endif
|
||||
|
||||
+#if defined(USE_AURA)
|
||||
+#include "ui/events/event_constants.h"
|
||||
+#endif
|
||||
+
|
||||
namespace ipc {
|
||||
class Message;
|
||||
}
|
||||
@@ -194,6 +198,9 @@ class TextInputStateSender {
|
||||
void SetFlags(int flags);
|
||||
void SetCanComposeInline(bool can_compose_inline);
|
||||
void SetShowVirtualKeyboardIfEnabled(bool show_ime_if_needed);
|
||||
+#if defined(USE_AURA)
|
||||
+ void SetLastPointerType(ui::EventPointerType last_pointer_type);
|
||||
+#endif
|
||||
|
||||
private:
|
||||
std::unique_ptr<TextInputState> text_input_state_;
|
||||
diff --git a/ui/views/controls/textfield/textfield.cc b/ui/views/controls/textfield/textfield.cc
|
||||
index c9a96b43788835476310c96b71b1ced21737a3c3..7963a4d1912eb8ba03d46dd353665f977680a2c5 100644
|
||||
--- a/ui/views/controls/textfield/textfield.cc
|
||||
+++ b/ui/views/controls/textfield/textfield.cc
|
||||
@@ -666,7 +666,9 @@ bool Textfield::OnMousePressed(const ui::MouseEvent& event) {
|
||||
(event.IsOnlyLeftMouseButton() || event.IsOnlyRightMouseButton())) {
|
||||
if (!had_focus)
|
||||
RequestFocusWithPointer(ui::EventPointerType::POINTER_TYPE_MOUSE);
|
||||
+#if !defined(OS_WIN)
|
||||
ShowVirtualKeyboardIfEnabled();
|
||||
+#endif
|
||||
}
|
||||
|
||||
#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
|
||||
@@ -743,10 +745,16 @@ bool Textfield::OnKeyReleased(const ui::KeyEvent& event) {
|
||||
}
|
||||
|
||||
void Textfield::OnGestureEvent(ui::GestureEvent* event) {
|
||||
+ bool show_virtual_keyboard = true;
|
||||
+#if defined(OS_WIN)
|
||||
+ show_virtual_keyboard = event->details().primary_pointer_type() ==
|
||||
+ ui::EventPointerType::POINTER_TYPE_TOUCH;
|
||||
+#endif
|
||||
switch (event->type()) {
|
||||
case ui::ET_GESTURE_TAP_DOWN:
|
||||
RequestFocusWithPointer(event->details().primary_pointer_type());
|
||||
- ShowVirtualKeyboardIfEnabled();
|
||||
+ if (show_virtual_keyboard)
|
||||
+ ShowVirtualKeyboardIfEnabled();
|
||||
event->SetHandled();
|
||||
break;
|
||||
case ui::ET_GESTURE_TAP:
|
||||
143
patches/common/chromium/enable_quic_proxies_for_https_urls.patch
Normal file
143
patches/common/chromium/enable_quic_proxies_for_https_urls.patch
Normal file
@@ -0,0 +1,143 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Milan Burda <milan.burda@gmail.com>
|
||||
Date: Sun, 31 Mar 2019 21:12:59 +0200
|
||||
Subject: Enable support for sending HTTPS URLs via QUIC proxies only when the
|
||||
finch param enable_quic_proxies_for_https_urls is set.
|
||||
|
||||
Backports:
|
||||
- https://chromium-review.googlesource.com/c/chromium/src/+/1377709
|
||||
- https://chromium-review.googlesource.com/c/chromium/src/+/1375112
|
||||
- https://chromium-review.googlesource.com/c/chromium/src/+/1417356
|
||||
|
||||
diff --git a/components/network_session_configurator/browser/network_session_configurator.cc b/components/network_session_configurator/browser/network_session_configurator.cc
|
||||
index 39fd430aafb358d465ba30120c30580672f95aa8..21d34cfab2c426ae367148433d21916fcd92c757 100644
|
||||
--- a/components/network_session_configurator/browser/network_session_configurator.cc
|
||||
+++ b/components/network_session_configurator/browser/network_session_configurator.cc
|
||||
@@ -143,6 +143,14 @@ bool ShouldEnableQuic(base::StringPiece quic_trial_group,
|
||||
GetVariationParam(quic_trial_params, "enable_quic"), "true");
|
||||
}
|
||||
|
||||
+bool ShouldEnableQuicProxiesForHttpsUrls(
|
||||
+ const VariationParameters& quic_trial_params) {
|
||||
+ return base::LowerCaseEqualsASCII(
|
||||
+ GetVariationParam(quic_trial_params,
|
||||
+ "enable_quic_proxies_for_https_urls"),
|
||||
+ "true");
|
||||
+}
|
||||
+
|
||||
bool ShouldMarkQuicBrokenWhenNetworkBlackholes(
|
||||
const VariationParameters& quic_trial_params) {
|
||||
return base::LowerCaseEqualsASCII(
|
||||
@@ -367,6 +375,8 @@ void ConfigureQuicParams(base::StringPiece quic_trial_group,
|
||||
ShouldSupportIetfFormatQuicAltSvc(quic_trial_params);
|
||||
|
||||
if (params->enable_quic) {
|
||||
+ params->enable_quic_proxies_for_https_urls =
|
||||
+ ShouldEnableQuicProxiesForHttpsUrls(quic_trial_params);
|
||||
params->quic_connection_options =
|
||||
GetQuicConnectionOptions(quic_trial_params);
|
||||
params->quic_client_connection_options =
|
||||
diff --git a/components/network_session_configurator/browser/network_session_configurator_unittest.cc b/components/network_session_configurator/browser/network_session_configurator_unittest.cc
|
||||
index 6235f7d927a82ebcc7a04792bc44e0675c8ced54..1e3f7b89c3c1ef5b3da2c89516acd13ac1ad283f 100644
|
||||
--- a/components/network_session_configurator/browser/network_session_configurator_unittest.cc
|
||||
+++ b/components/network_session_configurator/browser/network_session_configurator_unittest.cc
|
||||
@@ -67,6 +67,7 @@ TEST_F(NetworkSessionConfiguratorTest, Defaults) {
|
||||
EXPECT_FALSE(params_.enable_websocket_over_http2);
|
||||
|
||||
EXPECT_FALSE(params_.enable_quic);
|
||||
+ EXPECT_FALSE(params_.enable_quic_proxies_for_https_urls);
|
||||
EXPECT_EQ("Chrome/52.0.2709.0 Linux x86_64", params_.quic_user_agent_id);
|
||||
EXPECT_EQ(0u, params_.origins_to_force_quic_on.size());
|
||||
}
|
||||
@@ -146,6 +147,17 @@ TEST_F(NetworkSessionConfiguratorTest, EnableQuicForDataReductionProxy) {
|
||||
EXPECT_TRUE(params_.enable_quic);
|
||||
}
|
||||
|
||||
+TEST_F(NetworkSessionConfiguratorTest, EnableQuicProxiesForHttpsUrls) {
|
||||
+ std::map<std::string, std::string> field_trial_params;
|
||||
+ field_trial_params["enable_quic_proxies_for_https_urls"] = "true";
|
||||
+ variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params);
|
||||
+ base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled");
|
||||
+
|
||||
+ ParseFieldTrials();
|
||||
+
|
||||
+ EXPECT_TRUE(params_.enable_quic_proxies_for_https_urls);
|
||||
+}
|
||||
+
|
||||
TEST_F(NetworkSessionConfiguratorTest,
|
||||
MarkQuicBrokenWhenNetworkBlackholesFromFieldTrialParams) {
|
||||
std::map<std::string, std::string> field_trial_params;
|
||||
diff --git a/net/http/http_network_session.cc b/net/http/http_network_session.cc
|
||||
index 3bcaca68145012fe11374044e4dddf2b4c3d0b5c..d997e092d56c43222b491b27740cecead2ec3947 100644
|
||||
--- a/net/http/http_network_session.cc
|
||||
+++ b/net/http/http_network_session.cc
|
||||
@@ -112,6 +112,7 @@ HttpNetworkSession::Params::Params()
|
||||
enable_http2_alternative_service(false),
|
||||
enable_websocket_over_http2(false),
|
||||
enable_quic(false),
|
||||
+ enable_quic_proxies_for_https_urls(false),
|
||||
quic_max_packet_length(quic::kDefaultMaxPacketSize),
|
||||
quic_max_server_configs_stored_in_properties(0u),
|
||||
quic_enable_socket_recv_optimization(false),
|
||||
diff --git a/net/http/http_network_session.h b/net/http/http_network_session.h
|
||||
index 3392c846d577da239466b74f9de6fd076bb2ea84..03fbf1c253b01c6d503c02f56c1854ea59ae69ab 100644
|
||||
--- a/net/http/http_network_session.h
|
||||
+++ b/net/http/http_network_session.h
|
||||
@@ -124,6 +124,9 @@ class NET_EXPORT HttpNetworkSession : public base::MemoryCoordinatorClient {
|
||||
// Enables QUIC support.
|
||||
bool enable_quic;
|
||||
|
||||
+ // If true, HTTPS URLs can be sent to QUIC proxies.
|
||||
+ bool enable_quic_proxies_for_https_urls;
|
||||
+
|
||||
// QUIC runtime configuration options.
|
||||
|
||||
// Versions of QUIC which may be used.
|
||||
diff --git a/net/http/http_stream_factory_job.cc b/net/http/http_stream_factory_job.cc
|
||||
index ab66394c2023e5db037897853d9d86b29c78d72d..3cfc627225e4f531c06c66d5de5f1f075187cf92 100644
|
||||
--- a/net/http/http_stream_factory_job.cc
|
||||
+++ b/net/http/http_stream_factory_job.cc
|
||||
@@ -221,6 +221,10 @@ HttpStreamFactory::Job::Job(Delegate* delegate,
|
||||
stream_type_(HttpStreamRequest::BIDIRECTIONAL_STREAM),
|
||||
init_connection_already_resumed_(false),
|
||||
ptr_factory_(this) {
|
||||
+ // QUIC can only be spoken to servers, never to proxies.
|
||||
+ if (alternative_protocol == kProtoQUIC)
|
||||
+ DCHECK(proxy_info_.is_direct());
|
||||
+
|
||||
// The Job is forced to use QUIC without a designated version, try the
|
||||
// preferred QUIC version that is supported by default.
|
||||
if (quic_version_ == quic::QUIC_VERSION_UNSUPPORTED &&
|
||||
@@ -769,6 +773,11 @@ int HttpStreamFactory::Job::DoStart() {
|
||||
return ERR_UNSAFE_PORT;
|
||||
}
|
||||
|
||||
+ if (!session_->params().enable_quic_proxies_for_https_urls &&
|
||||
+ proxy_info_.is_quic() && !request_info_.url.SchemeIs(url::kHttpScheme)) {
|
||||
+ return ERR_NOT_IMPLEMENTED;
|
||||
+ }
|
||||
+
|
||||
next_state_ = STATE_WAIT;
|
||||
return OK;
|
||||
}
|
||||
diff --git a/net/http/http_stream_factory_job_controller.cc b/net/http/http_stream_factory_job_controller.cc
|
||||
index d632aabbdc155c10e1bd04a091e816a8231ab30c..91d4ba7446c2fd63976887c075aad9ff7a8e42c8 100644
|
||||
--- a/net/http/http_stream_factory_job_controller.cc
|
||||
+++ b/net/http/http_stream_factory_job_controller.cc
|
||||
@@ -793,9 +793,13 @@ int HttpStreamFactory::JobController::DoCreateJobs() {
|
||||
HostPortPair destination(HostPortPair::FromURL(request_info_.url));
|
||||
GURL origin_url = ApplyHostMappingRules(request_info_.url, &destination);
|
||||
|
||||
- // Create an alternative job if alternative service is set up for this domain.
|
||||
- alternative_service_info_ =
|
||||
- GetAlternativeServiceInfoFor(request_info_, delegate_, stream_type_);
|
||||
+ // Create an alternative job if alternative service is set up for this domain,
|
||||
+ // but only if we'll be speaking directly to the server, since QUIC through
|
||||
+ // proxies is not supported.
|
||||
+ if (proxy_info_.is_direct()) {
|
||||
+ alternative_service_info_ =
|
||||
+ GetAlternativeServiceInfoFor(request_info_, delegate_, stream_type_);
|
||||
+ }
|
||||
quic::QuicTransportVersion quic_version = quic::QUIC_VERSION_UNSUPPORTED;
|
||||
if (alternative_service_info_.protocol() == kProtoQUIC) {
|
||||
quic_version =
|
||||
@@ -0,0 +1,43 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Marijn Kruisselbrink <mek@chromium.org>
|
||||
Date: Tue, 29 Jan 2019 19:51:07 +0000
|
||||
Subject: Harden against overflows of OperationID a bit better.
|
||||
|
||||
Rather than having a UAF when OperationID overflows instead overwrite
|
||||
the old operation with the new one. Can still cause weirdness, but at
|
||||
least won't result in UAF. Also update OperationID to uint64_t to
|
||||
make sure we don't overflow to begin with.
|
||||
|
||||
Bug: 925864
|
||||
Change-Id: Ifdf3fa0935ab5ea8802d91bba39601f02b0dbdc9
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/1441498
|
||||
Commit-Queue: Marijn Kruisselbrink <mek@chromium.org>
|
||||
Reviewed-by: Victor Costan <pwnall@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/master@{#627115}
|
||||
|
||||
diff --git a/storage/browser/fileapi/file_system_operation_runner.cc b/storage/browser/fileapi/file_system_operation_runner.cc
|
||||
index fbda72b3cdf851947aa697776e54e0b5092e729b..09af7c0c8c9099489286152009f05ad49d968174 100644
|
||||
--- a/storage/browser/fileapi/file_system_operation_runner.cc
|
||||
+++ b/storage/browser/fileapi/file_system_operation_runner.cc
|
||||
@@ -701,7 +701,7 @@ FileSystemOperationRunner::BeginOperation(
|
||||
base::WeakPtr<BeginOperationScoper> scope) {
|
||||
OperationHandle handle;
|
||||
handle.id = next_operation_id_++;
|
||||
- operations_.emplace(handle.id, std::move(operation));
|
||||
+ operations_[handle.id] = std::move(operation);
|
||||
handle.scope = scope;
|
||||
return handle;
|
||||
}
|
||||
diff --git a/storage/browser/fileapi/file_system_operation_runner.h b/storage/browser/fileapi/file_system_operation_runner.h
|
||||
index a330f4802d5d5c721d8bba460f25edc2f8e1340a..97f9e0d81163d08644f0cee5b9da21ac24b300af 100644
|
||||
--- a/storage/browser/fileapi/file_system_operation_runner.h
|
||||
+++ b/storage/browser/fileapi/file_system_operation_runner.h
|
||||
@@ -53,7 +53,7 @@ class STORAGE_EXPORT FileSystemOperationRunner
|
||||
using CopyOrMoveOption = FileSystemOperation::CopyOrMoveOption;
|
||||
using GetMetadataField = FileSystemOperation::GetMetadataField;
|
||||
|
||||
- using OperationID = int;
|
||||
+ using OperationID = uint64_t;
|
||||
|
||||
virtual ~FileSystemOperationRunner();
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aaron Leventhal <aleventhal@chromium.org>
|
||||
Date: Wed, 25 Jul 2018 14:05:53 +0000
|
||||
Subject: Fire caret location change when focus moves from UI to content
|
||||
|
||||
When focus moves from UI back into content, but the same content element
|
||||
is focused as was previously, an accessibility event must be fired for
|
||||
the caret location change, as it is no longer in the UI.
|
||||
|
||||
This fix assists screen magnification software that must track the caret
|
||||
location.
|
||||
|
||||
Bug: 864563
|
||||
Change-Id: Ie9cc745288c124ddd73a54906c41dc16e07b9ff6
|
||||
Reviewed-on: https://chromium-review.googlesource.com/1140199
|
||||
Reviewed-by: Sadrul Chowdhury <sadrul@chromium.org>
|
||||
Reviewed-by: Kinuko Yasuda <kinuko@chromium.org>
|
||||
Reviewed-by: Dominic Mazzoni <dmazzoni@chromium.org>
|
||||
Commit-Queue: Aaron Leventhal <aleventhal@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/master@{#577868}
|
||||
|
||||
diff --git a/chrome/browser/renderer_host/site_per_process_text_input_browsertest.cc b/chrome/browser/renderer_host/site_per_process_text_input_browsertest.cc
|
||||
index c06ff416d83c943731166501260a7a4d9b36b078..5c8bdc8c73dc2047175f16c658428c9f2c038412 100644
|
||||
--- a/chrome/browser/renderer_host/site_per_process_text_input_browsertest.cc
|
||||
+++ b/chrome/browser/renderer_host/site_per_process_text_input_browsertest.cc
|
||||
@@ -10,6 +10,8 @@
|
||||
#include "build/build_config.h"
|
||||
#include "chrome/browser/chrome_content_browser_client.h"
|
||||
#include "chrome/browser/ui/browser.h"
|
||||
+#include "chrome/browser/ui/browser_window.h"
|
||||
+#include "chrome/browser/ui/location_bar/location_bar.h"
|
||||
#include "chrome/browser/ui/tabs/tab_strip_model.h"
|
||||
#include "chrome/test/base/in_process_browser_test.h"
|
||||
#include "chrome/test/base/interactive_test_utils.h"
|
||||
@@ -639,6 +641,41 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessTextInputManagerTest,
|
||||
reset_state_observer.Wait();
|
||||
}
|
||||
|
||||
+#if defined(USE_AURA)
|
||||
+// This test creates a blank page and adds an <input> to it. Then, the <input>
|
||||
+// is focused, UI is focused, then the input is refocused. The test verifies
|
||||
+// that selection bounds change with the refocus (see https://crbug.com/864563).
|
||||
+IN_PROC_BROWSER_TEST_F(SitePerProcessTextInputManagerTest,
|
||||
+ SelectionBoundsChangeAfterRefocusInput) {
|
||||
+ CreateIframePage("a()");
|
||||
+ content::RenderFrameHost* main_frame = GetFrame(IndexVector{});
|
||||
+ content::RenderWidgetHostView* view = main_frame->GetView();
|
||||
+ content::WebContents* web_contents = active_contents();
|
||||
+ AddInputFieldToFrame(main_frame, "text", "", false);
|
||||
+
|
||||
+ auto focus_input_and_wait_for_selection_bounds_change =
|
||||
+ [&main_frame, &web_contents, &view]() {
|
||||
+ ViewSelectionBoundsChangedObserver bounds_observer(web_contents, view);
|
||||
+ // SimulateKeyPress(web_contents, ui::DomKey::TAB, ui::DomCode::TAB,
|
||||
+ // ui::VKEY_TAB, false, true, false, false);
|
||||
+ EXPECT_TRUE(ExecuteScript(main_frame,
|
||||
+ "document.querySelector('input').focus();"));
|
||||
+ bounds_observer.Wait();
|
||||
+ };
|
||||
+
|
||||
+ focus_input_and_wait_for_selection_bounds_change();
|
||||
+
|
||||
+ // Focus location bar.
|
||||
+ BrowserWindow* window = browser()->window();
|
||||
+ ASSERT_TRUE(window);
|
||||
+ LocationBar* location_bar = window->GetLocationBar();
|
||||
+ ASSERT_TRUE(location_bar);
|
||||
+ location_bar->FocusLocation(true);
|
||||
+
|
||||
+ focus_input_and_wait_for_selection_bounds_change();
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
// This test verifies that if we have a focused <input> in the main frame and
|
||||
// the tab is closed, TextInputManager handles unregistering itself and
|
||||
// notifying the observers properly (see https://crbug.com/669375).
|
||||
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc
|
||||
index 09168578786f9ecfa3e1c44b134d7fe76af9504c..0eec5c7a6861f189192ab0cf8b3dbb3b452292e0 100644
|
||||
--- a/content/browser/renderer_host/render_widget_host_view_aura.cc
|
||||
+++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
|
||||
@@ -2339,11 +2339,14 @@ void RenderWidgetHostViewAura::OnUpdateTextInputStateCalled(
|
||||
GetInputMethod()->OnTextInputTypeChanged(this);
|
||||
|
||||
const TextInputState* state = text_input_manager_->GetTextInputState();
|
||||
- if (state && state->show_ime_if_needed &&
|
||||
- state->type != ui::TEXT_INPUT_TYPE_NONE &&
|
||||
- state->mode != ui::TEXT_INPUT_MODE_NONE &&
|
||||
- GetInputMethod()->GetTextInputClient() == this) {
|
||||
- GetInputMethod()->ShowVirtualKeyboardIfEnabled();
|
||||
+ if (state && state->type != ui::TEXT_INPUT_TYPE_NONE &&
|
||||
+ state->mode != ui::TEXT_INPUT_MODE_NONE) {
|
||||
+ if (state->show_ime_if_needed &&
|
||||
+ GetInputMethod()->GetTextInputClient() == this)
|
||||
+ GetInputMethod()->ShowVirtualKeyboardIfEnabled();
|
||||
+ // Ensure that accessibility events are fired when the selection location
|
||||
+ // moves from UI back to content.
|
||||
+ text_input_manager->NotifySelectionBoundsChanged(updated_view);
|
||||
}
|
||||
|
||||
if (auto* render_widget_host = updated_view->host()) {
|
||||
diff --git a/content/browser/renderer_host/text_input_manager.cc b/content/browser/renderer_host/text_input_manager.cc
|
||||
index 24f32e7228aa2b7ece229312a79cc0c95251a31f..ce3a5ff83cf2e0ca9e3cda56308b3b00f6471f16 100644
|
||||
--- a/content/browser/renderer_host/text_input_manager.cc
|
||||
+++ b/content/browser/renderer_host/text_input_manager.cc
|
||||
@@ -209,6 +209,11 @@ void TextInputManager::SelectionBoundsChanged(
|
||||
selection_region_map_[view].first_selection_rect.set_size(
|
||||
params.anchor_rect.size());
|
||||
|
||||
+ NotifySelectionBoundsChanged(view);
|
||||
+}
|
||||
+
|
||||
+void TextInputManager::NotifySelectionBoundsChanged(
|
||||
+ RenderWidgetHostViewBase* view) {
|
||||
for (auto& observer : observer_list_)
|
||||
observer.OnSelectionBoundsChanged(this, view);
|
||||
}
|
||||
diff --git a/content/browser/renderer_host/text_input_manager.h b/content/browser/renderer_host/text_input_manager.h
|
||||
index 8e4ecfe5be2defa1578eec9be3c713be0b07e84d..d145a992144079401817e2e24f664576c493b3fb 100644
|
||||
--- a/content/browser/renderer_host/text_input_manager.h
|
||||
+++ b/content/browser/renderer_host/text_input_manager.h
|
||||
@@ -184,6 +184,10 @@ class CONTENT_EXPORT TextInputManager {
|
||||
void SelectionBoundsChanged(RenderWidgetHostViewBase* view,
|
||||
const ViewHostMsg_SelectionBounds_Params& params);
|
||||
|
||||
+ // Notify observers that the selection bounds have been updated. This is also
|
||||
+ // called when a view with a selection is reactivated.
|
||||
+ void NotifySelectionBoundsChanged(RenderWidgetHostViewBase* view);
|
||||
+
|
||||
// Called when the composition range and/or character bounds have changed.
|
||||
void ImeCompositionRangeChanged(
|
||||
RenderWidgetHostViewBase* view,
|
||||
@@ -0,0 +1,43 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Pedro Pontes <pepontes@microsoft.com>
|
||||
Date: Thu, 12 Sep 2019 16:28:47 +0200
|
||||
Subject: fix: Add more checks in MojoCdmService.
|
||||
|
||||
Applies https://chromium.googlesource.com/chromium/src.git/+/b7b305f3389017cc42e2cfac6e7a319f42d5bde3%5E%21/
|
||||
|
||||
diff --git a/media/mojo/services/mojo_cdm_service.cc b/media/mojo/services/mojo_cdm_service.cc
|
||||
index 3334ac0f6d3a03b0df879b5b015e95de307c1cda..a49ac813b0f8540fadf2c3cccdcc36a6a504d4cd 100644
|
||||
--- a/media/mojo/services/mojo_cdm_service.cc
|
||||
+++ b/media/mojo/services/mojo_cdm_service.cc
|
||||
@@ -60,7 +60,9 @@ void MojoCdmService::Initialize(const std::string& key_system,
|
||||
const CdmConfig& cdm_config,
|
||||
InitializeCallback callback) {
|
||||
DVLOG(1) << __func__ << ": " << key_system;
|
||||
- DCHECK(!cdm_);
|
||||
+
|
||||
+ CHECK(!has_initialize_been_called_) << "Initialize should only happen once";
|
||||
+ has_initialize_been_called_ = true;
|
||||
|
||||
auto weak_this = weak_factory_.GetWeakPtr();
|
||||
cdm_factory_->Create(
|
||||
@@ -154,6 +156,7 @@ void MojoCdmService::OnCdmCreated(
|
||||
return;
|
||||
}
|
||||
|
||||
+ CHECK(!cdm_) << "CDM should only be created once.";
|
||||
cdm_ = cdm;
|
||||
|
||||
if (context_) {
|
||||
diff --git a/media/mojo/services/mojo_cdm_service.h b/media/mojo/services/mojo_cdm_service.h
|
||||
index c8de5534202ac8de99be3bc52766f48c3e10b95a..bfe7baf10bb8642e7c6ce79c8a4e86942909a56a 100644
|
||||
--- a/media/mojo/services/mojo_cdm_service.h
|
||||
+++ b/media/mojo/services/mojo_cdm_service.h
|
||||
@@ -101,6 +101,8 @@ class MEDIA_MOJO_EXPORT MojoCdmService : public mojom::ContentDecryptionModule {
|
||||
// Callback for when |decryptor_| loses connectivity.
|
||||
void OnDecryptorConnectionError();
|
||||
|
||||
+ bool has_initialize_been_called_ = false;
|
||||
+
|
||||
CdmFactory* cdm_factory_;
|
||||
MojoCdmServiceContext* const context_ = nullptr;
|
||||
scoped_refptr<::media::ContentDecryptionModule> cdm_;
|
||||
@@ -0,0 +1,105 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Kent Tamura <tkent@chromium.org>
|
||||
Date: Thu, 20 Dec 2018 00:22:07 +0000
|
||||
Subject: Fix crashes in RenderFrameImpl::OnSelectPopupMenuItem(s)
|
||||
|
||||
ExternalPopupMenu::DidSelectItem(s) can delete the RenderFrameImpl.
|
||||
We need to reset external_popup_menu_ before calling it.
|
||||
|
||||
Bug: 912211
|
||||
Change-Id: Ia9a628e144464a2ebb14ab77d3a693fd5cead6fc
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/1381325
|
||||
Commit-Queue: Kent Tamura <tkent@chromium.org>
|
||||
Reviewed-by: Avi Drissman <avi@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/master@{#618026}
|
||||
|
||||
diff --git a/content/renderer/external_popup_menu_browsertest.cc b/content/renderer/external_popup_menu_browsertest.cc
|
||||
index d3cff681551c4961a4a47c48bac9155b22fd7524..0ea34d8809f1b191504d2cc833f74fef694230d3 100644
|
||||
--- a/content/renderer/external_popup_menu_browsertest.cc
|
||||
+++ b/content/renderer/external_popup_menu_browsertest.cc
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "content/renderer/render_view_impl.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
#include "third_party/blink/public/platform/web_size.h"
|
||||
+#include "third_party/blink/public/web/web_local_frame.h"
|
||||
#include "third_party/blink/public/web/web_view.h"
|
||||
|
||||
// Tests for the external select popup menu (Mac specific).
|
||||
@@ -153,6 +154,31 @@ TEST_F(ExternalPopupMenuRemoveTest, RemoveOnChange) {
|
||||
EXPECT_FALSE(SimulateElementClick(kSelectID));
|
||||
}
|
||||
|
||||
+// crbug.com/912211
|
||||
+TEST_F(ExternalPopupMenuRemoveTest, RemoveFrameOnChange) {
|
||||
+ LoadHTML(
|
||||
+ "<style>* { margin: 0; } iframe { border: 0; }</style>"
|
||||
+ "<body><iframe srcdoc=\""
|
||||
+ "<style>* { margin: 0; }</style><select><option>opt1<option>opt2"
|
||||
+ "\"></iframe>"
|
||||
+ "<script>"
|
||||
+ "onload = function() {"
|
||||
+ " const frame = document.querySelector('iframe');"
|
||||
+ " frame.contentDocument.querySelector('select').onchange = "
|
||||
+ " () => { frame.remove(); };"
|
||||
+ "};"
|
||||
+ "</script>");
|
||||
+ // Open a popup.
|
||||
+ SimulatePointClick(gfx::Point(8, 8));
|
||||
+ // Select something on the sub-frame, it causes the frame to be removed from
|
||||
+ // the page.
|
||||
+ auto* child_web_frame =
|
||||
+ static_cast<blink::WebLocalFrame*>(frame()->GetWebFrame()->FirstChild());
|
||||
+ static_cast<RenderFrameImpl*>(RenderFrame::FromWebFrame(child_web_frame))
|
||||
+ ->OnSelectPopupMenuItem(1);
|
||||
+ // The test passes if the test didn't crash and ASAN didn't complain.
|
||||
+}
|
||||
+
|
||||
class ExternalPopupMenuDisplayNoneTest : public ExternalPopupMenuTest {
|
||||
public:
|
||||
ExternalPopupMenuDisplayNoneTest() {}
|
||||
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
|
||||
index 9571ea0233e84e3ab2f2159018efd12f18adcea9..7db2fa3591040b73a55ac620cbf35816afbd715f 100644
|
||||
--- a/content/renderer/render_frame_impl.cc
|
||||
+++ b/content/renderer/render_frame_impl.cc
|
||||
@@ -6473,8 +6473,12 @@ void RenderFrameImpl::OnSelectPopupMenuItem(int selected_index) {
|
||||
return;
|
||||
|
||||
blink::WebScopedUserGesture gesture(frame_);
|
||||
- external_popup_menu_->DidSelectItem(selected_index);
|
||||
- external_popup_menu_.reset();
|
||||
+ // We need to reset |external_popup_menu_| before calling DidSelectItem(),
|
||||
+ // which might delete |this|.
|
||||
+ // See ExternalPopupMenuRemoveTest.RemoveFrameOnChange
|
||||
+ std::unique_ptr<ExternalPopupMenu> popup;
|
||||
+ popup.swap(external_popup_menu_);
|
||||
+ popup->DidSelectItem(selected_index);
|
||||
}
|
||||
#else
|
||||
void RenderFrameImpl::OnSelectPopupMenuItems(
|
||||
@@ -6488,8 +6492,12 @@ void RenderFrameImpl::OnSelectPopupMenuItems(
|
||||
return;
|
||||
|
||||
blink::WebScopedUserGesture gesture(frame_);
|
||||
- external_popup_menu_->DidSelectItems(canceled, selected_indices);
|
||||
- external_popup_menu_.reset();
|
||||
+ // We need to reset |external_popup_menu_| before calling DidSelectItems(),
|
||||
+ // which might delete |this|.
|
||||
+ // See ExternalPopupMenuRemoveTest.RemoveFrameOnChange
|
||||
+ std::unique_ptr<ExternalPopupMenu> popup;
|
||||
+ popup.swap(external_popup_menu_);
|
||||
+ popup->DidSelectItems(canceled, selected_indices);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h
|
||||
index cb5ffc56b005d8fb5492c1254bf533a370d42448..c9fea9da0cf2e24cd1c1581cbe939a736edd65bf 100644
|
||||
--- a/content/renderer/render_frame_impl.h
|
||||
+++ b/content/renderer/render_frame_impl.h
|
||||
@@ -900,6 +900,7 @@ class CONTENT_EXPORT RenderFrameImpl
|
||||
friend class RenderAccessibilityImplTest;
|
||||
friend class TestRenderFrame;
|
||||
FRIEND_TEST_ALL_PREFIXES(ExternalPopupMenuDisplayNoneTest, SelectItem);
|
||||
+ FRIEND_TEST_ALL_PREFIXES(ExternalPopupMenuRemoveTest, RemoveFrameOnChange);
|
||||
FRIEND_TEST_ALL_PREFIXES(ExternalPopupMenuRemoveTest, RemoveOnChange);
|
||||
FRIEND_TEST_ALL_PREFIXES(ExternalPopupMenuTest, NormalCase);
|
||||
FRIEND_TEST_ALL_PREFIXES(ExternalPopupMenuTest, ShowPopupThenNavigate);
|
||||
@@ -0,0 +1,126 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: kylechar <kylechar@chromium.org>
|
||||
Date: Mon, 3 Dec 2018 18:17:17 +0000
|
||||
Subject: Fix re-entracy problem with InvalidateFrameSinkId().
|
||||
|
||||
HostFrameSinkManager::InvalidateFrameSinkId() can make a synchronous IPC
|
||||
to ensure whatever is drawing the platform window is destroyed before
|
||||
the platform window gets destroyed. However, while waiting for the
|
||||
synchronous IPC response other synchronous IPCs continue to get
|
||||
processed. |frame_sink_data_map_| can get mutated in response to a
|
||||
different synchronous IPC and |data| may no longer point to a valid
|
||||
memory location when DestroyCompositorFrameSink() returns.
|
||||
|
||||
Change the order so that all modifications to |data| happen before the
|
||||
synchronous IPC. Also add a comment to clarify that FrameSinkIds
|
||||
shouldn't be reused after they are invalidated. We don't do this today
|
||||
and it would cause more re-entrancy problems.
|
||||
|
||||
Also switch |frame_sink_data_map_| to use std::unordered_map instead of
|
||||
base::flat_map. This map can get large (tens of elements per open tab)
|
||||
so std::unordered_map is probably a better choice.
|
||||
|
||||
Bug: 907211
|
||||
Change-Id: Iea42d1eca290f5b61f215c66da9b9021f671c1e0
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/1352525
|
||||
Reviewed-by: Sadrul Chowdhury <sadrul@chromium.org>
|
||||
Commit-Queue: Sadrul Chowdhury <sadrul@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/master@{#613160}
|
||||
|
||||
diff --git a/components/viz/host/host_frame_sink_manager.cc b/components/viz/host/host_frame_sink_manager.cc
|
||||
index 53ccb9f26f8ce6bb472487d4650c0b1a51b9a4c6..bceb1bd9d96e11080928014e2c30674690e28a06 100644
|
||||
--- a/components/viz/host/host_frame_sink_manager.cc
|
||||
+++ b/components/viz/host/host_frame_sink_manager.cc
|
||||
@@ -79,15 +79,9 @@ void HostFrameSinkManager::InvalidateFrameSinkId(
|
||||
FrameSinkData& data = frame_sink_data_map_[frame_sink_id];
|
||||
DCHECK(data.IsFrameSinkRegistered());
|
||||
|
||||
- if (data.has_created_compositor_frame_sink && data.is_root) {
|
||||
- // This synchronous call ensures that the GL context/surface that draw to
|
||||
- // the platform window (eg. XWindow or HWND) get destroyed before the
|
||||
- // platform window is destroyed.
|
||||
- mojo::SyncCallRestrictions::ScopedAllowSyncCall allow_sync_call;
|
||||
- frame_sink_manager_->DestroyCompositorFrameSink(frame_sink_id);
|
||||
- }
|
||||
+ const bool destroy_synchronously =
|
||||
+ data.has_created_compositor_frame_sink && data.is_root;
|
||||
|
||||
- frame_sink_manager_->InvalidateFrameSinkId(frame_sink_id);
|
||||
data.has_created_compositor_frame_sink = false;
|
||||
data.client = nullptr;
|
||||
|
||||
@@ -96,6 +90,21 @@ void HostFrameSinkManager::InvalidateFrameSinkId(
|
||||
frame_sink_data_map_.erase(frame_sink_id);
|
||||
|
||||
display_hit_test_query_.erase(frame_sink_id);
|
||||
+
|
||||
+ if (destroy_synchronously) {
|
||||
+ // This synchronous call ensures that the GL context/surface that draw to
|
||||
+ // the platform window (eg. XWindow or HWND) get destroyed before the
|
||||
+ // platform window is destroyed.
|
||||
+ mojo::SyncCallRestrictions::ScopedAllowSyncCall allow_sync_call;
|
||||
+ frame_sink_manager_->DestroyCompositorFrameSink(frame_sink_id);
|
||||
+
|
||||
+ // Other synchronous IPCs continue to get processed while
|
||||
+ // DestroyCompositorFrameSink() is happening, so it's possible
|
||||
+ // HostFrameSinkManager has been mutated. |data| might not be a valid
|
||||
+ // reference at this point.
|
||||
+ }
|
||||
+
|
||||
+ frame_sink_manager_->InvalidateFrameSinkId(frame_sink_id);
|
||||
}
|
||||
|
||||
void HostFrameSinkManager::EnableSynchronizationReporting(
|
||||
diff --git a/components/viz/host/host_frame_sink_manager.h b/components/viz/host/host_frame_sink_manager.h
|
||||
index 1b6a6aca6d5cd58400bd0dd6784085f9dfd77ddb..68d0a251b0b60aac77fe04e1e910b51364357ae7 100644
|
||||
--- a/components/viz/host/host_frame_sink_manager.h
|
||||
+++ b/components/viz/host/host_frame_sink_manager.h
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
+#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include "base/compiler_specific.h"
|
||||
@@ -72,15 +73,24 @@ class VIZ_HOST_EXPORT HostFrameSinkManager
|
||||
// Sets a callback to be notified after Viz sent bad message to Viz host.
|
||||
void SetBadMessageReceivedFromGpuCallback(base::RepeatingClosure callback);
|
||||
|
||||
- // Registers |frame_sink_id| will be used. This must be called before
|
||||
- // CreateCompositorFrameSink(Support) is called.
|
||||
+ // Registers |frame_sink_id| so that a client can submit CompositorFrames
|
||||
+ // using it. This must be called before creating a CompositorFrameSink or
|
||||
+ // registering FrameSinkId hierarchy.
|
||||
+ //
|
||||
+ // When the client is done submitting CompositorFrames to |frame_sink_id| then
|
||||
+ // InvalidateFrameSink() should be called.
|
||||
void RegisterFrameSinkId(const FrameSinkId& frame_sink_id,
|
||||
HostFrameSinkClient* client);
|
||||
|
||||
- // Invalidates |frame_sink_id| which cleans up any dangling temporary
|
||||
- // references assigned to it. If there is a CompositorFrameSink for
|
||||
- // |frame_sink_id| then it will be destroyed and the message pipe to the
|
||||
- // client will be closed.
|
||||
+ // Invalidates |frame_sink_id| when the client is done submitting
|
||||
+ // CompositorFrames. If there is a CompositorFrameSink for |frame_sink_id|
|
||||
+ // then it will be destroyed and the message pipe to the client will be
|
||||
+ // closed.
|
||||
+ //
|
||||
+ // It's expected, but not enforced, that RegisterFrameSinkId() will never be
|
||||
+ // called for |frame_sink_id| again. This is to avoid problems with re-entrant
|
||||
+ // code. If the same client wants to submit CompositorFrames later a new
|
||||
+ // FrameSinkId should be allocated.
|
||||
void InvalidateFrameSinkId(const FrameSinkId& frame_sink_id);
|
||||
|
||||
// Tells FrameSinkManger to report when a synchronization event completes via
|
||||
@@ -256,7 +266,8 @@ class VIZ_HOST_EXPORT HostFrameSinkManager
|
||||
FrameSinkManagerImpl* frame_sink_manager_impl_ = nullptr;
|
||||
|
||||
// Per CompositorFrameSink data.
|
||||
- base::flat_map<FrameSinkId, FrameSinkData> frame_sink_data_map_;
|
||||
+ std::unordered_map<FrameSinkId, FrameSinkData, FrameSinkIdHash>
|
||||
+ frame_sink_data_map_;
|
||||
|
||||
// If |frame_sink_manager_ptr_| connection was lost.
|
||||
bool connection_was_lost_ = false;
|
||||
@@ -0,0 +1,63 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Rune Lillesveen <futhark@chromium.org>
|
||||
Date: Tue, 18 Dec 2018 14:45:19 +0000
|
||||
Subject: Fix SVG crash for v0 distribution into foreignObject.
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
We require a parent element to be an SVG element for non-svg-root
|
||||
elements in order to create a LayoutObject for them. However, we checked
|
||||
the light tree parent element, not the flat tree one which is the parent
|
||||
for the layout tree construction. Note that this is just an issue in
|
||||
Shadow DOM v0 since v1 does not allow shadow roots on SVG elements.
|
||||
|
||||
Bug: 915469
|
||||
Change-Id: Id81843abad08814fae747b5bc81c09666583f130
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/1382494
|
||||
Reviewed-by: Fredrik Söderquist <fs@opera.com>
|
||||
Commit-Queue: Rune Lillesveen <futhark@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/master@{#617487}
|
||||
|
||||
diff --git a/third_party/WebKit/LayoutTests/svg/foreignObject/shadow-dom-v0-crash.html b/third_party/WebKit/LayoutTests/svg/foreignObject/shadow-dom-v0-crash.html
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..44ac3b0540b8f5a816a67b5be382b179623bd0cd
|
||||
--- /dev/null
|
||||
+++ b/third_party/WebKit/LayoutTests/svg/foreignObject/shadow-dom-v0-crash.html
|
||||
@@ -0,0 +1,11 @@
|
||||
+<!DOCTYPE html>
|
||||
+<script src="../../resources/testharness.js"></script>
|
||||
+<script src="../../resources/testharnessreport.js"></script>
|
||||
+<p>PASS if no crash or DCHECK failure.</p>
|
||||
+<svg id="svg"><g /></svg>
|
||||
+<script>
|
||||
+ test(() => {
|
||||
+ const root = svg.createShadowRoot();
|
||||
+ root.innerHTML = '<foreignObject><div><content></content></div></foreignObject>';
|
||||
+ }, "Rendering an svg g element distributed into a foreignObject will crash.");
|
||||
+</script>
|
||||
diff --git a/third_party/blink/renderer/core/svg/svg_element.cc b/third_party/blink/renderer/core/svg/svg_element.cc
|
||||
index e9a1fd9dd0ef6975cbc3e0967e8b0e9c8362b7a1..6af7df47e3502903346c4509c6fd080ef6d071ef 100644
|
||||
--- a/third_party/blink/renderer/core/svg/svg_element.cc
|
||||
+++ b/third_party/blink/renderer/core/svg/svg_element.cc
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "third_party/blink/renderer/core/dom/document.h"
|
||||
#include "third_party/blink/renderer/core/dom/element_traversal.h"
|
||||
#include "third_party/blink/renderer/core/dom/events/event.h"
|
||||
+#include "third_party/blink/renderer/core/dom/flat_tree_traversal.h"
|
||||
#include "third_party/blink/renderer/core/dom/node_computed_style.h"
|
||||
#include "third_party/blink/renderer/core/dom/shadow_root.h"
|
||||
#include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
|
||||
@@ -1047,10 +1048,8 @@ bool SVGElement::LayoutObjectIsNeeded(const ComputedStyle& style) const {
|
||||
}
|
||||
|
||||
bool SVGElement::HasSVGParent() const {
|
||||
- // Should we use the flat tree parent instead? If so, we should probably fix a
|
||||
- // few other checks.
|
||||
- return ParentOrShadowHostElement() &&
|
||||
- ParentOrShadowHostElement()->IsSVGElement();
|
||||
+ Element* parent = FlatTreeTraversal::ParentElement(*this);
|
||||
+ return parent && parent->IsSVGElement();
|
||||
}
|
||||
|
||||
MutableCSSPropertyValueSet* SVGElement::AnimatedSMILStyleProperties() const {
|
||||
@@ -0,0 +1,134 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Marijn Kruisselbrink <mek@chromium.org>
|
||||
Date: Thu, 13 Dec 2018 17:09:55 +0000
|
||||
Subject: Fix UAP in ImageBitmapLoader/FileReaderLoader
|
||||
|
||||
FileReaderLoader stores its client as a raw pointer, so in cases like
|
||||
ImageBitmapLoader where the FileReaderLoaderClient really is garbage
|
||||
collected we have to make sure to destroy the FileReaderLoader when
|
||||
the ExecutionContext that owns it is destroyed.
|
||||
|
||||
Bug: 913970
|
||||
Change-Id: I40b02115367cf7bf5bbbbb8e9b57874d2510f861
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/1374511
|
||||
Reviewed-by: Jeremy Roman <jbroman@chromium.org>
|
||||
Commit-Queue: Marijn Kruisselbrink <mek@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/master@{#616342}
|
||||
|
||||
diff --git a/third_party/blink/renderer/core/imagebitmap/image_bitmap_factories.cc b/third_party/blink/renderer/core/imagebitmap/image_bitmap_factories.cc
|
||||
index 076b9beeaa6675c5e858a1c7f5a321ab57c606fb..40898b704891c3723574d3afa4aebf72f5cdce5c 100644
|
||||
--- a/third_party/blink/renderer/core/imagebitmap/image_bitmap_factories.cc
|
||||
+++ b/third_party/blink/renderer/core/imagebitmap/image_bitmap_factories.cc
|
||||
@@ -238,27 +238,31 @@ void ImageBitmapFactories::DidFinishLoading(ImageBitmapLoader* loader) {
|
||||
pending_loaders_.erase(loader);
|
||||
}
|
||||
|
||||
+void ImageBitmapFactories::Trace(blink::Visitor* visitor) {
|
||||
+ visitor->Trace(pending_loaders_);
|
||||
+ Supplement<LocalDOMWindow>::Trace(visitor);
|
||||
+ Supplement<WorkerGlobalScope>::Trace(visitor);
|
||||
+}
|
||||
+
|
||||
ImageBitmapFactories::ImageBitmapLoader::ImageBitmapLoader(
|
||||
ImageBitmapFactories& factory,
|
||||
base::Optional<IntRect> crop_rect,
|
||||
ScriptState* script_state,
|
||||
const ImageBitmapOptions& options)
|
||||
- : loader_(
|
||||
+ : ContextLifecycleObserver(ExecutionContext::From(script_state)),
|
||||
+ loader_(
|
||||
FileReaderLoader::Create(FileReaderLoader::kReadAsArrayBuffer, this)),
|
||||
factory_(&factory),
|
||||
resolver_(ScriptPromiseResolver::Create(script_state)),
|
||||
crop_rect_(crop_rect),
|
||||
options_(options) {}
|
||||
|
||||
-void ImageBitmapFactories::ImageBitmapLoader::LoadBlobAsync(
|
||||
- Blob* blob) {
|
||||
+void ImageBitmapFactories::ImageBitmapLoader::LoadBlobAsync(Blob* blob) {
|
||||
loader_->Start(blob->GetBlobDataHandle());
|
||||
}
|
||||
|
||||
-void ImageBitmapFactories::Trace(blink::Visitor* visitor) {
|
||||
- visitor->Trace(pending_loaders_);
|
||||
- Supplement<LocalDOMWindow>::Trace(visitor);
|
||||
- Supplement<WorkerGlobalScope>::Trace(visitor);
|
||||
+ImageBitmapFactories::ImageBitmapLoader::~ImageBitmapLoader() {
|
||||
+ DCHECK(!loader_);
|
||||
}
|
||||
|
||||
void ImageBitmapFactories::ImageBitmapLoader::RejectPromise(
|
||||
@@ -277,11 +281,20 @@ void ImageBitmapFactories::ImageBitmapLoader::RejectPromise(
|
||||
default:
|
||||
NOTREACHED();
|
||||
}
|
||||
+ loader_.reset();
|
||||
factory_->DidFinishLoading(this);
|
||||
}
|
||||
|
||||
+void ImageBitmapFactories::ImageBitmapLoader::ContextDestroyed(
|
||||
+ ExecutionContext*) {
|
||||
+ if (loader_)
|
||||
+ factory_->DidFinishLoading(this);
|
||||
+ loader_.reset();
|
||||
+}
|
||||
+
|
||||
void ImageBitmapFactories::ImageBitmapLoader::DidFinishLoading() {
|
||||
DOMArrayBuffer* array_buffer = loader_->ArrayBufferResult();
|
||||
+ loader_.reset();
|
||||
if (!array_buffer) {
|
||||
RejectPromise(kAllocationFailureImageBitmapRejectionReason);
|
||||
return;
|
||||
@@ -359,6 +372,7 @@ void ImageBitmapFactories::ImageBitmapLoader::ResolvePromiseOnOriginalThread(
|
||||
}
|
||||
|
||||
void ImageBitmapFactories::ImageBitmapLoader::Trace(blink::Visitor* visitor) {
|
||||
+ ContextLifecycleObserver::Trace(visitor);
|
||||
visitor->Trace(factory_);
|
||||
visitor->Trace(resolver_);
|
||||
}
|
||||
diff --git a/third_party/blink/renderer/core/imagebitmap/image_bitmap_factories.h b/third_party/blink/renderer/core/imagebitmap/image_bitmap_factories.h
|
||||
index 25bdf1ffd1e85a05ab4ee46aaa81c61294fd7d1a..726012a20f7250ea1166ec03875ebaa10f352a49 100644
|
||||
--- a/third_party/blink/renderer/core/imagebitmap/image_bitmap_factories.h
|
||||
+++ b/third_party/blink/renderer/core/imagebitmap/image_bitmap_factories.h
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "third_party/blink/renderer/bindings/core/v8/image_bitmap_source.h"
|
||||
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
|
||||
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
|
||||
+#include "third_party/blink/renderer/core/dom/context_lifecycle_observer.h"
|
||||
#include "third_party/blink/renderer/core/fileapi/file_reader_loader.h"
|
||||
#include "third_party/blink/renderer/core/fileapi/file_reader_loader_client.h"
|
||||
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
|
||||
@@ -103,7 +104,10 @@ class ImageBitmapFactories final
|
||||
private:
|
||||
class ImageBitmapLoader final
|
||||
: public GarbageCollectedFinalized<ImageBitmapLoader>,
|
||||
+ public ContextLifecycleObserver,
|
||||
public FileReaderLoaderClient {
|
||||
+ USING_GARBAGE_COLLECTED_MIXIN(ImageBitmapLoader);
|
||||
+
|
||||
public:
|
||||
static ImageBitmapLoader* Create(ImageBitmapFactories& factory,
|
||||
base::Optional<IntRect> crop_rect,
|
||||
@@ -115,9 +119,9 @@ class ImageBitmapFactories final
|
||||
void LoadBlobAsync(Blob*);
|
||||
ScriptPromise Promise() { return resolver_->Promise(); }
|
||||
|
||||
- void Trace(blink::Visitor*);
|
||||
+ void Trace(blink::Visitor*) override;
|
||||
|
||||
- ~ImageBitmapLoader() override = default;
|
||||
+ ~ImageBitmapLoader() override;
|
||||
|
||||
private:
|
||||
ImageBitmapLoader(ImageBitmapFactories&,
|
||||
@@ -140,6 +144,9 @@ class ImageBitmapFactories final
|
||||
const String& color_space_conversion_option);
|
||||
void ResolvePromiseOnOriginalThread(sk_sp<SkImage>);
|
||||
|
||||
+ // ContextLifecycleObserver
|
||||
+ void ContextDestroyed(ExecutionContext*) override;
|
||||
+
|
||||
// FileReaderLoaderClient
|
||||
void DidStartLoading() override {}
|
||||
void DidReceiveData() override {}
|
||||
146
patches/common/chromium/intersection-observer.patch
Normal file
146
patches/common/chromium/intersection-observer.patch
Normal file
@@ -0,0 +1,146 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Milan Burda <milan.burda@gmail.com>
|
||||
Date: Wed, 27 Mar 2019 23:27:40 +0100
|
||||
Subject: Report coordinates as CSS pixels.
|
||||
|
||||
Prior to this patch, IntersectionObserverEntry was reporting
|
||||
coordinates in device pixels.
|
||||
|
||||
Backports https://chromium-review.googlesource.com/c/chromium/src/+/1250121
|
||||
|
||||
diff --git a/third_party/WebKit/LayoutTests/external/wpt/intersection-observer/bounding-box.html b/third_party/WebKit/LayoutTests/external/wpt/intersection-observer/bounding-box.html
|
||||
index 69052b11ce6c40c6a56fe2b723c70c49ddc36dd9..50f33f0443bb70e64bec2e2fcc930fa2b4118ed6 100644
|
||||
--- a/third_party/WebKit/LayoutTests/external/wpt/intersection-observer/bounding-box.html
|
||||
+++ b/third_party/WebKit/LayoutTests/external/wpt/intersection-observer/bounding-box.html
|
||||
@@ -13,7 +13,7 @@ pre, #log {
|
||||
overflow: visible;
|
||||
height: 200px;
|
||||
width: 160px;
|
||||
- border: 7px solid black;
|
||||
+ border: 8px solid black;
|
||||
}
|
||||
#target {
|
||||
margin: 10px;
|
||||
@@ -50,12 +50,35 @@ function step0() {
|
||||
var targetBounds = clientBounds(target);
|
||||
target.style.transform = "translateY(195px)";
|
||||
runTestCycle(step1, "target.style.transform = 'translateY(195px)'");
|
||||
- checkLastEntry(entries, 0, targetBounds.concat(0, 0, 0, 0, 8, 182, 8, 222, false));
|
||||
+ checkLastEntry(entries, 0, targetBounds.concat(0, 0, 0, 0, 8, 184, 8, 224, false));
|
||||
}
|
||||
|
||||
function step1() {
|
||||
+ var targetBounds = clientBounds(target);
|
||||
+ target.style.transform = "translateY(300px)";
|
||||
+ runTestCycle(step2, "target.style.transform = 'translateY(300px)'");
|
||||
+ checkLastEntry(entries, 1, targetBounds.concat(26, 146, 221, 224, 8, 184, 8, 224, true));
|
||||
+}
|
||||
+
|
||||
+function step2() {
|
||||
var targetBounds = clientBounds(target);
|
||||
target.style.transform = "";
|
||||
- checkLastEntry(entries, 1, targetBounds.concat(25, 145, 220, 222, 8, 182, 8, 222, true));
|
||||
+ target.style.zoom = "2";
|
||||
+ runTestCycle(step3, "target.style.zoom = 2");
|
||||
+ checkLastEntry(entries, 2, targetBounds.concat(0, 0, 0, 0, 8, 184, 8, 224, false));
|
||||
}
|
||||
+
|
||||
+function step3() {
|
||||
+ var targetBounds = clientBounds(target);
|
||||
+ var intersectionWidth = (
|
||||
+ 176 // root width including border
|
||||
+ -8 // root left border
|
||||
+ -20 // target left margin * target zoom
|
||||
+ ) / 2; // convert to target's zoom factor.
|
||||
+ var intersectionHeight = (216 - 8 - 20) / 2;
|
||||
+ var intersectionRect = [targetBounds[0], targetBounds[0] + intersectionWidth,
|
||||
+ targetBounds[2], targetBounds[2] + intersectionHeight];
|
||||
+ checkLastEntry(entries, 3, targetBounds.concat(intersectionRect).concat(8, 184, 8, 224, true));
|
||||
+}
|
||||
+
|
||||
</script>
|
||||
diff --git a/third_party/blink/renderer/core/intersection_observer/intersection_observation.cc b/third_party/blink/renderer/core/intersection_observer/intersection_observation.cc
|
||||
index 8b355a9f0b1e567950f8b5e9525d3af3e56605c4..d44b8b4e50f2a9de0628ebfb1bfdeac0292f79b5 100644
|
||||
--- a/third_party/blink/renderer/core/intersection_observer/intersection_observation.cc
|
||||
+++ b/third_party/blink/renderer/core/intersection_observer/intersection_observation.cc
|
||||
@@ -100,12 +100,12 @@ void IntersectionObservation::ComputeIntersectionObservations(
|
||||
|
||||
if (last_threshold_index_ != new_threshold_index ||
|
||||
last_is_visible_ != is_visible) {
|
||||
- FloatRect snapped_root_bounds(geometry.RootRect());
|
||||
+ FloatRect root_bounds(geometry.UnZoomedRootRect());
|
||||
FloatRect* root_bounds_pointer =
|
||||
- should_report_root_bounds_ ? &snapped_root_bounds : nullptr;
|
||||
+ should_report_root_bounds_ ? &root_bounds : nullptr;
|
||||
IntersectionObserverEntry* new_entry = new IntersectionObserverEntry(
|
||||
- timestamp, new_visible_ratio, FloatRect(geometry.TargetRect()),
|
||||
- root_bounds_pointer, FloatRect(geometry.IntersectionRect()),
|
||||
+ timestamp, new_visible_ratio, FloatRect(geometry.UnZoomedTargetRect()),
|
||||
+ root_bounds_pointer, FloatRect(geometry.UnZoomedIntersectionRect()),
|
||||
geometry.DoesIntersect(), is_visible, Target());
|
||||
Observer()->EnqueueIntersectionObserverEntry(*new_entry);
|
||||
SetLastThresholdIndex(new_threshold_index);
|
||||
diff --git a/third_party/blink/renderer/core/layout/intersection_geometry.cc b/third_party/blink/renderer/core/layout/intersection_geometry.cc
|
||||
index 2efb1a9cfef2c8372c98986f6a168979cafcd6df..1102b72814941faacf36ce486a46535565ea11e8 100644
|
||||
--- a/third_party/blink/renderer/core/layout/intersection_geometry.cc
|
||||
+++ b/third_party/blink/renderer/core/layout/intersection_geometry.cc
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
|
||||
#include "third_party/blink/renderer/core/frame/settings.h"
|
||||
#include "third_party/blink/renderer/core/html/html_frame_owner_element.h"
|
||||
+#include "third_party/blink/renderer/core/layout/adjust_for_absolute_zoom.h"
|
||||
#include "third_party/blink/renderer/core/layout/layout_box.h"
|
||||
#include "third_party/blink/renderer/core/layout/layout_view.h"
|
||||
#include "third_party/blink/renderer/core/page/page.h"
|
||||
@@ -230,4 +231,28 @@ void IntersectionGeometry::ComputeGeometry() {
|
||||
MapRootRectToRootFrameCoordinates();
|
||||
}
|
||||
|
||||
+LayoutRect IntersectionGeometry::UnZoomedTargetRect() const {
|
||||
+ if (!target_)
|
||||
+ return target_rect_;
|
||||
+ FloatRect rect(target_rect_);
|
||||
+ AdjustForAbsoluteZoom::AdjustFloatRect(rect, *target_);
|
||||
+ return LayoutRect(rect);
|
||||
+}
|
||||
+
|
||||
+LayoutRect IntersectionGeometry::UnZoomedIntersectionRect() const {
|
||||
+ if (!target_)
|
||||
+ return intersection_rect_;
|
||||
+ FloatRect rect(intersection_rect_);
|
||||
+ AdjustForAbsoluteZoom::AdjustFloatRect(rect, *target_);
|
||||
+ return LayoutRect(rect);
|
||||
+}
|
||||
+
|
||||
+LayoutRect IntersectionGeometry::UnZoomedRootRect() const {
|
||||
+ if (!root_)
|
||||
+ return root_rect_;
|
||||
+ FloatRect rect(root_rect_);
|
||||
+ AdjustForAbsoluteZoom::AdjustFloatRect(rect, *root_);
|
||||
+ return LayoutRect(rect);
|
||||
+}
|
||||
+
|
||||
} // namespace blink
|
||||
diff --git a/third_party/blink/renderer/core/layout/intersection_geometry.h b/third_party/blink/renderer/core/layout/intersection_geometry.h
|
||||
index cd264792a894bb2d25cb3df80a60cd667dcba36e..f08cfdbcc0778900558816eaaeee14dc662c3f9c 100644
|
||||
--- a/third_party/blink/renderer/core/layout/intersection_geometry.h
|
||||
+++ b/third_party/blink/renderer/core/layout/intersection_geometry.h
|
||||
@@ -38,12 +38,18 @@ class IntersectionGeometry {
|
||||
|
||||
// Client rect in the coordinate system of the frame containing target.
|
||||
LayoutRect TargetRect() const { return target_rect_; }
|
||||
+ // Target rect in CSS pixels
|
||||
+ LayoutRect UnZoomedTargetRect() const;
|
||||
|
||||
// Client rect in the coordinate system of the frame containing target.
|
||||
LayoutRect IntersectionRect() const { return intersection_rect_; }
|
||||
+ // Intersection rect in CSS pixels
|
||||
+ LayoutRect UnZoomedIntersectionRect() const;
|
||||
|
||||
// Client rect in the coordinate system of the frame containing root.
|
||||
LayoutRect RootRect() const { return root_rect_; }
|
||||
+ // Root rect in CSS pixels
|
||||
+ LayoutRect UnZoomedRootRect() const;
|
||||
|
||||
bool DoesIntersect() const { return does_intersect_; }
|
||||
|
||||
96
patches/common/chromium/keyboard-lock-service-impl.patch
Normal file
96
patches/common/chromium/keyboard-lock-service-impl.patch
Normal file
@@ -0,0 +1,96 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Joe Downing <joedow@chromium.org>
|
||||
Date: Thu, 27 Sep 2018 00:24:13 +0000
|
||||
Subject: Destroy KeyboardLockServiceImpl instance when RenderFrameHost goes
|
||||
away
|
||||
|
||||
This CL updates KeyboardLockServiceImpl to release its mojo binding if
|
||||
the RenderFrameHost instance it is linked to is destroyed.
|
||||
|
||||
Bug: 888678
|
||||
Change-Id: Icea5fe1a5c76df4d71fa4e78c423e49828664637
|
||||
Reviewed-on: https://chromium-review.googlesource.com/1246290
|
||||
Commit-Queue: Joe Downing <joedow@chromium.org>
|
||||
Reviewed-by: Daniel Cheng <dcheng@chromium.org>
|
||||
Reviewed-by: Scott Violet <sky@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/master@{#594534}
|
||||
|
||||
diff --git a/content/browser/keyboard_lock/keyboard_lock_service_impl.cc b/content/browser/keyboard_lock/keyboard_lock_service_impl.cc
|
||||
index f783d5356c8c81137ad99b366062aea1c76616a4..b0aa16010bbc602b0a854cd777221221164a49e3 100644
|
||||
--- a/content/browser/keyboard_lock/keyboard_lock_service_impl.cc
|
||||
+++ b/content/browser/keyboard_lock/keyboard_lock_service_impl.cc
|
||||
@@ -38,20 +38,22 @@ void LogKeyboardLockMethodCalled(KeyboardLockMethods method) {
|
||||
} // namespace
|
||||
|
||||
KeyboardLockServiceImpl::KeyboardLockServiceImpl(
|
||||
- RenderFrameHost* render_frame_host)
|
||||
- : render_frame_host_(static_cast<RenderFrameHostImpl*>(render_frame_host)) {
|
||||
+ RenderFrameHost* render_frame_host,
|
||||
+ blink::mojom::KeyboardLockServiceRequest request)
|
||||
+ : FrameServiceBase(render_frame_host, std::move(request)),
|
||||
+ render_frame_host_(static_cast<RenderFrameHostImpl*>(render_frame_host)) {
|
||||
DCHECK(render_frame_host_);
|
||||
}
|
||||
|
||||
-KeyboardLockServiceImpl::~KeyboardLockServiceImpl() = default;
|
||||
-
|
||||
// static
|
||||
void KeyboardLockServiceImpl::CreateMojoService(
|
||||
RenderFrameHost* render_frame_host,
|
||||
blink::mojom::KeyboardLockServiceRequest request) {
|
||||
- mojo::MakeStrongBinding(
|
||||
- std::make_unique<KeyboardLockServiceImpl>(render_frame_host),
|
||||
- std::move(request));
|
||||
+ DCHECK(render_frame_host);
|
||||
+
|
||||
+ // The object is bound to the lifetime of |render_frame_host| and the mojo
|
||||
+ // connection. See FrameServiceBase for details.
|
||||
+ new KeyboardLockServiceImpl(render_frame_host, std::move(request));
|
||||
}
|
||||
|
||||
void KeyboardLockServiceImpl::RequestKeyboardLock(
|
||||
@@ -131,4 +133,6 @@ void KeyboardLockServiceImpl::GetKeyboardLayoutMap(
|
||||
std::move(callback).Run(std::move(response));
|
||||
}
|
||||
|
||||
+KeyboardLockServiceImpl::~KeyboardLockServiceImpl() = default;
|
||||
+
|
||||
} // namespace content
|
||||
diff --git a/content/browser/keyboard_lock/keyboard_lock_service_impl.h b/content/browser/keyboard_lock/keyboard_lock_service_impl.h
|
||||
index 19c2f994758801e7d21d5256ec762eab84e7dd15..eecefd26e448befcb9c12b7203271c04d728751f 100644
|
||||
--- a/content/browser/keyboard_lock/keyboard_lock_service_impl.h
|
||||
+++ b/content/browser/keyboard_lock/keyboard_lock_service_impl.h
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "content/common/content_export.h"
|
||||
+#include "content/public/browser/frame_service_base.h"
|
||||
#include "mojo/public/cpp/bindings/strong_binding.h"
|
||||
#include "third_party/blink/public/platform/modules/keyboard_lock/keyboard_lock.mojom.h"
|
||||
|
||||
@@ -17,11 +18,11 @@ namespace content {
|
||||
class RenderFrameHost;
|
||||
class RenderFrameHostImpl;
|
||||
|
||||
-class CONTENT_EXPORT KeyboardLockServiceImpl
|
||||
- : public blink::mojom::KeyboardLockService {
|
||||
+class CONTENT_EXPORT KeyboardLockServiceImpl final
|
||||
+ : public FrameServiceBase<blink::mojom::KeyboardLockService> {
|
||||
public:
|
||||
- explicit KeyboardLockServiceImpl(RenderFrameHost* render_frame_host);
|
||||
- ~KeyboardLockServiceImpl() override;
|
||||
+ KeyboardLockServiceImpl(RenderFrameHost* render_frame_host,
|
||||
+ blink::mojom::KeyboardLockServiceRequest request);
|
||||
|
||||
static void CreateMojoService(
|
||||
RenderFrameHost* render_frame_host,
|
||||
@@ -34,6 +35,9 @@ class CONTENT_EXPORT KeyboardLockServiceImpl
|
||||
void GetKeyboardLayoutMap(GetKeyboardLayoutMapCallback callback) override;
|
||||
|
||||
private:
|
||||
+ // |this| can only be destroyed by FrameServiceBase.
|
||||
+ ~KeyboardLockServiceImpl() override;
|
||||
+
|
||||
RenderFrameHostImpl* const render_frame_host_;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,246 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Eric Roman <eroman@chromium.org>
|
||||
Date: Tue, 8 Jan 2019 22:35:26 +0000
|
||||
Subject: Make --explicitly-allowed-ports work with NetworkService.
|
||||
|
||||
This also makes it work in content_shell, whereas previously it was only wired up in chrome.
|
||||
|
||||
Bug: 916025
|
||||
Change-Id: Ic79e478d02160e2cb0727a22495c029f21447796
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/1400042
|
||||
Commit-Queue: Eric Roman <eroman@chromium.org>
|
||||
Reviewed-by: John Abd-El-Malek <jam@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/master@{#620910}
|
||||
|
||||
diff --git a/chrome/browser/ui/startup/startup_browser_creator.cc b/chrome/browser/ui/startup/startup_browser_creator.cc
|
||||
index e2afc34bd98f6a6cc76132dc4d1f8ca5c84afbaf..1a86063573849d5e174603ce418beebd103120d3 100644
|
||||
--- a/chrome/browser/ui/startup/startup_browser_creator.cc
|
||||
+++ b/chrome/browser/ui/startup/startup_browser_creator.cc
|
||||
@@ -66,7 +66,6 @@
|
||||
#include "content/public/browser/notification_source.h"
|
||||
#include "content/public/common/content_switches.h"
|
||||
#include "extensions/common/switches.h"
|
||||
-#include "net/base/port_util.h"
|
||||
#include "printing/buildflags/buildflags.h"
|
||||
|
||||
#if defined(OS_CHROMEOS)
|
||||
@@ -585,12 +584,6 @@ bool StartupBrowserCreator::ProcessCmdLineImpl(
|
||||
}
|
||||
#endif // BUILDFLAG(ENABLE_PRINT_PREVIEW)
|
||||
|
||||
- if (command_line.HasSwitch(switches::kExplicitlyAllowedPorts)) {
|
||||
- std::string allowed_ports =
|
||||
- command_line.GetSwitchValueASCII(switches::kExplicitlyAllowedPorts);
|
||||
- net::SetExplicitlyAllowedPorts(allowed_ports);
|
||||
- }
|
||||
-
|
||||
if (command_line.HasSwitch(switches::kValidateCrx)) {
|
||||
if (!process_startup) {
|
||||
LOG(ERROR) << "chrome is already running; you must close all running "
|
||||
diff --git a/content/browser/net/net_command_line_flags_browsertest.cc b/content/browser/net/net_command_line_flags_browsertest.cc
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..e47cbbf08076216f60f0d01942626f162746e4f3
|
||||
--- /dev/null
|
||||
+++ b/content/browser/net/net_command_line_flags_browsertest.cc
|
||||
@@ -0,0 +1,52 @@
|
||||
+// Copyright 2018 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 "content/public/browser/browser_context.h"
|
||||
+#include "content/public/browser/storage_partition.h"
|
||||
+#include "content/public/browser/web_contents.h"
|
||||
+#include "content/public/test/browser_test_utils.h"
|
||||
+#include "content/public/test/content_browser_test.h"
|
||||
+#include "content/shell/browser/shell.h"
|
||||
+#include "services/network/public/cpp/network_switches.h"
|
||||
+
|
||||
+namespace content {
|
||||
+
|
||||
+class CommandLineFlagsBrowserTest : public ContentBrowserTest {
|
||||
+ protected:
|
||||
+ network::mojom::NetworkContext* network_context() {
|
||||
+ return content::BrowserContext::GetDefaultStoragePartition(
|
||||
+ shell()->web_contents()->GetBrowserContext())
|
||||
+ ->GetNetworkContext();
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
+// Tests that when no special command line flags are passed, requests to port 79
|
||||
+// (finger) fail with ERR_UNSAFE_PORT.
|
||||
+IN_PROC_BROWSER_TEST_F(CommandLineFlagsBrowserTest, Port79DefaultBlocked) {
|
||||
+ EXPECT_EQ(net::ERR_UNSAFE_PORT,
|
||||
+ content::LoadBasicRequest(network_context(),
|
||||
+ GURL("http://127.0.0.1:79"), 0, 0, 0));
|
||||
+}
|
||||
+
|
||||
+class ExplicitlyAllowPort79BrowserTest : public CommandLineFlagsBrowserTest {
|
||||
+ public:
|
||||
+ void SetUpCommandLine(base::CommandLine* command_line) override {
|
||||
+ command_line->AppendSwitchASCII(network::switches::kExplicitlyAllowedPorts,
|
||||
+ "79");
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
+// Tests that when run with the flag --explicitly-allowed-ports=79, requests to
|
||||
+// port 79 (finger) are permitted.
|
||||
+//
|
||||
+// The request may succeed or fail depending on the platform and what services
|
||||
+// are running, so the test just verifies the reason for failure is not
|
||||
+// ERR_UNSAFE_PORT.
|
||||
+IN_PROC_BROWSER_TEST_F(ExplicitlyAllowPort79BrowserTest, Load) {
|
||||
+ EXPECT_NE(net::ERR_UNSAFE_PORT,
|
||||
+ content::LoadBasicRequest(network_context(),
|
||||
+ GURL("http://127.0.0.1:79"), 0, 0, 0));
|
||||
+}
|
||||
+
|
||||
+} // namespace content
|
||||
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc
|
||||
index 35fdb9d351db5a6bdaa61742ec49dc75fe70cfa4..c72025ad2e825d3c7f8136434587bcebf8f858e0 100644
|
||||
--- a/content/browser/renderer_host/render_process_host_impl.cc
|
||||
+++ b/content/browser/renderer_host/render_process_host_impl.cc
|
||||
@@ -2782,6 +2782,7 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
|
||||
static const char* const kSwitchNames[] = {
|
||||
switches::kDisableColorCorrectRendering,
|
||||
network::switches::kNoReferrers,
|
||||
+ network::switches::kExplicitlyAllowedPorts,
|
||||
service_manager::switches::kDisableInProcessStackTraces,
|
||||
service_manager::switches::kDisableSeccompFilterSandbox,
|
||||
service_manager::switches::kNoSandbox,
|
||||
@@ -2863,7 +2864,6 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
|
||||
switches::kEnableWebGLDraftExtensions,
|
||||
switches::kEnableWebGLImageChromium,
|
||||
switches::kEnableWebVR,
|
||||
- switches::kExplicitlyAllowedPorts,
|
||||
switches::kFileUrlPathAlias,
|
||||
switches::kFMPNetworkQuietTimeout,
|
||||
switches::kForceColorProfile,
|
||||
diff --git a/content/browser/utility_process_host.cc b/content/browser/utility_process_host.cc
|
||||
index 9d7c9791bd99c361a9ba3edc539d9b48b46659d4..3d11373b77af8bc0db42a27fcfab3089f8aaed1c 100644
|
||||
--- a/content/browser/utility_process_host.cc
|
||||
+++ b/content/browser/utility_process_host.cc
|
||||
@@ -286,6 +286,7 @@ bool UtilityProcessHost::StartProcess() {
|
||||
network::switches::kIgnoreCertificateErrorsSPKIList,
|
||||
network::switches::kLogNetLog,
|
||||
network::switches::kNoReferrers,
|
||||
+ network::switches::kExplicitlyAllowedPorts,
|
||||
service_manager::switches::kNoSandbox,
|
||||
#if defined(OS_MACOSX)
|
||||
service_manager::switches::kEnableSandboxLogging,
|
||||
diff --git a/content/public/common/content_switches.cc b/content/public/common/content_switches.cc
|
||||
index 19c2246a3bd8dcc3d1e070b74ff3d416adc473fe..cdf81f6c35cd78b4fff4d666284d0615e6c057c6 100644
|
||||
--- a/content/public/common/content_switches.cc
|
||||
+++ b/content/public/common/content_switches.cc
|
||||
@@ -469,10 +469,6 @@ const char kEnableWebVR[] = "enable-webvr";
|
||||
// Enable rasterizer that writes directly to GPU memory associated with tiles.
|
||||
const char kEnableZeroCopy[] = "enable-zero-copy";
|
||||
|
||||
-// Explicitly allows additional ports using a comma-separated list of port
|
||||
-// numbers.
|
||||
-const char kExplicitlyAllowedPorts[] = "explicitly-allowed-ports";
|
||||
-
|
||||
// Handle to the shared memory segment containing field trial state that is to
|
||||
// be shared between processes. The argument to this switch is the handle id
|
||||
// (pointer on Windows) as a string, followed by a comma, then the size of the
|
||||
diff --git a/content/public/common/content_switches.h b/content/public/common/content_switches.h
|
||||
index 2c795e814b13961eb190d5c7f9bce3c854dbfc17..a4da6292e7c5784e06e686cd62e017b010fa7e27 100644
|
||||
--- a/content/public/common/content_switches.h
|
||||
+++ b/content/public/common/content_switches.h
|
||||
@@ -147,7 +147,6 @@ CONTENT_EXPORT extern const char kEnableWebGLDraftExtensions[];
|
||||
CONTENT_EXPORT extern const char kEnableWebGLImageChromium[];
|
||||
CONTENT_EXPORT extern const char kEnableWebVR[];
|
||||
CONTENT_EXPORT extern const char kEnableZeroCopy[];
|
||||
-CONTENT_EXPORT extern const char kExplicitlyAllowedPorts[];
|
||||
CONTENT_EXPORT extern const char kFieldTrialHandle[];
|
||||
CONTENT_EXPORT extern const char kFileUrlPathAlias[];
|
||||
CONTENT_EXPORT extern const char kForceDisplayList2dCanvas[];
|
||||
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc
|
||||
index 5c31ab7654d0168d232e9974105573fa01543aed..b670c95891ab80e749209a843d958ffcbdcc6ba2 100644
|
||||
--- a/content/renderer/render_thread_impl.cc
|
||||
+++ b/content/renderer/render_thread_impl.cc
|
||||
@@ -143,6 +143,7 @@
|
||||
#include "net/base/url_util.h"
|
||||
#include "ppapi/buildflags/buildflags.h"
|
||||
#include "services/metrics/public/cpp/mojo_ukm_recorder.h"
|
||||
+#include "services/network/public/cpp/network_switches.h"
|
||||
#include "services/service_manager/public/cpp/connector.h"
|
||||
#include "services/service_manager/public/cpp/interface_provider.h"
|
||||
#include "services/ui/public/cpp/gpu/context_provider_command_buffer.h"
|
||||
@@ -1281,9 +1282,9 @@ void RenderThreadImpl::InitializeWebKit(
|
||||
SkGraphics::SetImageGeneratorFromEncodedDataFactory(
|
||||
blink::WebImageGenerator::CreateAsSkImageGenerator);
|
||||
|
||||
- if (command_line.HasSwitch(switches::kExplicitlyAllowedPorts)) {
|
||||
- std::string allowed_ports =
|
||||
- command_line.GetSwitchValueASCII(switches::kExplicitlyAllowedPorts);
|
||||
+ if (command_line.HasSwitch(network::switches::kExplicitlyAllowedPorts)) {
|
||||
+ std::string allowed_ports = command_line.GetSwitchValueASCII(
|
||||
+ network::switches::kExplicitlyAllowedPorts);
|
||||
net::SetExplicitlyAllowedPorts(allowed_ports);
|
||||
}
|
||||
}
|
||||
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn
|
||||
index 15a64a49d5c821d3cb10b9dfd99725296e6a912c..a28467ec68e2b63964e396977c17a2cbb5cf2407 100644
|
||||
--- a/content/test/BUILD.gn
|
||||
+++ b/content/test/BUILD.gn
|
||||
@@ -791,6 +791,7 @@ test("content_browsertests") {
|
||||
"../browser/message_port_provider_browsertest.cc",
|
||||
"../browser/mojo_sandbox_browsertest.cc",
|
||||
"../browser/net/accept_header_browsertest.cc",
|
||||
+ "../browser/net/net_command_line_flags_browsertest.cc",
|
||||
"../browser/net_info_browsertest.cc",
|
||||
"../browser/network_service_browsertest.cc",
|
||||
"../browser/network_service_restart_browsertest.cc",
|
||||
diff --git a/services/network/network_service.cc b/services/network/network_service.cc
|
||||
index a91a9f4b5866c11ae76e2d173a92579f0b7d12a1..404c3fa8316abdd77b492468e29a577c0c9c0988 100644
|
||||
--- a/services/network/network_service.cc
|
||||
+++ b/services/network/network_service.cc
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "mojo/public/cpp/bindings/strong_binding.h"
|
||||
#include "net/base/logging_network_change_observer.h"
|
||||
#include "net/base/network_change_notifier.h"
|
||||
+#include "net/base/port_util.h"
|
||||
#include "net/cert/ct_log_response_parser.h"
|
||||
#include "net/cert/signed_tree_head.h"
|
||||
#include "net/dns/host_resolver.h"
|
||||
@@ -121,6 +122,13 @@ NetworkService::NetworkService(
|
||||
|
||||
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
|
||||
|
||||
+ // Set-up the global port overrides.
|
||||
+ if (command_line->HasSwitch(switches::kExplicitlyAllowedPorts)) {
|
||||
+ std::string allowed_ports =
|
||||
+ command_line->GetSwitchValueASCII(switches::kExplicitlyAllowedPorts);
|
||||
+ net::SetExplicitlyAllowedPorts(allowed_ports);
|
||||
+ }
|
||||
+
|
||||
// Record this once per session, though the switch is appled on a
|
||||
// per-NetworkContext basis.
|
||||
UMA_HISTOGRAM_BOOLEAN(
|
||||
diff --git a/services/network/public/cpp/network_switches.cc b/services/network/public/cpp/network_switches.cc
|
||||
index 7790a6fa6e749f0f87d104f0175ad76d5aace108..6e489aafa30155fbbf75edfbffd17f93159e5665 100644
|
||||
--- a/services/network/public/cpp/network_switches.cc
|
||||
+++ b/services/network/public/cpp/network_switches.cc
|
||||
@@ -37,6 +37,10 @@ const char kLogNetLog[] = "log-net-log";
|
||||
// Don't send HTTP-Referer headers.
|
||||
const char kNoReferrers[] = "no-referrers";
|
||||
|
||||
+// Allows overriding the list of restricted ports by passing a comma-separated
|
||||
+// list of port numbers.
|
||||
+const char kExplicitlyAllowedPorts[] = "explicitly-allowed-ports";
|
||||
+
|
||||
} // namespace switches
|
||||
|
||||
} // namespace network
|
||||
diff --git a/services/network/public/cpp/network_switches.h b/services/network/public/cpp/network_switches.h
|
||||
index 3829a2d4360e6b04fc348712f236451ee704c575..28edfb93d4eaa3797a24691772850dc0009d50c9 100644
|
||||
--- a/services/network/public/cpp/network_switches.h
|
||||
+++ b/services/network/public/cpp/network_switches.h
|
||||
@@ -18,6 +18,7 @@ COMPONENT_EXPORT(NETWORK_CPP)
|
||||
extern const char kIgnoreCertificateErrorsSPKIList[];
|
||||
COMPONENT_EXPORT(NETWORK_CPP) extern const char kLogNetLog[];
|
||||
COMPONENT_EXPORT(NETWORK_CPP) extern const char kNoReferrers[];
|
||||
+COMPONENT_EXPORT(NETWORK_CPP) extern const char kExplicitlyAllowedPorts[];
|
||||
|
||||
} // namespace switches
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user