mirror of
https://github.com/electron/electron.git
synced 2026-02-26 03:01:17 -05:00
Compare commits
162 Commits
v20.0.0-be
...
v20.3.5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e8b8ee1454 | ||
|
|
b9d0a5aee3 | ||
|
|
bc3d0bf0c2 | ||
|
|
a0f608b8b6 | ||
|
|
92a338a273 | ||
|
|
f8ab27474f | ||
|
|
d844933377 | ||
|
|
30046ca08d | ||
|
|
98ab127aa1 | ||
|
|
1008774610 | ||
|
|
782e5adc99 | ||
|
|
806d0840ff | ||
|
|
bdf6126133 | ||
|
|
378110b748 | ||
|
|
117b264db5 | ||
|
|
109009f3e7 | ||
|
|
b2ca7f9c05 | ||
|
|
5382df7ea2 | ||
|
|
aedfdadf1b | ||
|
|
7a70765ba1 | ||
|
|
a7ae2511d2 | ||
|
|
cf9f5ca5b8 | ||
|
|
2e85e7fd69 | ||
|
|
3028dcd785 | ||
|
|
d010bcca86 | ||
|
|
1ba8128c8c | ||
|
|
25e504a7ed | ||
|
|
589199f335 | ||
|
|
c0371ab218 | ||
|
|
50f2f10b94 | ||
|
|
2ee36539ba | ||
|
|
0d05ce8d12 | ||
|
|
9e064fec80 | ||
|
|
619a88cf56 | ||
|
|
080bc57145 | ||
|
|
a03ec151e1 | ||
|
|
0858a08097 | ||
|
|
53b6270320 | ||
|
|
4c44e86fd1 | ||
|
|
543a29c926 | ||
|
|
c0c83d2719 | ||
|
|
a7848809fc | ||
|
|
d8ca287700 | ||
|
|
b0c881f608 | ||
|
|
6620ba4e15 | ||
|
|
1babaec6da | ||
|
|
cbe1debbe2 | ||
|
|
3c73ea5259 | ||
|
|
02622b02a6 | ||
|
|
700906c1f1 | ||
|
|
d19a0ac51b | ||
|
|
25521f6286 | ||
|
|
f89b51fe0a | ||
|
|
2a42cd2f65 | ||
|
|
9e419bc4e9 | ||
|
|
1921f802fd | ||
|
|
06e585d82f | ||
|
|
febee696d6 | ||
|
|
57917c4b5a | ||
|
|
3f7f4de319 | ||
|
|
91bafdd3d5 | ||
|
|
c676831a54 | ||
|
|
a62b98a23f | ||
|
|
cbd39f73f8 | ||
|
|
eb819e0881 | ||
|
|
36885ea919 | ||
|
|
bc09b08664 | ||
|
|
880d06e304 | ||
|
|
cb5b28f833 | ||
|
|
e867b08172 | ||
|
|
4541c432af | ||
|
|
604034a899 | ||
|
|
c256db23ce | ||
|
|
c19f09e92e | ||
|
|
328368be56 | ||
|
|
73deb5f56d | ||
|
|
46c416190b | ||
|
|
046ef10147 | ||
|
|
7c8d5f68d5 | ||
|
|
4be4dc7c4f | ||
|
|
5cfb58161c | ||
|
|
2f116aacfb | ||
|
|
2f5c0f9eec | ||
|
|
c730abc55d | ||
|
|
61f385a89e | ||
|
|
389911d7e2 | ||
|
|
85ae4c4a77 | ||
|
|
bb0a66823b | ||
|
|
e9b721ba51 | ||
|
|
42bb395529 | ||
|
|
7a418ffa43 | ||
|
|
1e14b3ebb8 | ||
|
|
dbaa3528f9 | ||
|
|
44bd6aac3a | ||
|
|
fef7d52e73 | ||
|
|
0bdb5ac85a | ||
|
|
1e54a8d3fe | ||
|
|
5ef4b258ec | ||
|
|
dad125a0e0 | ||
|
|
42e2e54730 | ||
|
|
3795fbaccb | ||
|
|
7358d0fd71 | ||
|
|
f85bd310c8 | ||
|
|
a415eb6f06 | ||
|
|
3f6b9a8fcd | ||
|
|
cc17929ebb | ||
|
|
a85ad0ea38 | ||
|
|
91e09c69bd | ||
|
|
6e27b53527 | ||
|
|
534d313758 | ||
|
|
30b446ca32 | ||
|
|
7e6d0d4c3c | ||
|
|
6eabd3c72b | ||
|
|
f0302c4981 | ||
|
|
3c71a812c3 | ||
|
|
58981b69b1 | ||
|
|
6a451311cd | ||
|
|
09beb48648 | ||
|
|
e6fc453d90 | ||
|
|
305751aa47 | ||
|
|
d8fbdf6b3e | ||
|
|
c84a45f9f2 | ||
|
|
5274c253db | ||
|
|
8e70826af6 | ||
|
|
9afa4194ac | ||
|
|
062f7c0cb1 | ||
|
|
13cfb4ef8f | ||
|
|
39d08c3f2a | ||
|
|
1a6d998c34 | ||
|
|
ab426d5abf | ||
|
|
6ff154c7cc | ||
|
|
910dd786a9 | ||
|
|
d7fedd2961 | ||
|
|
f20a51a87f | ||
|
|
6c29ab10a4 | ||
|
|
b61692d790 | ||
|
|
0e6f172897 | ||
|
|
aa99d73990 | ||
|
|
f1c7562d9c | ||
|
|
08aa57806e | ||
|
|
76450afd47 | ||
|
|
8ac0e2bdec | ||
|
|
c61a14c5d1 | ||
|
|
ecdfca8f13 | ||
|
|
2f9414dcc4 | ||
|
|
816e8e804c | ||
|
|
5f1c3b4d13 | ||
|
|
7b1872dafe | ||
|
|
c10922f15f | ||
|
|
d8edf84cfc | ||
|
|
215ae2b012 | ||
|
|
09c4fdd6d0 | ||
|
|
77d561a8a6 | ||
|
|
3777902abc | ||
|
|
3a079feb87 | ||
|
|
8d68009abc | ||
|
|
4f3be68ad5 | ||
|
|
c7509b0a53 | ||
|
|
fa4052fc9e | ||
|
|
e02fbe1d29 | ||
|
|
7e06da25ef | ||
|
|
f0ae458f6f |
@@ -216,6 +216,7 @@ step-maybe-cleanup-arm64-mac: &step-maybe-cleanup-arm64-mac
|
||||
rm -rf ~/Library/Application\ Support/electron*
|
||||
security delete-generic-password -l "Chromium Safe Storage" || echo "✓ Keychain does not contain password from tests"
|
||||
security delete-generic-password -l "Electron Test Main Safe Storage" || echo "✓ Keychain does not contain password from tests"
|
||||
security delete-generic-password -a "electron-test-safe-storage" || echo "✓ Keychain does not contain password from tests"
|
||||
elif [ "$TARGET_ARCH" == "arm" ] || [ "$TARGET_ARCH" == "arm64" ]; then
|
||||
XVFB=/usr/bin/Xvfb
|
||||
/sbin/start-stop-daemon --stop --exec $XVFB || echo "Xvfb not running"
|
||||
@@ -346,7 +347,7 @@ step-wait-for-goma: &step-wait-for-goma
|
||||
sleep 5
|
||||
done
|
||||
echo "Goma ready"
|
||||
no_output_timeout: 2m
|
||||
no_output_timeout: 5m
|
||||
|
||||
step-restore-brew-cache: &step-restore-brew-cache
|
||||
restore_cache:
|
||||
@@ -454,7 +455,7 @@ step-delete-git-directories: &step-delete-git-directories
|
||||
command: |
|
||||
if [ "`uname`" == "Darwin" ]; then
|
||||
cd src
|
||||
( find . -type d -name ".git" -not -path "./third_party/angle/*" -not -path "./third_party/dawn/*" ) | xargs rm -rf
|
||||
( find . -type d -name ".git" -not -path "./third_party/angle/*" -not -path "./third_party/dawn/*" -not -path "./electron/*" ) | xargs rm -rf
|
||||
fi
|
||||
|
||||
# On macOS the yarn install command during gclient sync was run on a linux
|
||||
@@ -812,7 +813,7 @@ step-maybe-zip-symbols: &step-maybe-zip-symbols
|
||||
cd src
|
||||
export BUILD_PATH="$PWD/out/Default"
|
||||
ninja -C out/Default electron:licenses
|
||||
ninja -C out/Default electron:electron_version
|
||||
ninja -C out/Default electron:electron_version_file
|
||||
DELETE_DSYMS_AFTER_ZIP=1 electron/script/zip-symbols.py -b $BUILD_PATH
|
||||
|
||||
step-maybe-cross-arch-snapshot: &step-maybe-cross-arch-snapshot
|
||||
@@ -872,12 +873,12 @@ step-touch-sync-done: &step-touch-sync-done
|
||||
step-maybe-restore-src-cache: &step-maybe-restore-src-cache
|
||||
restore_cache:
|
||||
keys:
|
||||
- v14-src-cache-{{ checksum "src/electron/.depshash" }}
|
||||
- v15-src-cache-{{ checksum "src/electron/.depshash" }}
|
||||
name: Restoring src cache
|
||||
step-maybe-restore-src-cache-marker: &step-maybe-restore-src-cache-marker
|
||||
restore_cache:
|
||||
keys:
|
||||
- v14-src-cache-marker-{{ checksum "src/electron/.depshash" }}
|
||||
- v15-src-cache-marker-{{ checksum "src/electron/.depshash" }}
|
||||
name: Restoring src cache marker
|
||||
|
||||
# Restore exact or closest git cache based on the hash of DEPS and .circle-sync-done
|
||||
@@ -953,13 +954,14 @@ step-minimize-workspace-size-from-checkout: &step-minimize-workspace-size-from-c
|
||||
rm -rf third_party/electron_node/deps/openssl
|
||||
rm -rf third_party/electron_node/deps/v8
|
||||
rm -rf chrome/test/data/xr/webvr_info
|
||||
rm -rf src/third_party/angle/third_party/VK-GL-CTS/src
|
||||
|
||||
# Save the src cache based on the deps hash
|
||||
step-save-src-cache: &step-save-src-cache
|
||||
save_cache:
|
||||
paths:
|
||||
- /var/portal
|
||||
key: v14-src-cache-{{ checksum "/var/portal/src/electron/.depshash" }}
|
||||
key: v15-src-cache-{{ checksum "/var/portal/src/electron/.depshash" }}
|
||||
name: Persisting src cache
|
||||
step-make-src-cache-marker: &step-make-src-cache-marker
|
||||
run:
|
||||
@@ -969,7 +971,7 @@ step-save-src-cache-marker: &step-save-src-cache-marker
|
||||
save_cache:
|
||||
paths:
|
||||
- .src-cache-marker
|
||||
key: v14-src-cache-marker-{{ checksum "/var/portal/src/electron/.depshash" }}
|
||||
key: v15-src-cache-marker-{{ checksum "/var/portal/src/electron/.depshash" }}
|
||||
|
||||
step-maybe-early-exit-no-doc-change: &step-maybe-early-exit-no-doc-change
|
||||
run:
|
||||
|
||||
2
.github/semantic.yml
vendored
2
.github/semantic.yml
vendored
@@ -1,2 +0,0 @@
|
||||
# Always validate the PR title, and ignore the commits
|
||||
titleOnly: true
|
||||
178
.github/workflows/electron_woa_testing.yml
vendored
Normal file
178
.github/workflows/electron_woa_testing.yml
vendored
Normal file
@@ -0,0 +1,178 @@
|
||||
name: Electron WOA Testing
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: '**'
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
appveyor_job_id:
|
||||
description: 'Job Id of Appveyor WOA job to test'
|
||||
type: text
|
||||
required: true
|
||||
|
||||
jobs:
|
||||
electron-woa-init:
|
||||
if: ${{ github.event_name == 'push' && github.repository == 'electron/electron' }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Dummy step for push event
|
||||
run: |
|
||||
echo "This job is a needed initialization step for Electron WOA testing. Another test result will appear once the electron-woa-testing build is done."
|
||||
|
||||
electron-woa-testing:
|
||||
if: ${{ github.event_name == 'workflow_dispatch' && github.repository == 'electron/electron' }}
|
||||
runs-on: [self-hosted, woa]
|
||||
permissions:
|
||||
checks: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
- uses: LouisBrunner/checks-action@v1.1.1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
name: electron-woa-testing
|
||||
status: in_progress
|
||||
details_url: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
||||
output: |
|
||||
{"summary":"Test In Progress","text_description":"See job details here: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"}
|
||||
- name: Clean Workspace
|
||||
run: |
|
||||
Remove-Item * -Recurse -Force
|
||||
shell: powershell
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
path: src\electron
|
||||
fetch-depth: 0
|
||||
- name: Yarn install
|
||||
run: |
|
||||
cd src\electron
|
||||
node script/yarn.js install --frozen-lockfile
|
||||
- name: Download and extract dist.zip for test
|
||||
run: |
|
||||
$localArtifactPath = "$pwd\dist.zip"
|
||||
$serverArtifactPath = "https://ci.appveyor.com/api/buildjobs/${{ inputs.appveyor_job_id }}/artifacts/dist.zip"
|
||||
Invoke-RestMethod -Method Get -Uri $serverArtifactPath -OutFile $localArtifactPath -Headers @{ "Authorization" = "Bearer ${{ secrets.APPVEYOR_TOKEN }}" }
|
||||
& "${env:ProgramFiles(x86)}\7-Zip\7z.exe" x -osrc\out\Default -y $localArtifactPath
|
||||
shell: powershell
|
||||
- name: Download and extract native test executables for test
|
||||
run: |
|
||||
$localArtifactPath = "src\out\Default\shell_browser_ui_unittests.exe"
|
||||
$serverArtifactPath = "https://ci.appveyor.com/api/buildjobs/${{ inputs.appveyor_job_id }}/artifacts/shell_browser_ui_unittests.exe"
|
||||
Invoke-RestMethod -Method Get -Uri $serverArtifactPath -OutFile $localArtifactPath -Headers @{ "Authorization" = "Bearer ${{ secrets.APPVEYOR_TOKEN }}" }
|
||||
shell: powershell
|
||||
- name: Download and extract ffmpeg.zip for test
|
||||
run: |
|
||||
$localArtifactPath = "$pwd\ffmpeg.zip"
|
||||
$serverArtifactPath = "https://ci.appveyor.com/api/buildjobs/${{ inputs.appveyor_job_id }}/artifacts/ffmpeg.zip"
|
||||
Invoke-RestMethod -Method Get -Uri $serverArtifactPath -OutFile $localArtifactPath -Headers @{ "Authorization" = "Bearer ${{ secrets.APPVEYOR_TOKEN }}" }
|
||||
& "${env:ProgramFiles(x86)}\7-Zip\7z.exe" x -osrc\out\ffmpeg $localArtifactPath
|
||||
shell: powershell
|
||||
- name: Download node headers for test
|
||||
run: |
|
||||
$localArtifactPath = "src\node_headers.zip"
|
||||
$serverArtifactPath = "https://ci.appveyor.com/api/buildjobs/${{ inputs.appveyor_job_id }}/artifacts/node_headers.zip"
|
||||
Invoke-RestMethod -Method Get -Uri $serverArtifactPath -OutFile $localArtifactPath -Headers @{ "Authorization" = "Bearer ${{ secrets.APPVEYOR_TOKEN }}" }
|
||||
cd src
|
||||
& "${env:ProgramFiles(x86)}\7-Zip\7z.exe" x -y node_headers.zip
|
||||
shell: powershell
|
||||
- name: Download electron.lib for test
|
||||
run: |
|
||||
$localArtifactPath = "src\out\Default\electron.lib"
|
||||
$serverArtifactPath = "https://ci.appveyor.com/api/buildjobs/${{ inputs.appveyor_job_id }}/artifacts/electron.lib"
|
||||
Invoke-RestMethod -Method Get -Uri $serverArtifactPath -OutFile $localArtifactPath -Headers @{ "Authorization" = "Bearer ${{ secrets.APPVEYOR_TOKEN }}" }
|
||||
shell: powershell
|
||||
# Uncomment the following block if pdb files are needed to debug issues
|
||||
# - name: Download pdb files for detailed stacktraces
|
||||
# if: ${{ github.event_name == 'workflow_dispatch' }}
|
||||
# run: |
|
||||
# try {
|
||||
# $localArtifactPath = "src\pdb.zip"
|
||||
# $serverArtifactPath = "https://ci.appveyor.com/api/buildjobs/${{ inputs.appveyor_job_id }}/artifacts/pdb.zip"
|
||||
# Invoke-RestMethod -Method Get -Uri $serverArtifactPath -OutFile $localArtifactPath -Headers @{ "Authorization" = "Bearer ${{ secrets.APPVEYOR_TOKEN }}" }
|
||||
# cd src
|
||||
# & "${env:ProgramFiles(x86)}\7-Zip\7z.exe" x -y pdb.zip
|
||||
# } catch {
|
||||
# Write-Host "There was an exception encountered while downloading pdb files:" $_.Exception.Message
|
||||
# } finally {
|
||||
# $global:LASTEXITCODE = 0
|
||||
# }
|
||||
# shell: powershell
|
||||
- name: Setup node headers
|
||||
run: |
|
||||
New-Item src\out\Default\gen\node_headers\Release -Type directory
|
||||
Copy-Item -path src\out\Default\electron.lib -destination src\out\Default\gen\node_headers\Release\node.lib
|
||||
shell: powershell
|
||||
- name: Run Electron Main process tests
|
||||
run: |
|
||||
cd src
|
||||
set npm_config_nodedir=%cd%\out\Default\gen\node_headers
|
||||
set npm_config_arch=arm64
|
||||
cd electron
|
||||
node script/yarn test --runners=main --enable-logging --disable-features=CalculateNativeWinOcclusion
|
||||
env:
|
||||
ELECTRON_ENABLE_STACK_DUMPING: true
|
||||
ELECTRON_OUT_DIR: Default
|
||||
IGNORE_YARN_INSTALL_ERROR: 1
|
||||
ELECTRON_TEST_RESULTS_DIR: junit
|
||||
MOCHA_MULTI_REPORTERS: 'mocha-junit-reporter, tap'
|
||||
MOCHA_REPORTER: mocha-multi-reporters
|
||||
ELECTRON_SKIP_NATIVE_MODULE_TESTS: true
|
||||
- name: Run Electron Remote based tests
|
||||
if: ${{ success() || failure() }}
|
||||
run: |
|
||||
cd src
|
||||
set npm_config_nodedir=%cd%\out\Default\gen\node_headers
|
||||
set npm_config_arch=arm64
|
||||
cd electron
|
||||
node script/yarn test --runners=remote --enable-logging --disable-features=CalculateNativeWinOcclusion
|
||||
env:
|
||||
ELECTRON_OUT_DIR: Default
|
||||
IGNORE_YARN_INSTALL_ERROR: 1
|
||||
ELECTRON_TEST_RESULTS_DIR: junit
|
||||
MOCHA_MULTI_REPORTERS: 'mocha-junit-reporter, tap'
|
||||
MOCHA_REPORTER: mocha-multi-reporters
|
||||
ELECTRON_SKIP_NATIVE_MODULE_TESTS: true
|
||||
- name: Verify ffmpeg
|
||||
run: |
|
||||
cd src
|
||||
echo "Verifying non proprietary ffmpeg"
|
||||
python electron\script\verify-ffmpeg.py --build-dir out\Default --source-root %cd% --ffmpeg-path out\ffmpeg
|
||||
shell: cmd
|
||||
- name: Kill processes left running from last test run
|
||||
if: ${{ always() }}
|
||||
run: |
|
||||
Get-Process | Where Name -Like "electron*" | Stop-Process
|
||||
Get-Process | Where Name -Like "msedge*" | Stop-Process
|
||||
shell: powershell
|
||||
- name: Delete user app data directories
|
||||
if: ${{ always() }}
|
||||
run: |
|
||||
Remove-Item -path $env:APPDATA/Electron* -Recurse -Force -ErrorAction Ignore
|
||||
shell: powershell
|
||||
- uses: LouisBrunner/checks-action@v1.1.1
|
||||
if: ${{ success() }}
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
name: electron-woa-testing
|
||||
conclusion: "${{ job.status }}"
|
||||
details_url: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
||||
output: |
|
||||
{"summary":"${{ job.status }}","text_description":"See job details here: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"}
|
||||
- uses: LouisBrunner/checks-action@v1.1.1
|
||||
if: ${{ success() }}
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
name: electron-woa-testing
|
||||
conclusion: "${{ job.status }}"
|
||||
details_url: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
||||
output: |
|
||||
{"summary":"Job Succeeded","text_description":"See job details here: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"}
|
||||
- uses: LouisBrunner/checks-action@v1.1.1
|
||||
if: ${{ ! success() }}
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
name: electron-woa-testing
|
||||
conclusion: "${{ job.status }}"
|
||||
details_url: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
||||
output: |
|
||||
{"summary":"Job Failed","text_description":"See job details here: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"}
|
||||
71
BUILD.gn
71
BUILD.gn
@@ -107,6 +107,14 @@ branding = read_file("shell/app/BRANDING.json", "json")
|
||||
electron_project_name = branding.project_name
|
||||
electron_product_name = branding.product_name
|
||||
electron_mac_bundle_id = branding.mac_bundle_id
|
||||
electron_version = exec_script("script/print-version.py",
|
||||
[],
|
||||
"trim string",
|
||||
[
|
||||
".git/packed-refs",
|
||||
".git/HEAD",
|
||||
"script/lib/get-version.js",
|
||||
])
|
||||
|
||||
if (is_mas_build) {
|
||||
assert(is_mac,
|
||||
@@ -233,6 +241,7 @@ action("electron_js2c") {
|
||||
action("generate_config_gypi") {
|
||||
outputs = [ "$root_gen_dir/config.gypi" ]
|
||||
script = "script/generate-config-gypi.py"
|
||||
inputs = [ "//third_party/electron_node/configure.py" ]
|
||||
args = rebase_path(outputs) + [ target_cpu ]
|
||||
}
|
||||
|
||||
@@ -301,12 +310,9 @@ npm_action("electron_version_args") {
|
||||
|
||||
outputs = [ "$target_gen_dir/electron_version.args" ]
|
||||
|
||||
args = rebase_path(outputs)
|
||||
args = rebase_path(outputs) + [ "$electron_version" ]
|
||||
|
||||
inputs = [
|
||||
"ELECTRON_VERSION",
|
||||
"script/generate-version-json.js",
|
||||
]
|
||||
inputs = [ "script/generate-version-json.js" ]
|
||||
}
|
||||
|
||||
templated_file("electron_version_header") {
|
||||
@@ -318,6 +324,39 @@ templated_file("electron_version_header") {
|
||||
args_files = get_target_outputs(":electron_version_args")
|
||||
}
|
||||
|
||||
templated_file("electron_win_rc") {
|
||||
deps = [ ":electron_version_args" ]
|
||||
|
||||
template = "build/templates/electron_rc.tmpl"
|
||||
output = "$target_gen_dir/win-resources/electron.rc"
|
||||
|
||||
args_files = get_target_outputs(":electron_version_args")
|
||||
}
|
||||
|
||||
copy("electron_win_resource_files") {
|
||||
sources = [
|
||||
"shell/browser/resources/win/electron.ico",
|
||||
"shell/browser/resources/win/resource.h",
|
||||
]
|
||||
outputs = [ "$target_gen_dir/win-resources/{{source_file_part}}" ]
|
||||
}
|
||||
|
||||
templated_file("electron_version_file") {
|
||||
deps = [ ":electron_version_args" ]
|
||||
|
||||
template = "build/templates/version_string.tmpl"
|
||||
output = "$root_build_dir/version"
|
||||
|
||||
args_files = get_target_outputs(":electron_version_args")
|
||||
}
|
||||
|
||||
group("electron_win32_resources") {
|
||||
public_deps = [
|
||||
":electron_win_rc",
|
||||
":electron_win_resource_files",
|
||||
]
|
||||
}
|
||||
|
||||
action("electron_fuses") {
|
||||
script = "build/fuses/build.py"
|
||||
|
||||
@@ -402,9 +441,6 @@ source_set("electron_lib") {
|
||||
"//media/mojo/mojom",
|
||||
"//net:extras",
|
||||
"//net:net_resources",
|
||||
"//ppapi/host",
|
||||
"//ppapi/proxy",
|
||||
"//ppapi/shared_impl",
|
||||
"//printing/buildflags",
|
||||
"//services/device/public/cpp/geolocation",
|
||||
"//services/device/public/cpp/hid",
|
||||
@@ -615,7 +651,12 @@ source_set("electron_lib") {
|
||||
}
|
||||
|
||||
if (enable_plugins) {
|
||||
deps += [ "chromium_src:plugins" ]
|
||||
deps += [
|
||||
"chromium_src:plugins",
|
||||
"//ppapi/host",
|
||||
"//ppapi/proxy",
|
||||
"//ppapi/shared_impl",
|
||||
]
|
||||
sources += [
|
||||
"shell/renderer/pepper_helper.cc",
|
||||
"shell/renderer/pepper_helper.h",
|
||||
@@ -749,7 +790,6 @@ 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("ELECTRON_VERSION", "trim string")
|
||||
|
||||
mac_xib_bundle_data("electron_xibs") {
|
||||
sources = [ "shell/common/resources/mac/MainMenu.xib" ]
|
||||
@@ -1183,6 +1223,7 @@ if (is_mac) {
|
||||
":default_app_asar",
|
||||
":electron_app_manifest",
|
||||
":electron_lib",
|
||||
":electron_win32_resources",
|
||||
":packed_resources",
|
||||
"//components/crash/core/app",
|
||||
"//content:sandbox_helper_win",
|
||||
@@ -1216,8 +1257,7 @@ if (is_mac) {
|
||||
|
||||
if (is_win) {
|
||||
sources += [
|
||||
# TODO: we should be generating our .rc files more like how chrome does
|
||||
"shell/browser/resources/win/electron.rc",
|
||||
"$target_gen_dir/win-resources/electron.rc",
|
||||
"shell/browser/resources/win/resource.h",
|
||||
]
|
||||
|
||||
@@ -1399,15 +1439,10 @@ group("licenses") {
|
||||
]
|
||||
}
|
||||
|
||||
copy("electron_version") {
|
||||
sources = [ "ELECTRON_VERSION" ]
|
||||
outputs = [ "$root_build_dir/version" ]
|
||||
}
|
||||
|
||||
dist_zip("electron_dist_zip") {
|
||||
data_deps = [
|
||||
":electron_app",
|
||||
":electron_version",
|
||||
":electron_version_file",
|
||||
":licenses",
|
||||
]
|
||||
if (is_linux) {
|
||||
|
||||
2
DEPS
2
DEPS
@@ -2,7 +2,7 @@ gclient_gn_args_from = 'src'
|
||||
|
||||
vars = {
|
||||
'chromium_version':
|
||||
'104.0.5112.48',
|
||||
'104.0.5112.124',
|
||||
'node_version':
|
||||
'v16.15.0',
|
||||
'nan_version':
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
20.0.0-beta.10
|
||||
@@ -38,7 +38,7 @@ For more installation options and troubleshooting tips, see
|
||||
|
||||
Each Electron release provides binaries for macOS, Windows, and Linux.
|
||||
|
||||
* macOS (El Capitan and up): Electron provides 64-bit Intel and ARM binaries for macOS. Apple Silicon support was added in Electron 11.
|
||||
* macOS (High Sierra and up): Electron provides 64-bit Intel and ARM binaries for macOS. Apple Silicon support was added in Electron 11.
|
||||
* Windows (Windows 7 and up): Electron provides `ia32` (`x86`), `x64` (`amd64`), and `arm64` binaries for Windows. Windows on ARM support was added in Electron 5.0.8.
|
||||
* Linux: The prebuilt binaries of Electron are built on Ubuntu 20.04. They have also been verified to work on:
|
||||
* Ubuntu 14.04 and newer
|
||||
|
||||
23
appveyor.yml
23
appveyor.yml
@@ -170,25 +170,22 @@ build_script:
|
||||
- python %LOCAL_GOMA_DIR%\goma_ctl.py stat
|
||||
- python3 electron/build/profile_toolchain.py --output-json=out/Default/windows_toolchain_profile.json
|
||||
- 7z a node_headers.zip out\Default\gen\node_headers
|
||||
# Temporarily disable symbol generation on 32-bit Windows due to failures
|
||||
- ps: >-
|
||||
if ($env:GN_CONFIG -eq 'release' -And $env:TARGET_ARCH -ne 'ia32') {
|
||||
if ($env:GN_CONFIG -eq 'release') {
|
||||
# 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
|
||||
}
|
||||
- ps: >-
|
||||
if ($env:GN_CONFIG -eq 'release') {
|
||||
if ($env:TARGET_ARCH -ne 'ia32') {
|
||||
python electron\script\zip-symbols.py
|
||||
appveyor-retry appveyor PushArtifact out/Default/symbols.zip
|
||||
}
|
||||
python3 electron\script\zip-symbols.py
|
||||
appveyor-retry appveyor PushArtifact out/Default/symbols.zip
|
||||
} else {
|
||||
# It's useful to have pdb files when debugging testing builds that are
|
||||
# built on CI.
|
||||
7z a pdb.zip out\Default\*.pdb
|
||||
}
|
||||
- python electron/script/zip_manifests/check-zip-manifest.py out/Default/dist.zip electron/script/zip_manifests/dist_zip.win.%TARGET_ARCH%.manifest
|
||||
- python3 electron/script/zip_manifests/check-zip-manifest.py out/Default/dist.zip electron/script/zip_manifests/dist_zip.win.%TARGET_ARCH%.manifest
|
||||
test_script:
|
||||
# Workaround for https://github.com/appveyor/ci/issues/2420
|
||||
- set "PATH=%PATH%;C:\Program Files\Git\mingw64\libexec\git-core"
|
||||
@@ -209,11 +206,11 @@ test_script:
|
||||
- if "%RUN_TESTS%"=="true" ( echo Running remote test suite & node script/yarn test -- --trace-uncaught --runners=remote --runTestFilesSeperately --enable-logging=file --log-file=%cd%\electron.log --disable-features=CalculateNativeWinOcclusion )
|
||||
- if "%RUN_TESTS%"=="true" ( echo Running native test suite & node script/yarn test -- --trace-uncaught --runners=native --enable-logging=file --log-file=%cd%\electron.log --disable-features=CalculateNativeWinOcclusion )
|
||||
- cd ..
|
||||
- if "%RUN_TESTS%"=="true" ( echo Verifying non proprietary ffmpeg & python electron\script\verify-ffmpeg.py --build-dir out\Default --source-root %cd% --ffmpeg-path out\ffmpeg )
|
||||
- if "%RUN_TESTS%"=="true" ( echo Verifying non proprietary ffmpeg & python3 electron\script\verify-ffmpeg.py --build-dir out\Default --source-root %cd% --ffmpeg-path out\ffmpeg )
|
||||
- echo "About to verify mksnapshot"
|
||||
- if "%RUN_TESTS%"=="true" ( echo Verifying mksnapshot & python electron\script\verify-mksnapshot.py --build-dir out\Default --source-root %cd% )
|
||||
- if "%RUN_TESTS%"=="true" ( echo Verifying mksnapshot & python3 electron\script\verify-mksnapshot.py --build-dir out\Default --source-root %cd% )
|
||||
- echo "Done verifying mksnapshot"
|
||||
- if "%RUN_TESTS%"=="true" ( echo Verifying chromedriver & python electron\script\verify-chromedriver.py --build-dir out\Default --source-root %cd% )
|
||||
- if "%RUN_TESTS%"=="true" ( echo Verifying chromedriver & python3 electron\script\verify-chromedriver.py --build-dir out\Default --source-root %cd% )
|
||||
- echo "Done verifying chromedriver"
|
||||
deploy_script:
|
||||
- cd electron
|
||||
@@ -221,13 +218,13 @@ deploy_script:
|
||||
if (Test-Path Env:\ELECTRON_RELEASE) {
|
||||
if (Test-Path Env:\UPLOAD_TO_STORAGE) {
|
||||
Write-Output "Uploading Electron release distribution to azure"
|
||||
& python script\release\uploaders\upload.py --verbose --upload_to_storage
|
||||
& python3 script\release\uploaders\upload.py --verbose --upload_to_storage
|
||||
} else {
|
||||
Write-Output "Uploading Electron release distribution to github releases"
|
||||
& python script\release\uploaders\upload.py --verbose
|
||||
& python3 script\release\uploaders\upload.py --verbose
|
||||
}
|
||||
} elseif (Test-Path Env:\TEST_WOA) {
|
||||
node script/release/ci-release-build.js --job=electron-woa-testing --ci=VSTS --armTest --appveyorJobId=$env:APPVEYOR_JOB_ID $env:APPVEYOR_REPO_BRANCH
|
||||
node script/release/ci-release-build.js --job=electron-woa-testing --ci=GHA --appveyorJobId=$env:APPVEYOR_JOB_ID $env:APPVEYOR_REPO_BRANCH
|
||||
}
|
||||
on_finish:
|
||||
# Uncomment this lines to enable RDP
|
||||
|
||||
@@ -1,121 +0,0 @@
|
||||
steps:
|
||||
- task: CopyFiles@2
|
||||
displayName: 'Copy Files to: src/electron'
|
||||
inputs:
|
||||
TargetFolder: src/electron
|
||||
|
||||
- bash: |
|
||||
cd src/electron
|
||||
node script/yarn.js install --frozen-lockfile
|
||||
displayName: 'Yarn install'
|
||||
|
||||
- bash: |
|
||||
export ZIP_DEST=$PWD/src/out/Default
|
||||
echo "##vso[task.setvariable variable=ZIP_DEST]$ZIP_DEST"
|
||||
mkdir -p $ZIP_DEST
|
||||
cd src/electron
|
||||
node script/download-circleci-artifacts.js --buildNum=$CIRCLE_BUILD_NUM --name=dist.zip --dest=$ZIP_DEST
|
||||
cd $ZIP_DEST
|
||||
unzip -o dist.zip
|
||||
xattr -cr Electron.app
|
||||
displayName: 'Download and unzip dist files for test'
|
||||
env:
|
||||
CIRCLE_TOKEN: $(CIRCLECI_TOKEN)
|
||||
|
||||
- bash: |
|
||||
export FFMPEG_ZIP_DEST=$PWD/src/out/ffmpeg
|
||||
mkdir -p $FFMPEG_ZIP_DEST
|
||||
cd src/electron
|
||||
node script/download-circleci-artifacts.js --buildNum=$CIRCLE_BUILD_NUM --name=ffmpeg.zip --dest=$FFMPEG_ZIP_DEST
|
||||
cd $FFMPEG_ZIP_DEST
|
||||
unzip -o ffmpeg.zip
|
||||
displayName: 'Download and unzip ffmpeg for test'
|
||||
env:
|
||||
CIRCLE_TOKEN: $(CIRCLECI_TOKEN)
|
||||
|
||||
- bash: |
|
||||
export NODE_HEADERS_DEST=$PWD/src/out/Default/gen
|
||||
mkdir -p $NODE_HEADERS_DEST
|
||||
cd src/electron
|
||||
node script/download-circleci-artifacts.js --buildNum=$CIRCLE_BUILD_NUM --name=node_headers.tar.gz --dest=$NODE_HEADERS_DEST
|
||||
cd $NODE_HEADERS_DEST
|
||||
tar xzf node_headers.tar.gz
|
||||
displayName: 'Download and untar node header files for test'
|
||||
env:
|
||||
CIRCLE_TOKEN: $(CIRCLECI_TOKEN)
|
||||
|
||||
- bash: |
|
||||
export CROSS_ARCH_SNAPSHOTS=$PWD/src/out/Default/cross-arch-snapshots
|
||||
mkdir -p $CROSS_ARCH_SNAPSHOTS
|
||||
cd src/electron
|
||||
node script/download-circleci-artifacts.js --buildNum=$CIRCLE_BUILD_NUM --name=cross-arch-snapshots/snapshot_blob.bin --dest=$CROSS_ARCH_SNAPSHOTS
|
||||
node script/download-circleci-artifacts.js --buildNum=$CIRCLE_BUILD_NUM --name=cross-arch-snapshots/v8_context_snapshot.arm64.bin --dest=$CROSS_ARCH_SNAPSHOTS
|
||||
displayName: 'Download cross arch snapshot files'
|
||||
env:
|
||||
CIRCLE_TOKEN: $(CIRCLECI_TOKEN)
|
||||
|
||||
- bash: |
|
||||
cd src
|
||||
export ELECTRON_OUT_DIR=Default
|
||||
export npm_config_arch=arm64
|
||||
(cd electron && node script/yarn test --enable-logging --runners main)
|
||||
displayName: 'Run Electron main tests'
|
||||
timeoutInMinutes: 20
|
||||
env:
|
||||
ELECTRON_DISABLE_SECURITY_WARNINGS: 1
|
||||
IGNORE_YARN_INSTALL_ERROR: 1
|
||||
ELECTRON_TEST_RESULTS_DIR: junit
|
||||
|
||||
- bash: |
|
||||
cd src
|
||||
export ELECTRON_OUT_DIR=Default
|
||||
export npm_config_arch=arm64
|
||||
(cd electron && node script/yarn test --enable-logging --runners remote)
|
||||
displayName: 'Run Electron remote tests'
|
||||
timeoutInMinutes: 20
|
||||
condition: succeededOrFailed()
|
||||
env:
|
||||
ELECTRON_DISABLE_SECURITY_WARNINGS: 1
|
||||
IGNORE_YARN_INSTALL_ERROR: 1
|
||||
ELECTRON_TEST_RESULTS_DIR: junit
|
||||
|
||||
- bash: |
|
||||
cd src
|
||||
python electron/script/verify-ffmpeg.py --source-root "$PWD" --build-dir out/Default --ffmpeg-path out/ffmpeg
|
||||
displayName: Verify non proprietary ffmpeg
|
||||
timeoutInMinutes: 5
|
||||
condition: succeededOrFailed()
|
||||
env:
|
||||
TARGET_ARCH: arm64
|
||||
|
||||
- bash: |
|
||||
cd src
|
||||
echo Verify cross arch snapshot
|
||||
python electron/script/verify-mksnapshot.py --source-root "$PWD" --build-dir out/Default --snapshot-files-dir $PWD/out/Default/cross-arch-snapshots
|
||||
displayName: Verify cross arch snapshot
|
||||
timeoutInMinutes: 5
|
||||
condition: succeededOrFailed()
|
||||
|
||||
- task: PublishTestResults@2
|
||||
displayName: 'Publish Test Results'
|
||||
inputs:
|
||||
testResultsFiles: '*.xml'
|
||||
|
||||
searchFolder: '$(System.DefaultWorkingDirectory)/src/junit/'
|
||||
|
||||
condition: succeededOrFailed()
|
||||
|
||||
- bash: killall Electron || echo "No Electron processes left running"
|
||||
displayName: 'Kill processes left running from last test run'
|
||||
condition: always()
|
||||
|
||||
- bash: |
|
||||
rm -rf ~/Library/Application\ Support/Electron*
|
||||
rm -rf ~/Library/Application\ Support/electron*
|
||||
displayName: 'Delete user app data directories'
|
||||
condition: always()
|
||||
|
||||
- task: mspremier.PostBuildCleanup.PostBuildCleanup-task.PostBuildCleanup@3
|
||||
displayName: 'Clean Agent Directories'
|
||||
|
||||
condition: always()
|
||||
@@ -1,130 +0,0 @@
|
||||
workspace:
|
||||
clean: all
|
||||
|
||||
steps:
|
||||
- checkout: self
|
||||
path: src\electron
|
||||
|
||||
- script: |
|
||||
node script/yarn.js install --frozen-lockfile
|
||||
displayName: 'Yarn install'
|
||||
|
||||
- powershell: |
|
||||
$localArtifactPath = "$pwd\dist.zip"
|
||||
$serverArtifactPath = "$env:APPVEYOR_URL/buildjobs/$env:APPVEYOR_JOB_ID/artifacts/dist.zip"
|
||||
Invoke-RestMethod -Method Get -Uri $serverArtifactPath -OutFile $localArtifactPath -Headers @{ "Authorization" = "Bearer $env:APPVEYOR_TOKEN" }
|
||||
& "${env:ProgramFiles(x86)}\7-Zip\7z.exe" x -o$(Pipeline.Workspace)\src\out\Default -y $localArtifactPath
|
||||
displayName: 'Download and extract dist.zip for test'
|
||||
env:
|
||||
APPVEYOR_TOKEN: $(APPVEYOR_TOKEN)
|
||||
|
||||
- powershell: |
|
||||
$localArtifactPath = "$(Pipeline.Workspace)\src\out\Default\shell_browser_ui_unittests.exe"
|
||||
$serverArtifactPath = "$env:APPVEYOR_URL/buildjobs/$env:APPVEYOR_JOB_ID/artifacts/shell_browser_ui_unittests.exe"
|
||||
Invoke-RestMethod -Method Get -Uri $serverArtifactPath -OutFile $localArtifactPath -Headers @{ "Authorization" = "Bearer $env:APPVEYOR_TOKEN" }
|
||||
displayName: 'Download and extract native test executables for test'
|
||||
env:
|
||||
APPVEYOR_TOKEN: $(APPVEYOR_TOKEN)
|
||||
|
||||
- powershell: |
|
||||
$localArtifactPath = "$pwd\ffmpeg.zip"
|
||||
$serverArtifactPath = "$env:APPVEYOR_URL/buildjobs/$env:APPVEYOR_JOB_ID/artifacts/ffmpeg.zip"
|
||||
Invoke-RestMethod -Method Get -Uri $serverArtifactPath -OutFile $localArtifactPath -Headers @{ "Authorization" = "Bearer $env:APPVEYOR_TOKEN" }
|
||||
& "${env:ProgramFiles(x86)}\7-Zip\7z.exe" x -o$(Pipeline.Workspace)\src\out\ffmpeg $localArtifactPath
|
||||
displayName: 'Download and extract ffmpeg.zip for test'
|
||||
env:
|
||||
APPVEYOR_TOKEN: $(APPVEYOR_TOKEN)
|
||||
|
||||
- powershell: |
|
||||
$localArtifactPath = "$(Pipeline.Workspace)\src\node_headers.zip"
|
||||
$serverArtifactPath = "$env:APPVEYOR_URL/buildjobs/$env:APPVEYOR_JOB_ID/artifacts/node_headers.zip"
|
||||
Invoke-RestMethod -Method Get -Uri $serverArtifactPath -OutFile $localArtifactPath -Headers @{ "Authorization" = "Bearer $env:APPVEYOR_TOKEN" }
|
||||
cd $(Pipeline.Workspace)\src
|
||||
& "${env:ProgramFiles(x86)}\7-Zip\7z.exe" x -y node_headers.zip
|
||||
displayName: 'Download node headers for test'
|
||||
env:
|
||||
APPVEYOR_TOKEN: $(APPVEYOR_TOKEN)
|
||||
|
||||
- powershell: |
|
||||
$localArtifactPath = "$(Pipeline.Workspace)\src\out\Default\electron.lib"
|
||||
$serverArtifactPath = "$env:APPVEYOR_URL/buildjobs/$env:APPVEYOR_JOB_ID/artifacts/electron.lib"
|
||||
Invoke-RestMethod -Method Get -Uri $serverArtifactPath -OutFile $localArtifactPath -Headers @{ "Authorization" = "Bearer $env:APPVEYOR_TOKEN" }
|
||||
displayName: 'Download electron.lib for test'
|
||||
env:
|
||||
APPVEYOR_TOKEN: $(APPVEYOR_TOKEN)
|
||||
|
||||
# Uncomment the following block if pdb files are needed to debug issues
|
||||
# - powershell: |
|
||||
# try {
|
||||
# $localArtifactPath = "$(Pipeline.Workspace)\src\pdb.zip"
|
||||
# $serverArtifactPath = "$env:APPVEYOR_URL/buildjobs/$env:APPVEYOR_JOB_ID/artifacts/pdb.zip"
|
||||
# Invoke-RestMethod -Method Get -Uri $serverArtifactPath -OutFile $localArtifactPath -Headers @{ "Authorization" = "Bearer $env:APPVEYOR_TOKEN" }
|
||||
# cd $(Pipeline.Workspace)\src
|
||||
# & "${env:ProgramFiles(x86)}\7-Zip\7z.exe" x -y pdb.zip
|
||||
# } catch {
|
||||
# Write-Host "There was an exception encountered while downloading pdb files:" $_.Exception.Message
|
||||
# } finally {
|
||||
# $global:LASTEXITCODE = 0
|
||||
# }
|
||||
# displayName: 'Download pdb files for detailed stacktraces'
|
||||
# env:
|
||||
# APPVEYOR_TOKEN: $(APPVEYOR_TOKEN)
|
||||
|
||||
- powershell: |
|
||||
New-Item $(Pipeline.Workspace)\src\out\Default\gen\node_headers\Release -Type directory
|
||||
Copy-Item -path $(Pipeline.Workspace)\src\out\Default\electron.lib -destination $(Pipeline.Workspace)\src\out\Default\gen\node_headers\Release\node.lib
|
||||
displayName: 'Setup node headers'
|
||||
|
||||
- script: |
|
||||
cd $(Pipeline.Workspace)\src
|
||||
set npm_config_nodedir=%cd%\out\Default\gen\node_headers
|
||||
set npm_config_arch=arm64
|
||||
cd electron
|
||||
node script/yarn test --runners=main --enable-logging --disable-features=CalculateNativeWinOcclusion
|
||||
displayName: 'Run Electron Main process tests'
|
||||
env:
|
||||
ELECTRON_ENABLE_STACK_DUMPING: true
|
||||
ELECTRON_OUT_DIR: Default
|
||||
IGNORE_YARN_INSTALL_ERROR: 1
|
||||
ELECTRON_TEST_RESULTS_DIR: junit
|
||||
MOCHA_MULTI_REPORTERS: 'mocha-junit-reporter, tap'
|
||||
MOCHA_REPORTER: mocha-multi-reporters
|
||||
|
||||
- script: |
|
||||
cd $(Pipeline.Workspace)\src
|
||||
set npm_config_nodedir=%cd%\out\Default\gen\node_headers
|
||||
set npm_config_arch=arm64
|
||||
cd electron
|
||||
node script/yarn test --runners=remote --enable-logging --disable-features=CalculateNativeWinOcclusion
|
||||
displayName: 'Run Electron Remote based tests'
|
||||
env:
|
||||
ELECTRON_OUT_DIR: Default
|
||||
IGNORE_YARN_INSTALL_ERROR: 1
|
||||
ELECTRON_TEST_RESULTS_DIR: junit
|
||||
MOCHA_MULTI_REPORTERS: 'mocha-junit-reporter, tap'
|
||||
MOCHA_REPORTER: mocha-multi-reporters
|
||||
condition: succeededOrFailed()
|
||||
|
||||
- task: PublishTestResults@2
|
||||
displayName: 'Publish Test Results'
|
||||
inputs:
|
||||
testResultsFiles: '*.xml'
|
||||
searchFolder: '$(Pipeline.Workspace)/src/junit/'
|
||||
condition: always()
|
||||
|
||||
- script: |
|
||||
cd $(Pipeline.Workspace)\src
|
||||
echo "Verifying non proprietary ffmpeg"
|
||||
python electron\script\verify-ffmpeg.py --build-dir out\Default --source-root %cd% --ffmpeg-path out\ffmpeg
|
||||
displayName: 'Verify ffmpeg'
|
||||
|
||||
- powershell: |
|
||||
Get-Process | Where Name –Like "electron*" | Stop-Process
|
||||
Get-Process | Where Name –Like "msedge*" | Stop-Process
|
||||
displayName: 'Kill processes left running from last test run'
|
||||
condition: always()
|
||||
|
||||
- powershell: |
|
||||
Remove-Item -path $env:APPDATA/Electron* -Recurse -Force -ErrorAction Ignore
|
||||
displayName: 'Delete user app data directories'
|
||||
condition: always()
|
||||
@@ -24,7 +24,11 @@ template("extract_symbols") {
|
||||
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)"
|
||||
if (host_os == "win" && target_cpu == "x86") {
|
||||
dump_syms_label = "//third_party/breakpad:dump_syms(//build/toolchain/win:win_clang_x64)"
|
||||
} else {
|
||||
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"
|
||||
|
||||
|
||||
@@ -7,5 +7,6 @@
|
||||
"node_options": "1",
|
||||
"node_cli_inspect": "1",
|
||||
"embedded_asar_integrity_validation": "0",
|
||||
"only_load_app_from_asar": "0"
|
||||
"only_load_app_from_asar": "0",
|
||||
"load_browser_process_specific_v8_snapshot": "0"
|
||||
}
|
||||
|
||||
@@ -50,8 +50,8 @@ END
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 20,0,0,10
|
||||
PRODUCTVERSION 20,0,0,10
|
||||
FILEVERSION $major,$minor,$patch,$prerelease_number
|
||||
PRODUCTVERSION $major,$minor,$patch,$prerelease_number
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@@ -68,12 +68,12 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "CompanyName", "GitHub, Inc."
|
||||
VALUE "FileDescription", "Electron"
|
||||
VALUE "FileVersion", "20.0.0"
|
||||
VALUE "FileVersion", "$major.$minor.$patch"
|
||||
VALUE "InternalName", "electron.exe"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved."
|
||||
VALUE "OriginalFilename", "electron.exe"
|
||||
VALUE "ProductName", "Electron"
|
||||
VALUE "ProductVersion", "20.0.0"
|
||||
VALUE "ProductVersion", "$major.$minor.$patch"
|
||||
VALUE "SquirrelAwareVersion", "1"
|
||||
END
|
||||
END
|
||||
1
build/templates/version_string.tmpl
Normal file
1
build/templates/version_string.tmpl
Normal file
@@ -0,0 +1 @@
|
||||
$full_version
|
||||
@@ -6,6 +6,7 @@ import("//build/config/ozone.gni")
|
||||
import("//build/config/ui.gni")
|
||||
import("//components/spellcheck/spellcheck_build_features.gni")
|
||||
import("//electron/buildflags/buildflags.gni")
|
||||
import("//ppapi/buildflags/buildflags.gni")
|
||||
import("//printing/buildflags/buildflags.gni")
|
||||
import("//third_party/widevine/cdm/widevine.gni")
|
||||
|
||||
@@ -55,6 +56,14 @@ static_library("chrome") {
|
||||
"//chrome/browser/process_singleton.h",
|
||||
"//chrome/browser/process_singleton_internal.cc",
|
||||
"//chrome/browser/process_singleton_internal.h",
|
||||
"//chrome/browser/themes/browser_theme_pack.cc",
|
||||
"//chrome/browser/themes/browser_theme_pack.h",
|
||||
"//chrome/browser/themes/custom_theme_supplier.cc",
|
||||
"//chrome/browser/themes/custom_theme_supplier.h",
|
||||
"//chrome/browser/themes/theme_properties.cc",
|
||||
"//chrome/browser/themes/theme_properties.h",
|
||||
"//chrome/browser/ui/color/chrome_color_mixers.cc",
|
||||
"//chrome/browser/ui/color/chrome_color_mixers.h",
|
||||
"//chrome/browser/ui/exclusive_access/exclusive_access_bubble_type.cc",
|
||||
"//chrome/browser/ui/exclusive_access/exclusive_access_bubble_type.h",
|
||||
"//chrome/browser/ui/exclusive_access/exclusive_access_controller_base.cc",
|
||||
@@ -69,7 +78,11 @@ static_library("chrome") {
|
||||
"//chrome/browser/ui/exclusive_access/keyboard_lock_controller.h",
|
||||
"//chrome/browser/ui/exclusive_access/mouse_lock_controller.cc",
|
||||
"//chrome/browser/ui/exclusive_access/mouse_lock_controller.h",
|
||||
"//chrome/browser/ui/frame/window_frame_util.cc",
|
||||
"//chrome/browser/ui/frame/window_frame_util.h",
|
||||
"//chrome/browser/ui/native_window_tracker.h",
|
||||
"//chrome/browser/ui/ui_features.cc",
|
||||
"//chrome/browser/ui/ui_features.h",
|
||||
"//chrome/browser/ui/views/eye_dropper/eye_dropper.cc",
|
||||
"//chrome/browser/ui/views/eye_dropper/eye_dropper.h",
|
||||
"//chrome/browser/ui/views/eye_dropper/eye_dropper_view.cc",
|
||||
@@ -109,6 +122,8 @@ static_library("chrome") {
|
||||
"//chrome/browser/ui/view_ids.h",
|
||||
"//chrome/browser/win/chrome_process_finder.cc",
|
||||
"//chrome/browser/win/chrome_process_finder.h",
|
||||
"//chrome/browser/win/titlebar_config.cc",
|
||||
"//chrome/browser/win/titlebar_config.h",
|
||||
"//chrome/browser/win/titlebar_config.h",
|
||||
"//chrome/child/v8_crashpad_support_win.cc",
|
||||
"//chrome/child/v8_crashpad_support_win.h",
|
||||
@@ -130,6 +145,7 @@ static_library("chrome") {
|
||||
|
||||
public_deps = [
|
||||
"//chrome/browser:dev_ui_browser_resources",
|
||||
"//chrome/browser/ui/color:mixers",
|
||||
"//chrome/common",
|
||||
"//chrome/common:version_header",
|
||||
"//components/keyed_service/content",
|
||||
@@ -355,15 +371,20 @@ source_set("plugins") {
|
||||
deps += [
|
||||
"//components/strings",
|
||||
"//media:media_buildflags",
|
||||
"//ppapi/buildflags",
|
||||
"//ppapi/host",
|
||||
"//ppapi/proxy",
|
||||
"//ppapi/proxy:ipc",
|
||||
"//ppapi/shared_impl",
|
||||
"//services/device/public/mojom",
|
||||
"//skia",
|
||||
"//storage/browser",
|
||||
]
|
||||
|
||||
if (enable_plugins) {
|
||||
deps += [
|
||||
"//ppapi/buildflags",
|
||||
"//ppapi/host",
|
||||
"//ppapi/proxy",
|
||||
"//ppapi/proxy:ipc",
|
||||
"//ppapi/shared_impl",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
# This source set is just so we don't have to depend on all of //chrome/browser
|
||||
|
||||
@@ -83,7 +83,7 @@ function loadApplicationPackage (packagePath: string) {
|
||||
});
|
||||
|
||||
try {
|
||||
// Override app name and version.
|
||||
// Override app's package.json data.
|
||||
packagePath = path.resolve(packagePath);
|
||||
const packageJsonPath = path.join(packagePath, 'package.json');
|
||||
let appPath;
|
||||
@@ -104,6 +104,16 @@ function loadApplicationPackage (packagePath: string) {
|
||||
} else if (packageJson.name) {
|
||||
app.name = packageJson.name;
|
||||
}
|
||||
if (packageJson.desktopName) {
|
||||
app.setDesktopName(packageJson.desktopName);
|
||||
} else {
|
||||
app.setDesktopName(`${app.name}.desktop`);
|
||||
}
|
||||
// Set v8 flags, deliberately lazy load so that apps that do not use this
|
||||
// feature do not pay the price
|
||||
if (packageJson.v8Flags) {
|
||||
require('v8').setFlagsFromString(packageJson.v8Flags);
|
||||
}
|
||||
appPath = packagePath;
|
||||
}
|
||||
|
||||
|
||||
@@ -68,6 +68,7 @@ an issue:
|
||||
* [Mac App Store](tutorial/mac-app-store-submission-guide.md)
|
||||
* [Windows Store](tutorial/windows-store-guide.md)
|
||||
* [Snapcraft](tutorial/snapcraft.md)
|
||||
* [ASAR Archives](tutorial/asar-archives.md)
|
||||
* [Updates](tutorial/updates.md)
|
||||
* [Getting Support](tutorial/support.md)
|
||||
|
||||
@@ -82,7 +83,6 @@ These individual tutorials expand on topics discussed in the guide above.
|
||||
* Electron Releases & Developer Feedback
|
||||
* [Versioning Policy](tutorial/electron-versioning.md)
|
||||
* [Release Timelines](tutorial/electron-timelines.md)
|
||||
* [Testing Widevine CDM](tutorial/testing-widevine-cdm.md)
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -246,7 +246,8 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
|
||||
* `trafficLightPosition` [Point](structures/point.md) (optional) _macOS_ -
|
||||
Set a custom position for the traffic light buttons in frameless windows.
|
||||
* `roundedCorners` boolean (optional) _macOS_ - Whether frameless window
|
||||
should have rounded corners on macOS. Default is `true`.
|
||||
should have rounded corners on macOS. Default is `true`. Setting this property
|
||||
to `false` will prevent the window from being fullscreenable.
|
||||
* `fullscreenWindowTitle` boolean (optional) _macOS_ _Deprecated_ - Shows
|
||||
the title in the title bar in full screen mode on macOS for `hiddenInset`
|
||||
titleBarStyle. Default is `false`.
|
||||
@@ -1323,7 +1324,7 @@ win.setSheetOffset(toolbarRect.height)
|
||||
|
||||
Starts or stops flashing the window to attract user's attention.
|
||||
|
||||
#### `win.setSkipTaskbar(skip)`
|
||||
#### `win.setSkipTaskbar(skip)` _macOS_ _Windows_
|
||||
|
||||
* `skip` boolean
|
||||
|
||||
|
||||
@@ -96,14 +96,6 @@ Algorithm][SCA], just like [`window.postMessage`][], so prototype chains will no
|
||||
included. Sending Functions, Promises, Symbols, WeakMaps, or WeakSets will
|
||||
throw an exception.
|
||||
|
||||
> **NOTE:** Sending non-standard JavaScript types such as DOM objects or
|
||||
> special Electron objects will throw an exception.
|
||||
>
|
||||
> Since the main process does not have support for DOM objects such as
|
||||
> `ImageBitmap`, `File`, `DOMMatrix` and so on, such objects cannot be sent over
|
||||
> Electron's IPC to the main process, as the main process would have no way to decode
|
||||
> them. Attempting to send such objects over IPC will result in an error.
|
||||
|
||||
The main process should listen for `channel` with
|
||||
[`ipcMain.handle()`](./ipc-main.md#ipcmainhandlechannel-listener).
|
||||
|
||||
@@ -126,6 +118,21 @@ If you need to transfer a [`MessagePort`][] to the main process, use [`ipcRender
|
||||
|
||||
If you do not need a response to the message, consider using [`ipcRenderer.send`](#ipcrenderersendchannel-args).
|
||||
|
||||
> **Note**
|
||||
> Sending non-standard JavaScript types such as DOM objects or
|
||||
> special Electron objects will throw an exception.
|
||||
>
|
||||
> Since the main process does not have support for DOM objects such as
|
||||
> `ImageBitmap`, `File`, `DOMMatrix` and so on, such objects cannot be sent over
|
||||
> Electron's IPC to the main process, as the main process would have no way to decode
|
||||
> them. Attempting to send such objects over IPC will result in an error.
|
||||
|
||||
> **Note**
|
||||
> If the handler in the main process throws an error,
|
||||
> the promise returned by `invoke` will reject.
|
||||
> However, the `Error` object in the renderer process
|
||||
> will not be the same as the one thrown in the main process.
|
||||
|
||||
### `ipcRenderer.sendSync(channel, ...args)`
|
||||
|
||||
* `channel` string
|
||||
|
||||
@@ -10,11 +10,12 @@ An example of implementing a protocol that has the same effect as the
|
||||
```javascript
|
||||
const { app, protocol } = require('electron')
|
||||
const path = require('path')
|
||||
const url = require('url')
|
||||
|
||||
app.whenReady().then(() => {
|
||||
protocol.registerFileProtocol('atom', (request, callback) => {
|
||||
const url = request.url.substr(7)
|
||||
callback({ path: path.normalize(`${__dirname}/${url}`) })
|
||||
const filePath = url.fileURLToPath('file://' + request.url.slice('atom://'.length))
|
||||
callback(filePath)
|
||||
})
|
||||
})
|
||||
```
|
||||
@@ -175,7 +176,7 @@ property.
|
||||
* `handler` Function
|
||||
* `request` [ProtocolRequest](structures/protocol-request.md)
|
||||
* `callback` Function
|
||||
* `response` ProtocolResponse
|
||||
* `response` [ProtocolResponse](structures/protocol-response.md)
|
||||
|
||||
Returns `boolean` - Whether the protocol was successfully registered
|
||||
|
||||
|
||||
@@ -635,7 +635,7 @@ win.webContents.session.setCertificateVerifyProc((request, callback) => {
|
||||
* `notifications` - Request notification creation and the ability to display them in the user's system tray.
|
||||
* `midi` - Request MIDI access in the `webmidi` API.
|
||||
* `midiSysex` - Request the use of system exclusive messages in the `webmidi` API.
|
||||
* `pointerLock` - Request to directly interpret mouse movements as an input method. Click [here](https://developer.mozilla.org/en-US/docs/Web/API/Pointer_Lock_API) to know more.
|
||||
* `pointerLock` - Request to directly interpret mouse movements as an input method. Click [here](https://developer.mozilla.org/en-US/docs/Web/API/Pointer_Lock_API) to know more. These requests always appear to originate from the main frame.
|
||||
* `fullscreen` - Request for the app to enter fullscreen mode.
|
||||
* `openExternal` - Request to open links in external applications.
|
||||
* `unknown` - An unrecognized permission request
|
||||
@@ -1049,7 +1049,7 @@ is emitted.
|
||||
|
||||
#### `ses.getStoragePath()`
|
||||
|
||||
A `string | null` indicating the absolute file system path where data for this
|
||||
Returns `string | null` - The absolute file system path where data for this
|
||||
session is persisted on disk. For in memory sessions this returns `null`.
|
||||
|
||||
### Instance Properties
|
||||
|
||||
@@ -25,15 +25,20 @@ app.whenReady().then(() => {
|
||||
})
|
||||
```
|
||||
|
||||
__Platform limitations:__
|
||||
__Platform Considerations__
|
||||
|
||||
If you want to keep exact same behaviors on all platforms, you should not
|
||||
rely on the `click` event; instead, always attach a context menu to the tray icon.
|
||||
|
||||
__Linux__
|
||||
|
||||
* On Linux the app indicator will be used if it is supported, otherwise
|
||||
`GtkStatusIcon` will be used instead.
|
||||
* On Linux distributions that only have app indicator support, you have to
|
||||
install `libappindicator1` to make the tray icon work.
|
||||
* The app indicator will be used if it is supported, otherwise
|
||||
`GtkStatusIcon` will be used instead.
|
||||
* App indicator will only be shown when it has a context menu.
|
||||
* When app indicator is used on Linux, the `click` event is ignored.
|
||||
* On Linux in order for changes made to individual `MenuItem`s to take effect,
|
||||
* The `click` event is ignored when using the app indicator.
|
||||
* In order for changes made to individual `MenuItem`s to take effect,
|
||||
you have to call `setContextMenu` again. For example:
|
||||
|
||||
```javascript
|
||||
@@ -55,10 +60,16 @@ app.whenReady().then(() => {
|
||||
})
|
||||
```
|
||||
|
||||
* On Windows it is recommended to use `ICO` icons to get best visual effects.
|
||||
__MacOS__
|
||||
|
||||
If you want to keep exact same behaviors on all platforms, you should not
|
||||
rely on the `click` event and always attach a context menu to the tray icon.
|
||||
* Icons passed to the Tray constructor should be [Template Images](native-image.md#template-image).
|
||||
* To make sure your icon isn't grainy on retina monitors, be sure your `@2x` image is 144dpi.
|
||||
* If you are bundling your application (e.g., with webpack for development), be sure that the file names are not being mangled or hashed. The filename needs to end in Template, and the `@2x` image needs to have the same filename as the standard image, or MacOS will not magically invert your image's colors or use the high density image.
|
||||
* 16x16 (72dpi) and 32x32@2x (144dpi) work well for most icons.
|
||||
|
||||
__Windows__
|
||||
|
||||
* It is recommended to use `ICO` icons to get best visual effects.
|
||||
|
||||
### `new Tray(image, [guid])`
|
||||
|
||||
|
||||
@@ -1635,6 +1635,8 @@ Opens the devtools.
|
||||
When `contents` is a `<webview>` tag, the `mode` would be `detach` by default,
|
||||
explicitly passing an empty `mode` can force using last used dock state.
|
||||
|
||||
On Windows, if Windows Control Overlay is enabled, Devtools will be opened with `mode: 'detach'`.
|
||||
|
||||
#### `contents.closeDevTools()`
|
||||
|
||||
Closes the devtools.
|
||||
|
||||
@@ -144,6 +144,16 @@ ipcRenderer.on('port', (e, msg) => {
|
||||
|
||||
A `string` representing the current URL of the frame.
|
||||
|
||||
#### `frame.origin` _Readonly_
|
||||
|
||||
A `string` representing the current origin of the frame, serialized according
|
||||
to [RFC 6454](https://www.rfc-editor.org/rfc/rfc6454). This may be different
|
||||
from the URL. For instance, if the frame is a child window opened to
|
||||
`about:blank`, then `frame.origin` will return the parent frame's origin, while
|
||||
`frame.url` will return the empty string. Pages without a scheme/host/port
|
||||
triple origin will have the serialized origin of `"null"` (that is, the string
|
||||
containing the letters n, u, l, l).
|
||||
|
||||
#### `frame.top` _Readonly_
|
||||
|
||||
A `WebFrameMain | null` representing top frame in the frame hierarchy to which `frame`
|
||||
|
||||
@@ -135,7 +135,7 @@ is only available in renderer processes.
|
||||
|
||||
If [sub-pixel anti-aliasing](https://alienryderflex.com/sub_pixel/) is deactivated, then fonts on LCD screens can look blurry. Example:
|
||||
|
||||
![subpixel rendering example]
|
||||

|
||||
|
||||
Sub-pixel anti-aliasing needs a non-transparent background of the layer containing the font glyphs. (See [this issue](https://github.com/electron/electron/issues/6344#issuecomment-420371918) for more info).
|
||||
|
||||
@@ -161,4 +161,3 @@ Notice that just setting the background in the CSS does not have the desired eff
|
||||
[indexed-db]: https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API
|
||||
[message-port]: https://developer.mozilla.org/en-US/docs/Web/API/MessagePort
|
||||
[browser-window]: api/browser-window.md
|
||||
[subpixel rendering example]: images/subpixel-rendering-screenshot.gif
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
const { contextBridge, ipcRenderer } = require('electron')
|
||||
const path = require('path')
|
||||
|
||||
contextBridge.exposeInMainWorld('electron', {
|
||||
startDrag: (fileName) => {
|
||||
|
||||
@@ -33,12 +33,16 @@ function createWindow () {
|
||||
if (permission === 'serial' && details.securityOrigin === 'file:///') {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
})
|
||||
|
||||
mainWindow.webContents.session.setDevicePermissionHandler((details) => {
|
||||
if (details.deviceType === 'serial' && details.origin === 'file://') {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
})
|
||||
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
@@ -11,8 +11,8 @@ can either use specialized tooling or manual approaches.
|
||||
## With tooling
|
||||
|
||||
There are a couple tools out there that exist to package and distribute your Electron app.
|
||||
We recommend using [Electron Forge](https://www.electronforge.io). You can check out
|
||||
its documentation directly, or refer to the [Packaging and Distribution](./tutorial-5-packaging.md)
|
||||
We recommend using [Electron Forge](./forge-overview.md). You can check out
|
||||
its [documentation](https://www.electronforge.io) directly, or refer to the [Packaging and Distribution](./tutorial-5-packaging.md)
|
||||
part of the Electron tutorial.
|
||||
|
||||
## Manual packaging
|
||||
|
||||
175
docs/tutorial/asar-archives.md
Normal file
175
docs/tutorial/asar-archives.md
Normal file
@@ -0,0 +1,175 @@
|
||||
---
|
||||
title: ASAR Archives
|
||||
description: What is ASAR archive and how does it affect the application.
|
||||
slug: asar-archives
|
||||
hide_title: false
|
||||
---
|
||||
|
||||
After creating an [application distribution](application-distribution.md), the
|
||||
app's source code are usually bundled into an [ASAR
|
||||
archive](https://github.com/electron/asar), which is a simple extensive archive
|
||||
format designed for Electron apps. By bundling the app we can mitigate issues
|
||||
around long path names on Windows, speed up `require` and conceal your source
|
||||
code from cursory inspection.
|
||||
|
||||
The bundled app runs in a virtual file system and most APIs would just work
|
||||
normally, but for some cases you might want to work on ASAR archives explicitly
|
||||
due to a few caveats.
|
||||
|
||||
## Using ASAR Archives
|
||||
|
||||
In Electron there are two sets of APIs: Node APIs provided by Node.js and Web
|
||||
APIs provided by Chromium. Both APIs support reading files from ASAR archives.
|
||||
|
||||
### Node API
|
||||
|
||||
With special patches in Electron, Node APIs like `fs.readFile` and `require`
|
||||
treat ASAR archives as virtual directories, and the files in it as normal
|
||||
files in the filesystem.
|
||||
|
||||
For example, suppose we have an `example.asar` archive under `/path/to`:
|
||||
|
||||
```sh
|
||||
$ asar list /path/to/example.asar
|
||||
/app.js
|
||||
/file.txt
|
||||
/dir/module.js
|
||||
/static/index.html
|
||||
/static/main.css
|
||||
/static/jquery.min.js
|
||||
```
|
||||
|
||||
Read a file in the ASAR archive:
|
||||
|
||||
```javascript
|
||||
const fs = require('fs')
|
||||
fs.readFileSync('/path/to/example.asar/file.txt')
|
||||
```
|
||||
|
||||
List all files under the root of the archive:
|
||||
|
||||
```javascript
|
||||
const fs = require('fs')
|
||||
fs.readdirSync('/path/to/example.asar')
|
||||
```
|
||||
|
||||
Use a module from the archive:
|
||||
|
||||
```javascript
|
||||
require('./path/to/example.asar/dir/module.js')
|
||||
```
|
||||
|
||||
You can also display a web page in an ASAR archive with `BrowserWindow`:
|
||||
|
||||
```javascript
|
||||
const { BrowserWindow } = require('electron')
|
||||
const win = new BrowserWindow()
|
||||
|
||||
win.loadURL('file:///path/to/example.asar/static/index.html')
|
||||
```
|
||||
|
||||
### Web API
|
||||
|
||||
In a web page, files in an archive can be requested with the `file:` protocol.
|
||||
Like the Node API, ASAR archives are treated as directories.
|
||||
|
||||
For example, to get a file with `$.get`:
|
||||
|
||||
```html
|
||||
<script>
|
||||
let $ = require('./jquery.min.js')
|
||||
$.get('file:///path/to/example.asar/file.txt', (data) => {
|
||||
console.log(data)
|
||||
})
|
||||
</script>
|
||||
```
|
||||
|
||||
### Treating an ASAR archive as a Normal File
|
||||
|
||||
For some cases like verifying the ASAR archive's checksum, we need to read the
|
||||
content of an ASAR archive as a file. For this purpose you can use the built-in
|
||||
`original-fs` module which provides original `fs` APIs without `asar` support:
|
||||
|
||||
```javascript
|
||||
const originalFs = require('original-fs')
|
||||
originalFs.readFileSync('/path/to/example.asar')
|
||||
```
|
||||
|
||||
You can also set `process.noAsar` to `true` to disable the support for `asar` in
|
||||
the `fs` module:
|
||||
|
||||
```javascript
|
||||
const fs = require('fs')
|
||||
process.noAsar = true
|
||||
fs.readFileSync('/path/to/example.asar')
|
||||
```
|
||||
|
||||
## Limitations of the Node API
|
||||
|
||||
Even though we tried hard to make ASAR archives in the Node API work like
|
||||
directories as much as possible, there are still limitations due to the
|
||||
low-level nature of the Node API.
|
||||
|
||||
### Archives Are Read-only
|
||||
|
||||
The archives can not be modified so all Node APIs that can modify files will not
|
||||
work with ASAR archives.
|
||||
|
||||
### Working Directory Can Not Be Set to Directories in Archive
|
||||
|
||||
Though ASAR archives are treated as directories, there are no actual
|
||||
directories in the filesystem, so you can never set the working directory to
|
||||
directories in ASAR archives. Passing them as the `cwd` option of some APIs
|
||||
will also cause errors.
|
||||
|
||||
### Extra Unpacking on Some APIs
|
||||
|
||||
Most `fs` APIs can read a file or get a file's information from ASAR archives
|
||||
without unpacking, but for some APIs that rely on passing the real file path to
|
||||
underlying system calls, Electron will extract the needed file into a
|
||||
temporary file and pass the path of the temporary file to the APIs to make them
|
||||
work. This adds a little overhead for those APIs.
|
||||
|
||||
APIs that requires extra unpacking are:
|
||||
|
||||
* `child_process.execFile`
|
||||
* `child_process.execFileSync`
|
||||
* `fs.open`
|
||||
* `fs.openSync`
|
||||
* `process.dlopen` - Used by `require` on native modules
|
||||
|
||||
### Fake Stat Information of `fs.stat`
|
||||
|
||||
The `Stats` object returned by `fs.stat` and its friends on files in `asar`
|
||||
archives is generated by guessing, because those files do not exist on the
|
||||
filesystem. So you should not trust the `Stats` object except for getting file
|
||||
size and checking file type.
|
||||
|
||||
### Executing Binaries Inside ASAR archive
|
||||
|
||||
There are Node APIs that can execute binaries like `child_process.exec`,
|
||||
`child_process.spawn` and `child_process.execFile`, but only `execFile` is
|
||||
supported to execute binaries inside ASAR archive.
|
||||
|
||||
This is because `exec` and `spawn` accept `command` instead of `file` as input,
|
||||
and `command`s are executed under shell. There is no reliable way to determine
|
||||
whether a command uses a file in asar archive, and even if we do, we can not be
|
||||
sure whether we can replace the path in command without side effects.
|
||||
|
||||
## Adding Unpacked Files to ASAR archives
|
||||
|
||||
As stated above, some Node APIs will unpack the file to the filesystem when
|
||||
called. Apart from the performance issues, various anti-virus scanners might
|
||||
be triggered by this behavior.
|
||||
|
||||
As a workaround, you can leave various files unpacked using the `--unpack` option.
|
||||
In the following example, shared libraries of native Node.js modules will not be
|
||||
packed:
|
||||
|
||||
```sh
|
||||
$ asar pack app app.asar --unpack *.node
|
||||
```
|
||||
|
||||
After running the command, you will notice that a folder named `app.asar.unpacked`
|
||||
was created together with the `app.asar` file. It contains the unpacked files
|
||||
and should be shipped together with the `app.asar` archive.
|
||||
53
docs/tutorial/asar-integrity.md
Normal file
53
docs/tutorial/asar-integrity.md
Normal file
@@ -0,0 +1,53 @@
|
||||
---
|
||||
title: 'ASAR Integrity'
|
||||
description: 'An experimental feature that ensures the validity of ASAR contents at runtime.'
|
||||
slug: asar-integrity
|
||||
hide_title: false
|
||||
---
|
||||
|
||||
## Platform Support
|
||||
|
||||
Currently ASAR integrity checking is only supported on macOS.
|
||||
|
||||
## Requirements
|
||||
|
||||
### Electron Forge / Electron Packager
|
||||
|
||||
If you are using `>= electron-packager@15.4.0` or `>= @electron-forge/core@6.0.0-beta.61` then all these requirements are met for you automatically and you can skip to [Toggling the Fuse](#toggling-the-fuse).
|
||||
|
||||
### Other build systems
|
||||
|
||||
In order to enable ASAR integrity checking you need to ensure that your `app.asar` file was generated by a version of the `asar` npm package that supports asar integrity. Support was introduced in version `3.1.0`.
|
||||
|
||||
Your must then populate a valid `ElectronAsarIntegrity` dictionary block in your packaged apps `Info.plist`. An example is included below.
|
||||
|
||||
```plist
|
||||
<key>ElectronAsarIntegrity</key>
|
||||
<dict>
|
||||
<key>Resources/app.asar</key>
|
||||
<dict>
|
||||
<key>algorithm</key>
|
||||
<string>SHA256</string>
|
||||
<key>hash</key>
|
||||
<string>9d1f61ea03c4bb62b4416387a521101b81151da0cfbe18c9f8c8b818c5cebfac</string>
|
||||
</dict>
|
||||
</dict>
|
||||
```
|
||||
|
||||
Valid `algorithm` values are currently `SHA256` only. The `hash` is a hash of the ASAR header using the given algorithm. The `asar` package exposes a `getRawHeader` method whose result can then be hashed to generate this value.
|
||||
|
||||
## Toggling the Fuse
|
||||
|
||||
ASAR integrity checking is currently disabled by default and can be enabled by toggling a fuse. See [Electron Fuses](fuses.md) for more information on what Electron Fuses are and how they work. When enabling this fuse you typically also want to enable the `onlyLoadAppFromAsar` fuse otherwise the validity checking can be bypassed via the Electron app code search path.
|
||||
|
||||
```js
|
||||
require('@electron/fuses').flipFuses(
|
||||
// E.g. /a/b/Foo.app
|
||||
pathToPackagedApp,
|
||||
{
|
||||
version: FuseVersion.V1,
|
||||
[FuseV1Options.EnableEmbeddedAsarIntegrityValidation]: true,
|
||||
[FuseV1Options.OnlyLoadAppFromAsar]: true
|
||||
}
|
||||
)
|
||||
```
|
||||
@@ -26,10 +26,8 @@ beginners, using a command line tool is likely to be helpful*.
|
||||
|
||||
## electron-forge
|
||||
|
||||
A "complete tool for building modern Electron applications". Electron Forge
|
||||
unifies the existing (and well maintained) build tools for Electron development
|
||||
into a cohesive package so that anyone can jump right in to Electron
|
||||
development.
|
||||
Electron Forge is a tool for packaging and publishing Electron applications. It unifies Electron's tooling ecosystem
|
||||
into a single extensible interface so that anyone can jump right into making Electron apps.
|
||||
|
||||
Forge comes with [a ready-to-use template](https://electronforge.io/templates) using Webpack as a bundler. It includes an example typescript configuration and provides two configuration files to enable easy customization. It uses the same core modules used by the
|
||||
greater Electron community (like [`electron-packager`](https://github.com/electron/electron-packager)) –
|
||||
|
||||
@@ -54,85 +54,11 @@ and notarized requires a few additions to your configuration. [Forge](https://el
|
||||
collection of the official Electron tools, using [`electron-packager`],
|
||||
[`electron-osx-sign`], and [`electron-notarize`] under the hood.
|
||||
|
||||
Let's take a look at an example `package.json` configuration with all required fields. Not all of them are
|
||||
required: the tools will be clever enough to automatically find a suitable `identity`, for instance,
|
||||
but we recommend that you are explicit.
|
||||
|
||||
```json title="package.json" {7}
|
||||
{
|
||||
"name": "my-app",
|
||||
"version": "0.0.1",
|
||||
"config": {
|
||||
"forge": {
|
||||
"packagerConfig": {
|
||||
"osxSign": {
|
||||
"identity": "Developer ID Application: Felix Rieseberg (LT94ZKYDCJ)",
|
||||
"hardened-runtime": true,
|
||||
"entitlements": "entitlements.plist",
|
||||
"entitlements-inherit": "entitlements.plist",
|
||||
"signature-flags": "library"
|
||||
},
|
||||
"osxNotarize": {
|
||||
"appleId": "felix@felix.fun",
|
||||
"appleIdPassword": "my-apple-id-password"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The `entitlements.plist` file referenced here needs the following macOS-specific entitlements
|
||||
to assure the Apple security mechanisms that your app is doing these things
|
||||
without meaning any harm:
|
||||
|
||||
```xml title="entitlements.plist"
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.security.cs.allow-jit</key>
|
||||
<true/>
|
||||
<key>com.apple.security.cs.debugger</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
```
|
||||
|
||||
Note that up until Electron 12, the `com.apple.security.cs.allow-unsigned-executable-memory` entitlement was required
|
||||
as well. However, it should not be used anymore if it can be avoided.
|
||||
|
||||
To see all of this in action, check out Electron Fiddle's source code,
|
||||
[especially its `electron-forge` configuration
|
||||
file](https://github.com/electron/fiddle/blob/master/forge.config.js).
|
||||
|
||||
If you plan to access the microphone or camera within your app using Electron's APIs, you'll also
|
||||
need to add the following entitlements:
|
||||
|
||||
```xml title="entitlements.plist"
|
||||
<key>com.apple.security.device.audio-input</key>
|
||||
<true/>
|
||||
<key>com.apple.security.device.camera</key>
|
||||
<true/>
|
||||
```
|
||||
|
||||
If these are not present in your app's entitlements when you invoke, for example:
|
||||
|
||||
```js title="main.js"
|
||||
const { systemPreferences } = require('electron')
|
||||
const microphone = systemPreferences.askForMediaAccess('microphone')
|
||||
```
|
||||
|
||||
Your app may crash. See the Resource Access section in [Hardened Runtime](https://developer.apple.com/documentation/security/hardened_runtime) for more information and entitlements you may need.
|
||||
|
||||
### Using Electron Builder
|
||||
|
||||
Electron Builder comes with a custom solution for signing your application. You
|
||||
can find [its documentation here](https://www.electron.build/code-signing).
|
||||
Detailed instructions on how to configure your application can be found in the [Electron Forge Code Signing Tutorial](https://www.electronforge.io/guides/code-signing/code-signing-macos).
|
||||
|
||||
### Using Electron Packager
|
||||
|
||||
If you're not using an integrated build pipeline like Forge or Builder, you
|
||||
If you're not using an integrated build pipeline like Forge, you
|
||||
are likely using [`electron-packager`], which includes [`electron-osx-sign`] and
|
||||
[`electron-notarize`].
|
||||
|
||||
@@ -204,36 +130,7 @@ commit it to your source code.
|
||||
|
||||
### Using Electron Forge
|
||||
|
||||
Once you have a code signing certificate file (`.pfx`), you can sign
|
||||
[Squirrel.Windows][maker-squirrel] and [MSI][maker-msi] installers in Electron Forge
|
||||
with the `certificateFile` and `certificatePassword` fields in their respective
|
||||
configuration objects.
|
||||
|
||||
For example, if you keep your Forge config in your `package.json` file and are
|
||||
creating a Squirrel.Windows installer:
|
||||
|
||||
```json {9-15} title='package.json'
|
||||
{
|
||||
"name": "my-app",
|
||||
"version": "0.0.1",
|
||||
//...
|
||||
"config": {
|
||||
"forge": {
|
||||
"packagerConfig": {},
|
||||
"makers": [
|
||||
{
|
||||
"name": "@electron-forge/maker-squirrel",
|
||||
"config": {
|
||||
"certificateFile": "./cert.pfx",
|
||||
"certificatePassword": "this-is-a-secret"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
//...
|
||||
}
|
||||
```
|
||||
Electron Forge is the recommended way to sign your `Squirrel.Windows` and `WiX MSI` installers. Detailed instructions on how to configure your application can be found in the [Electron Forge Code Signing Tutorial](https://www.electronforge.io/guides/code-signing/code-signing-macos).
|
||||
|
||||
### Using electron-winstaller (Squirrel.Windows)
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ you can deliver it to your users.
|
||||
## Packaging
|
||||
|
||||
To distribute your app with Electron, you need to package all your resources and assets
|
||||
into an executable and rebrand it. To do this, you can either use specialized tooling
|
||||
into an executable and rebrand it. To do this, you can either use specialized tooling like Electron Forge
|
||||
or do it manually. See the [Application Packaging][application-packaging] tutorial
|
||||
for more information.
|
||||
|
||||
|
||||
@@ -24,10 +24,11 @@ check out our [Electron Versioning](./electron-versioning.md) doc.
|
||||
| 14.0.0 | -- | 2021-May-27 | 2021-Aug-31 | M93 | v14.17 | 🚫 |
|
||||
| 15.0.0 | 2021-Jul-20 | 2021-Sep-01 | 2021-Sep-21 | M94 | v16.5 | 🚫 |
|
||||
| 16.0.0 | 2021-Sep-23 | 2021-Oct-20 | 2021-Nov-16 | M96 | v16.9 | 🚫 |
|
||||
| 17.0.0 | 2021-Nov-18 | 2022-Jan-06 | 2022-Feb-01 | M98 | v16.13 | ✅ |
|
||||
| 17.0.0 | 2021-Nov-18 | 2022-Jan-06 | 2022-Feb-01 | M98 | v16.13 | 🚫 |
|
||||
| 18.0.0 | 2022-Feb-03 | 2022-Mar-03 | 2022-Mar-29 | M100 | v16.13 | ✅ |
|
||||
| 19.0.0 | 2022-Mar-31 | 2022-Apr-26 | 2022-May-24 | M102 | v16.14 | ✅ |
|
||||
| 20.0.0 | 2022-May-26 | 2022-Jun-21 | 2022-Aug-02 | M104 | TBD | ✅ |
|
||||
| 20.0.0 | 2022-May-26 | 2022-Jun-21 | 2022-Aug-02 | M104 | v16.15 | ✅ |
|
||||
| 21.0.0 | 2022-Aug-04 | 2022-Aug-30 | 2022-Sep-27 | M106 | TBD | ✅ |
|
||||
|
||||
**Notes:**
|
||||
|
||||
|
||||
36
docs/tutorial/forge-overview.md
Normal file
36
docs/tutorial/forge-overview.md
Normal file
@@ -0,0 +1,36 @@
|
||||
# Distributing Apps With Electron Forge
|
||||
|
||||
Electron Forge is a tool for packaging and publishing Electron applications.
|
||||
It unifies Electron's build tooling ecosystem into
|
||||
a single extensible interface so that anyone can jump right into making Electron apps.
|
||||
|
||||
## Getting started
|
||||
|
||||
The [Electron Forge docs] contain detailed information on taking your application
|
||||
from source code to your end users' machines.
|
||||
This includes:
|
||||
|
||||
* Packaging your application [(package)]
|
||||
* Generating executables and installers for each OS [(make)], and,
|
||||
* Publishing these files to online platforms to download [(publish)].
|
||||
|
||||
For beginners, we recommend following through Electron's [tutorial] to develop, build,
|
||||
package and publish your first Electron app. If you have already developed an app on your machine
|
||||
and want to start on packaging and distribution, start from [step 5] of the tutorial.
|
||||
|
||||
## Getting help
|
||||
|
||||
* If you need help with developing your app, our [community Discord server][discord] is a great place
|
||||
to get advice from other Electron app developers.
|
||||
* If you suspect you're running into a bug with Forge, please check the [GitHub issue tracker]
|
||||
to see if any existing issues match your problem. If not, feel free to fill out our bug report
|
||||
template and submit a new issue.
|
||||
|
||||
[Electron Forge Docs]: https://www.electronforge.io/
|
||||
[step 5]: ./tutorial-5-packaging.md
|
||||
[(package)]: https://www.electronforge.io/cli#package
|
||||
[(make)]: https://www.electronforge.io/cli#make
|
||||
[(publish)]: https://www.electronforge.io/cli#publish
|
||||
[GitHub issue tracker]: https://github.com/electron-userland/electron-forge/issues
|
||||
[discord]: https://discord.gg/APGC3k5yaH
|
||||
[tutorial]: https://www.electronjs.org/docs/latest/tutorial/tutorial-prerequisites
|
||||
@@ -8,6 +8,59 @@ For a subset of Electron functionality it makes sense to disable certain feature
|
||||
|
||||
Fuses are the solution to this problem, at a high level they are "magic bits" in the Electron binary that can be flipped when packaging your Electron app to enable / disable certain features / restrictions. Because they are flipped at package time before you code sign your app the OS becomes responsible for ensuring those bits aren't flipped back via OS level code signing validation (Gatekeeper / App Locker).
|
||||
|
||||
## Current Fuses
|
||||
|
||||
### `runAsNode`
|
||||
|
||||
**Default:** Enabled
|
||||
**@electron/fuses:** `FuseV1Options.RunAsNode`
|
||||
|
||||
The runAsNode fuse toggles whether the `ELECTRON_RUN_AS_NODE` environment variable is respected or not. Please note that if this fuse is disabled then `process.fork` in the main process will not function as expected as it depends on this environment variable to function.
|
||||
|
||||
### `cookieEncryption`
|
||||
|
||||
**Default:** Disabled
|
||||
**@electron/fuses:** `FuseV1Options.EnableCookieEncryption`
|
||||
|
||||
The cookieEncryption fuse toggles whether the cookie store on disk is encrypted using OS level cryptography keys. By default the sqlite database that Chromium uses to store cookies stores the values in plaintext. If you wish to ensure your apps cookies are encrypted in the same way Chrome does then you should enable this fuse. Please note it is a one-way transition, if you enable this fuse existing unencrypted cookies will be encrypted-on-write but if you then disable the fuse again your cookie store will effectively be corrupt and useless. Most apps can safely enable this fuse.
|
||||
|
||||
### `nodeOptions`
|
||||
|
||||
**Default:** Enabled
|
||||
**@electron/fuses:** `FuseV1Options.EnableNodeOptionsEnvironmentVariable`
|
||||
|
||||
The nodeOptions fuse toggles whether the [`NODE_OPTIONS`](https://nodejs.org/api/cli.html#node_optionsoptions) environment variable is respected or not. This environment variable can be used to pass all kinds of custom options to the Node.js runtime and isn't typically used by apps in production. Most apps can safely disable this fuse.
|
||||
|
||||
### `nodeCliInspect`
|
||||
|
||||
**Default:** Enabled
|
||||
**@electron/fuses:** `FuseV1Options.EnableNodeCliInspectArguments`
|
||||
|
||||
The nodeCliInspect fuse toggles whether the `--inspect`, `--inspect-brk`, etc. flags are respected or not. When disabled it also ensures that `SIGUSR1` signal does not initialize the main process inspector. Most apps can safely disable this fuse.
|
||||
|
||||
### `embeddedAsarIntegrityValidation`
|
||||
|
||||
**Default:** Disabled
|
||||
**@electron/fuses:** `FuseV1Options.EnableEmbeddedAsarIntegrityValidation`
|
||||
|
||||
The embeddedAsarIntegrityValidation fuse toggles an experimental feature on macOS that validates the content of the `app.asar` file when it is loaded. This feature is designed to have a minimal performance impact but may marginally slow down file reads from inside the `app.asar` archive.
|
||||
|
||||
For more information on how to use asar integrity validation please read the [Asar Integrity](asar-integrity.md) documentation.
|
||||
|
||||
### `onlyLoadAppFromAsar`
|
||||
|
||||
**Default:** Disabled
|
||||
**@electron/fuses:** `FuseV1Options.OnlyLoadAppFromAsar`
|
||||
|
||||
The onlyLoadAppFromAsar fuse changes the search system that Electron uses to locate your app code. By default Electron will search in the following order `app.asar` -> `app` -> `default_app.asar`. When this fuse is enabled the search order becomes a single entry `app.asar` thus ensuring that when combined with the `embeddedAsarIntegrityValidation` fuse it is impossible to load non-validated code.
|
||||
|
||||
### `loadBrowserProcessSpecificV8Snapshot`
|
||||
|
||||
**Default:** Disabled
|
||||
**@electron/fuses:** `FuseV1Options.LoadBrowserProcessSpecificV8Snapshot`
|
||||
|
||||
The loadBrowserProcessSpecificV8Snapshot fuse changes which V8 snapshot file is used for the browser process. By default Electron's processes will all use the same V8 snapshot file. When this fuse is enabled the browser process uses the file called `browser_v8_context_snapshot.bin` for its V8 snapshot. The other processes will use the V8 snapshot file that they normally do.
|
||||
|
||||
## How do I flip the fuses?
|
||||
|
||||
### The easy way
|
||||
@@ -20,11 +73,18 @@ require('@electron/fuses').flipFuses(
|
||||
require('electron'),
|
||||
// Fuses to flip
|
||||
{
|
||||
runAsNode: false
|
||||
version: FuseVersion.V1,
|
||||
[FuseV1Options.RunAsNode]: false
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
You can validate the fuses have been flipped or check the fuse status of an arbitrary Electron app using the fuses CLI.
|
||||
|
||||
```bash
|
||||
npx @electron/fuses read --app /Applications/Foo.app
|
||||
```
|
||||
|
||||
### The hard way
|
||||
|
||||
#### Quick Glossary
|
||||
|
||||
@@ -44,14 +44,14 @@ are the different categories and what you can expect on each one:
|
||||
application.
|
||||
- **Processes in Electron**: In-depth reference on Electron processes and how to work with them.
|
||||
- **Best Practices**: Important checklists to keep in mind when developing an Electron app.
|
||||
- **How-To Examples**: Quick references to add features to your Electron app.
|
||||
- **Examples**: Quick references to add features to your Electron app.
|
||||
- **Development**: Miscellaneous development guides.
|
||||
- **Distribution**: Learn how to distribute your app to end users.
|
||||
- **Testing and debugging**: How to debug JavaScript, write tests, and other tools used
|
||||
- **Testing And Debugging**: How to debug JavaScript, write tests, and other tools used
|
||||
to create quality Electron applications.
|
||||
- **Resources**: Useful links to better understand how the Electron project works
|
||||
- **References**: Useful links to better understand how the Electron project works
|
||||
and is organized.
|
||||
- **Contributing to Electron**: Compiling Electron and making contributions can be daunting.
|
||||
- **Contributing**: Compiling Electron and making contributions can be daunting.
|
||||
We try to make it easier in this section.
|
||||
|
||||
## Getting help
|
||||
@@ -66,6 +66,7 @@ Are you getting stuck anywhere? Here are a few links to places to look:
|
||||
|
||||
<!-- Links -->
|
||||
|
||||
[tutorial]: tutorial-1-prerequisites.md
|
||||
[api documentation]: ../api/app.md
|
||||
[chromium]: https://www.chromium.org/
|
||||
[discord]: https://discord.com/invite/APGC3k5yaH
|
||||
|
||||
@@ -232,7 +232,7 @@ how to meet the Mac App Store requirements.
|
||||
|
||||
### Upload
|
||||
|
||||
The Application Loader should be used to upload the signed app to iTunes
|
||||
[Apple Transporter][apple-transporter] should be used to upload the signed app to App Store
|
||||
Connect for processing, making sure you have [created a record][create-record]
|
||||
before uploading.
|
||||
|
||||
@@ -345,7 +345,8 @@ Electron uses following cryptographic algorithms:
|
||||
[app-sandboxing]: https://developer.apple.com/app-sandboxing/
|
||||
[app-notarization]: https://developer.apple.com/documentation/security/notarizing_macos_software_before_distribution
|
||||
[submitting-your-app]: https://developer.apple.com/library/mac/documentation/IDEs/Conceptual/AppDistributionGuide/SubmittingYourApp/SubmittingYourApp.html
|
||||
[create-record]: https://developer.apple.com/library/ios/documentation/LanguagesUtilities/Conceptual/iTunesConnect_Guide/Chapters/CreatingiTunesConnectRecord.html
|
||||
[create-record]: https://help.apple.com/app-store-connect/#/dev2cd126805
|
||||
[apple-transporter]: https://help.apple.com/itc/transporteruserguide/en.lproj/static.html
|
||||
[submit-for-review]: https://developer.apple.com/library/ios/documentation/LanguagesUtilities/Conceptual/iTunesConnect_Guide/Chapters/SubmittingTheApp.html
|
||||
[export-compliance]: https://help.apple.com/app-store-connect/#/devc3f64248f
|
||||
[user-selected]: https://developer.apple.com/library/mac/documentation/Miscellaneous/Reference/EntitlementKeyReference/Chapters/EnablingAppSandbox.html#//apple_ref/doc/uid/TP40011195-CH4-SW6
|
||||
|
||||
@@ -8,8 +8,7 @@ your app.
|
||||
|
||||
Here is a very brief example of what a MessagePort is and how it works:
|
||||
|
||||
```js
|
||||
// renderer.js ///////////////////////////////////////////////////////////////
|
||||
```js title='renderer.js (Renderer Process)'
|
||||
// MessagePorts are created in pairs. A connected pair of message ports is
|
||||
// called a channel.
|
||||
const channel = new MessageChannel()
|
||||
@@ -28,8 +27,7 @@ port2.postMessage({ answer: 42 })
|
||||
ipcRenderer.postMessage('port', null, [port1])
|
||||
```
|
||||
|
||||
```js
|
||||
// main.js ///////////////////////////////////////////////////////////////////
|
||||
```js title='main.js (Main Process)'
|
||||
// In the main process, we receive the port.
|
||||
ipcMain.on('port', (event) => {
|
||||
// When we receive a MessagePort in the main process, it becomes a
|
||||
@@ -84,14 +82,84 @@ process, you can listen for the `close` event by calling `port.on('close',
|
||||
|
||||
## Example use cases
|
||||
|
||||
### Setting up a MessageChannel between two renderers
|
||||
|
||||
In this example, the main process sets up a MessageChannel, then sends each port
|
||||
to a different renderer. This allows renderers to send messages to each other
|
||||
without needing to use the main process as an in-between.
|
||||
|
||||
```js title='main.js (Main Process)'
|
||||
const { BrowserWindow, app, MessageChannelMain } = require('electron')
|
||||
|
||||
app.whenReady().then(async () => {
|
||||
// create the windows.
|
||||
const mainWindow = new BrowserWindow({
|
||||
show: false,
|
||||
webPreferences: {
|
||||
contextIsolation: false,
|
||||
preload: 'preloadMain.js'
|
||||
}
|
||||
})
|
||||
|
||||
const secondaryWindow = new BrowserWindow({
|
||||
show: false,
|
||||
webPreferences: {
|
||||
contextIsolation: false,
|
||||
preload: 'preloadSecondary.js'
|
||||
}
|
||||
})
|
||||
|
||||
// set up the channel.
|
||||
const { port1, port2 } = new MessageChannelMain()
|
||||
|
||||
// once the webContents are ready, send a port to each webContents with postMessage.
|
||||
mainWindow.once('ready-to-show', () => {
|
||||
mainWindow.webContents.postMessage('port', null, [port1])
|
||||
})
|
||||
|
||||
secondaryWindow.once('ready-to-show', () => {
|
||||
secondaryWindow.webContents.postMessage('port', null, [port2])
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
Then, in your preload scripts you receive the port through IPC and set up the
|
||||
listeners.
|
||||
|
||||
```js title='preloadMain.js and preloadSecondary.js (Preload scripts)'
|
||||
const { ipcRenderer } = require('electron')
|
||||
|
||||
ipcRenderer.on('port', e => {
|
||||
// port received, make it globally available.
|
||||
window.electronMessagePort = e.ports[0]
|
||||
|
||||
window.electronMessagePort.onmessage = messageEvent => {
|
||||
// handle message
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
In this example messagePort is bound to the `window` object directly. It is better
|
||||
to use `contextIsolation` and set up specific contextBridge calls for each of your
|
||||
expected messages, but for the simplicity of this example we don't. You can find an
|
||||
example of context isolation further down this page at [Communicating directly between the main process and the main world of a context-isolated page](#communicating-directly-between-the-main-process-and-the-main-world-of-a-context-isolated-page)
|
||||
|
||||
That means window.electronMessagePort is globally available and you can call
|
||||
`postMessage` on it from anywhere in your app to send a message to the other
|
||||
renderer.
|
||||
|
||||
```js title='renderer.js (Renderer Process)'
|
||||
// elsewhere in your code to send a message to the other renderers message handler
|
||||
window.electronMessagePort.postmessage('ping')
|
||||
```
|
||||
|
||||
### Worker process
|
||||
|
||||
In this example, your app has a worker process implemented as a hidden window.
|
||||
You want the app page to be able to communicate directly with the worker
|
||||
process, without the performance overhead of relaying via the main process.
|
||||
|
||||
```js
|
||||
// main.js ///////////////////////////////////////////////////////////////////
|
||||
```js title='main.js (Main Process)'
|
||||
const { BrowserWindow, app, ipcMain, MessageChannelMain } = require('electron')
|
||||
|
||||
app.whenReady().then(async () => {
|
||||
@@ -129,8 +197,7 @@ app.whenReady().then(async () => {
|
||||
})
|
||||
```
|
||||
|
||||
```html
|
||||
<!-- worker.html ------------------------------------------------------------>
|
||||
```html title='worker.html'
|
||||
<script>
|
||||
const { ipcRenderer } = require('electron')
|
||||
|
||||
@@ -153,8 +220,7 @@ ipcRenderer.on('new-client', (event) => {
|
||||
</script>
|
||||
```
|
||||
|
||||
```html
|
||||
<!-- app.html --------------------------------------------------------------->
|
||||
```html title='app.html'
|
||||
<script>
|
||||
const { ipcRenderer } = require('electron')
|
||||
|
||||
@@ -182,9 +248,7 @@ Electron's built-in IPC methods only support two modes: fire-and-forget
|
||||
can implement a "response stream", where a single request responds with a
|
||||
stream of data.
|
||||
|
||||
```js
|
||||
// renderer.js ///////////////////////////////////////////////////////////////
|
||||
|
||||
```js title='renderer.js (Renderer Process)'
|
||||
const makeStreamingRequest = (element, callback) => {
|
||||
// MessageChannels are lightweight--it's cheap to create a new one for each
|
||||
// request.
|
||||
@@ -208,14 +272,12 @@ const makeStreamingRequest = (element, callback) => {
|
||||
}
|
||||
|
||||
makeStreamingRequest(42, (data) => {
|
||||
console.log('got response data:', event.data)
|
||||
console.log('got response data:', data)
|
||||
})
|
||||
// We will see "got response data: 42" 10 times.
|
||||
```
|
||||
|
||||
```js
|
||||
// main.js ///////////////////////////////////////////////////////////////////
|
||||
|
||||
```js title='main.js (Main Process)'
|
||||
ipcMain.on('give-me-a-stream', (event, msg) => {
|
||||
// The renderer has sent us a MessagePort that it wants us to send our
|
||||
// response over.
|
||||
@@ -242,8 +304,7 @@ the renderer are delivered to the isolated world, rather than to the main
|
||||
world. Sometimes you want to deliver messages to the main world directly,
|
||||
without having to step through the isolated world.
|
||||
|
||||
```js
|
||||
// main.js ///////////////////////////////////////////////////////////////////
|
||||
```js title='main.js (Main Process)'
|
||||
const { BrowserWindow, app, MessageChannelMain } = require('electron')
|
||||
const path = require('path')
|
||||
|
||||
@@ -278,8 +339,7 @@ app.whenReady().then(async () => {
|
||||
})
|
||||
```
|
||||
|
||||
```js
|
||||
// preload.js ////////////////////////////////////////////////////////////////
|
||||
```js title='preload.js (Preload Script)'
|
||||
const { ipcRenderer } = require('electron')
|
||||
|
||||
// We need to wait until the main world is ready to receive the message before
|
||||
@@ -297,8 +357,7 @@ ipcRenderer.on('main-world-port', async (event) => {
|
||||
})
|
||||
```
|
||||
|
||||
```html
|
||||
<!-- index.html ------------------------------------------------------------->
|
||||
```html title='index.html'
|
||||
<script>
|
||||
window.onmessage = (event) => {
|
||||
// event.source === window means the message is coming from the preload
|
||||
|
||||
@@ -22,7 +22,6 @@ In `preload.js` use the [`contextBridge`] to inject a method `window.electron.st
|
||||
|
||||
```js
|
||||
const { contextBridge, ipcRenderer } = require('electron')
|
||||
const path = require('path')
|
||||
|
||||
contextBridge.exposeInMainWorld('electron', {
|
||||
startDrag: (fileName) => {
|
||||
|
||||
@@ -12,28 +12,10 @@ the GPU service and the network service.
|
||||
|
||||
See Chromium's [Sandbox design document][sandbox] for more information.
|
||||
|
||||
## Electron's sandboxing policies
|
||||
|
||||
Electron comes with a mixed sandbox environment, meaning sandboxed processes can run
|
||||
alongside privileged ones. By default, renderer processes are not sandboxed, but
|
||||
utility processes are. Note that as in Chromium, the main (browser) process is
|
||||
privileged and cannot be sandboxed.
|
||||
|
||||
Historically, this mixed sandbox approach was established because having Node.js available
|
||||
in the renderer is an extremely powerful tool for app developers. Unfortunately, this
|
||||
feature is also an equally massive security vulnerability.
|
||||
|
||||
Theoretically, unsandboxed renderers are not a problem for desktop applications that
|
||||
only display trusted code, but they make Electron less secure than Chromium for
|
||||
displaying untrusted web content. However, even purportedly trusted code may be
|
||||
dangerous — there are countless attack vectors that malicious actors can use, from
|
||||
cross-site scripting to content injection to man-in-the-middle attacks on remotely loaded
|
||||
websites, just to name a few. For this reason, we recommend enabling renderer sandboxing
|
||||
for the vast majority of cases under an abundance of caution.
|
||||
|
||||
<!--TODO: update this guide when #28466 is either solved or closed -->
|
||||
Note that there is an active discussion in the issue tracker to enable renderer sandboxing
|
||||
by default. See [#28466][issue-28466]) for details.
|
||||
Starting from Electron 20, the sandbox is enabled for renderer processes without any
|
||||
further configuration. If you want to disable the sandbox for a process, see the
|
||||
[Disabling the sandbox for a single process](#disabling-the-sandbox-for-a-single-process)
|
||||
section.
|
||||
|
||||
## Sandbox behaviour in Electron
|
||||
|
||||
@@ -46,12 +28,17 @@ When renderer processes in Electron are sandboxed, they behave in the same way a
|
||||
regular Chrome renderer would. A sandboxed renderer won't have a Node.js
|
||||
environment initialized.
|
||||
|
||||
<!-- TODO(erickzhao): when we have a solid guide for IPC, link it here -->
|
||||
Therefore, when the sandbox is enabled, renderer processes can only perform privileged
|
||||
tasks (such as interacting with the filesystem, making changes to the system, or spawning
|
||||
subprocesses) by delegating these tasks to the main process via inter-process
|
||||
communication (IPC).
|
||||
|
||||
:::note
|
||||
|
||||
For more info on inter-process communication, check out our [IPC guide](./ipc.md).
|
||||
|
||||
:::
|
||||
|
||||
### Preload scripts
|
||||
|
||||
In order to allow renderer processes to communicate with the main process, preload
|
||||
@@ -66,7 +53,7 @@ but can only import a subset of Electron and Node's built-in modules:
|
||||
|
||||
In addition, the preload script also polyfills certain Node.js primitives as globals:
|
||||
|
||||
* [`Buffer`](https://nodejs.org/api/Buffer.html)
|
||||
* [`Buffer`](https://nodejs.org/api/buffer.html)
|
||||
* [`process`](../api/process.md)
|
||||
* [`clearImmediate`](https://nodejs.org/api/timers.html#timers_clearimmediate_immediate)
|
||||
* [`setImmediate`](https://nodejs.org/api/timers.html#timers_setimmediate_callback_args)
|
||||
@@ -83,13 +70,17 @@ privileged APIs to untrusted code running in the renderer process unless
|
||||
|
||||
## Configuring the sandbox
|
||||
|
||||
### Enabling the sandbox for a single process
|
||||
For most apps, sandboxing is the best choice. In certain use cases that are incompatible with
|
||||
the sandbox (for instance, when using native node modules in the renderer),
|
||||
it is possible to disable the sandbox for specific processes. This comes with security
|
||||
risks, especially if any untrusted code or content is present in the unsandboxed process.
|
||||
|
||||
In Electron, renderer sandboxing can be enabled on a per-process basis with
|
||||
the `sandbox: true` preference in the [`BrowserWindow`][browser-window] constructor.
|
||||
### Disabling the sandbox for a single process
|
||||
|
||||
```js
|
||||
// main.js
|
||||
In Electron, renderer sandboxing can be disabled on a per-process basis with
|
||||
the `sandbox: false` preference in the [`BrowserWindow`][browser-window] constructor.
|
||||
|
||||
```js title='main.js'
|
||||
app.whenReady().then(() => {
|
||||
const win = new BrowserWindow({
|
||||
webPreferences: {
|
||||
@@ -100,17 +91,30 @@ app.whenReady().then(() => {
|
||||
})
|
||||
```
|
||||
|
||||
Sandboxing is also disabled whenever Node.js integration is enabled in the renderer.
|
||||
This can be done through the BrowserWindow constructor with the `nodeIntegration: true` flag.
|
||||
|
||||
```js title='main.js'
|
||||
app.whenReady().then(() => {
|
||||
const win = new BrowserWindow({
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
win.loadURL('https://google.com')
|
||||
})
|
||||
```
|
||||
|
||||
### Enabling the sandbox globally
|
||||
|
||||
If you want to force sandboxing for all renderers, you can also use the
|
||||
[`app.enableSandbox`][enable-sandbox] API. Note that this API has to be called before the
|
||||
app's `ready` event.
|
||||
|
||||
```js
|
||||
// main.js
|
||||
```js title='main.js'
|
||||
app.enableSandbox()
|
||||
app.whenReady().then(() => {
|
||||
// no need to pass `sandbox: true` since `app.enableSandbox()` was called.
|
||||
// any sandbox:false calls are overridden since `app.enableSandbox()` was called.
|
||||
const win = new BrowserWindow()
|
||||
win.loadURL('https://google.com')
|
||||
})
|
||||
@@ -139,16 +143,16 @@ issues:
|
||||
have, to inherit everything we can from Chromium, and to respond quickly to
|
||||
security issues, but Electron cannot be as secure as Chromium without the
|
||||
resources that Chromium is able to dedicate.
|
||||
2. Some security features in Chrome (such as Safe Browsing and Certificate
|
||||
1. Some security features in Chrome (such as Safe Browsing and Certificate
|
||||
Transparency) require a centralized authority and dedicated servers, both of
|
||||
which run counter to the goals of the Electron project. As such, we disable
|
||||
those features in Electron, at the cost of the associated security they
|
||||
would otherwise bring.
|
||||
3. There is only one Chromium, whereas there are many thousands of apps built
|
||||
1. There is only one Chromium, whereas there are many thousands of apps built
|
||||
on Electron, all of which behave slightly differently. Accounting for those
|
||||
differences can yield a huge possibility space, and make it challenging to
|
||||
ensure the security of the platform in unusual use cases.
|
||||
4. We can't push security updates to users directly, so we rely on app vendors
|
||||
1. We can't push security updates to users directly, so we rely on app vendors
|
||||
to upgrade the version of Electron underlying their app in order for
|
||||
security updates to reach users.
|
||||
|
||||
|
||||
@@ -256,7 +256,7 @@ the sandbox in all renderers. Loading, reading or processing any untrusted
|
||||
content in an unsandboxed process, including the main process, is not advised.
|
||||
|
||||
:::info
|
||||
For more information on what `contextIsolation` is and how to enable it please
|
||||
For more information on what Process Sandboxing is and how to enable it please
|
||||
see our dedicated [Process Sandboxing](sandbox.md) document.
|
||||
:::info
|
||||
|
||||
|
||||
@@ -1,95 +0,0 @@
|
||||
# Testing Widevine CDM
|
||||
|
||||
In Electron you can use the Widevine CDM library shipped with Chrome browser.
|
||||
|
||||
Widevine Content Decryption Modules (CDMs) are how streaming services protect
|
||||
content using HTML5 video to web browsers without relying on an NPAPI plugin
|
||||
like Flash or Silverlight. Widevine support is an alternative solution for
|
||||
streaming services that currently rely on Silverlight for playback of
|
||||
DRM-protected video content. It will allow websites to show DRM-protected video
|
||||
content in Firefox without the use of NPAPI plugins. The Widevine CDM runs in an
|
||||
open-source CDM sandbox providing better user security than NPAPI plugins.
|
||||
|
||||
#### Note on VMP
|
||||
|
||||
As of [`Electron v1.8.0 (Chrome v59)`](https://electronjs.org/releases#1.8.1),
|
||||
the below steps are may only be some of the necessary steps to enable Widevine;
|
||||
any app on or after that version intending to use the Widevine CDM may need to
|
||||
be signed using a license obtained from [Widevine](https://www.widevine.com/)
|
||||
itself.
|
||||
|
||||
Per [Widevine](https://www.widevine.com/):
|
||||
|
||||
> Chrome 59 (and later) includes support for Verified Media Path (VMP). VMP
|
||||
> provides a method to verify the authenticity of a device platform. For browser
|
||||
> deployments, this will provide an additional signal to determine if a
|
||||
> browser-based implementation is reliable and secure.
|
||||
>
|
||||
> The proxy integration guide has been updated with information about VMP and
|
||||
> how to issue licenses.
|
||||
>
|
||||
> Widevine recommends our browser-based integrations (vendors and browser-based
|
||||
> applications) add support for VMP.
|
||||
|
||||
To enable video playback with this new restriction,
|
||||
[castLabs](https://castlabs.com/open-source/downstream/) has created a
|
||||
[fork](https://github.com/castlabs/electron-releases) that has implemented the
|
||||
necessary changes to enable Widevine to be played in an Electron application if
|
||||
one has obtained the necessary licenses from widevine.
|
||||
|
||||
## Getting the library
|
||||
|
||||
Open `chrome://components/` in Chrome browser, find `Widevine Content Decryption Module`
|
||||
and make sure it is up to date, then you can find the library files from the
|
||||
application directory.
|
||||
|
||||
### On Windows
|
||||
|
||||
The library file `widevinecdm.dll` will be under
|
||||
`Program Files(x86)/Google/Chrome/Application/CHROME_VERSION/WidevineCdm/_platform_specific/win_(x86|x64)/`
|
||||
directory.
|
||||
|
||||
### On macOS
|
||||
|
||||
The library file `libwidevinecdm.dylib` will be under
|
||||
`/Applications/Google Chrome.app/Contents/Versions/CHROME_VERSION/Google Chrome Framework.framework/Versions/A/Libraries/WidevineCdm/_platform_specific/mac_(x86|x64)/`
|
||||
directory.
|
||||
|
||||
**Note:** Make sure that chrome version used by Electron is greater than or
|
||||
equal to the `min_chrome_version` value of Chrome's widevine cdm component.
|
||||
The value can be found in `manifest.json` under `WidevineCdm` directory.
|
||||
|
||||
## Using the library
|
||||
|
||||
After getting the library files, you should pass the path to the file
|
||||
with `--widevine-cdm-path` command line switch, and the library's version
|
||||
with `--widevine-cdm-version` switch. The command line switches have to be
|
||||
passed before the `ready` event of `app` module gets emitted.
|
||||
|
||||
Example code:
|
||||
|
||||
```javascript
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
|
||||
// You have to pass the directory that contains widevine library here, it is
|
||||
// * `libwidevinecdm.dylib` on macOS,
|
||||
// * `widevinecdm.dll` on Windows.
|
||||
app.commandLine.appendSwitch('widevine-cdm-path', '/path/to/widevine_library')
|
||||
// The version of plugin can be got from `chrome://components` page in Chrome.
|
||||
app.commandLine.appendSwitch('widevine-cdm-version', '1.4.8.866')
|
||||
|
||||
let win = null
|
||||
app.whenReady().then(() => {
|
||||
win = new BrowserWindow()
|
||||
win.show()
|
||||
})
|
||||
```
|
||||
|
||||
## Verifying Widevine CDM support
|
||||
|
||||
To verify whether widevine works, you can use following ways:
|
||||
|
||||
* Open https://shaka-player-demo.appspot.com/ and load a manifest that uses
|
||||
`Widevine`.
|
||||
* Open http://www.dash-player.com/demo/drm-test-area/, check whether the page
|
||||
says `bitdash uses Widevine in your browser`, then play the video.
|
||||
@@ -123,7 +123,7 @@ the list of versions in the [electron/releases] repository.
|
||||
[homebrew]: https://brew.sh/
|
||||
[mdn-guide]: https://developer.mozilla.org/en-US/docs/Learn/
|
||||
[node]: https://nodejs.org/
|
||||
[node-guide]: https://nodejs.dev/learn
|
||||
[node-guide]: https://nodejs.dev/en/learn/
|
||||
[node-download]: https://nodejs.org/en/download/
|
||||
[nvm]: https://github.com/nvm-sh/nvm
|
||||
[process-model]: ./process-model.md
|
||||
|
||||
@@ -350,7 +350,7 @@ app.whenReady().then(() => {
|
||||
|
||||
## Optional: Debugging from VS Code
|
||||
|
||||
If you want to debug your application using VS Code, you have need attach VS Code to
|
||||
If you want to debug your application using VS Code, you need to attach VS Code to
|
||||
both the main and renderer processes. Here is a sample configuration for you to
|
||||
run. Create a launch.json configuration in a new `.vscode` folder in your project:
|
||||
|
||||
@@ -369,12 +369,12 @@ run. Create a launch.json configuration in a new `.vscode` folder in your projec
|
||||
"name": "Renderer",
|
||||
"port": 9222,
|
||||
"request": "attach",
|
||||
"type": "pwa-chrome",
|
||||
"type": "chrome",
|
||||
"webRoot": "${workspaceFolder}"
|
||||
},
|
||||
{
|
||||
"name": "Main",
|
||||
"type": "pwa-node",
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"runtimeExecutable": "${workspaceFolder}/node_modules/.bin/electron",
|
||||
@@ -398,11 +398,11 @@ What we have done in the `launch.json` file is to create 3 configurations:
|
||||
- `Main` is used to start the main process and also expose port 9222 for remote debugging
|
||||
(`--remote-debugging-port=9222`). This is the port that we will use to attach the debugger
|
||||
for the `Renderer`. Because the main process is a Node.js process, the type is set to
|
||||
`pwa-node` (`pwa-` is the prefix that tells VS Code to use the latest JavaScript debugger).
|
||||
`node`.
|
||||
- `Renderer` is used to debug the renderer process. Because the main process is the one
|
||||
that creates the process, we have to "attach" to it (`"request": "attach"`) instead of
|
||||
creating a new one.
|
||||
The renderer process is a web one, so the debugger we have to use is `pwa-chrome`.
|
||||
The renderer process is a web one, so the debugger we have to use is `chrome`.
|
||||
- `Main + renderer` is a [compound task] that executes the previous ones simultaneously.
|
||||
|
||||
:::caution
|
||||
|
||||
@@ -38,7 +38,25 @@ called a **preload**.
|
||||
## Augmenting the renderer with a preload script
|
||||
|
||||
A BrowserWindow's preload script runs in a context that has access to both the HTML DOM
|
||||
and a Node.js environment. Preload scripts are injected before a web page loads in the renderer,
|
||||
and a limited subset of Node.js and Electron APIs.
|
||||
|
||||
:::info Preload script sandboxing
|
||||
|
||||
From Electron 20 onwards, preload scripts are **sandboxed** by default and no longer have access
|
||||
to a full Node.js environment. Practically, this means that you have a polyfilled `require`
|
||||
function that only has access to a limited set of APIs.
|
||||
|
||||
| Available API | Details |
|
||||
| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Electron modules | Renderer process modules |
|
||||
| Node.js modules | [`events`](https://nodejs.org/api/events.html), [`timers`](https://nodejs.org/api/timers.html), [`url`](https://nodejs.org/api/url.html) |
|
||||
| Polyfilled globals | [`Buffer`](https://nodejs.org/api/buffer.html), [`process`](../api/process.md), [`clearImmediate`](https://nodejs.org/api/timers.html#timers_clearimmediate_immediate), [`setImmediate`](https://nodejs.org/api/timers.html#timers_setimmediate_callback_args) |
|
||||
|
||||
For more information, check out the [Process Sandboxing](./sandbox.md) guide.
|
||||
|
||||
:::
|
||||
|
||||
Preload scripts are injected before a web page loads in the renderer,
|
||||
similar to a Chrome extension's [content scripts][content-script]. To add features to your renderer
|
||||
that require privileged access, you can define [global] objects through the
|
||||
[contextBridge][contextbridge] API.
|
||||
|
||||
@@ -64,7 +64,7 @@ into end users' hands.
|
||||
|
||||
[discord]: https://discord.com/invite/APGC3k5yaH
|
||||
[github]: https://github.com/electron/electronjs.org-new/issues/new
|
||||
[how to]: ./examples.md
|
||||
[how-to]: ./examples.md
|
||||
[node-platform]: https://nodejs.org/api/process.html#process_process_platform
|
||||
|
||||
<!-- Tutorial links -->
|
||||
|
||||
@@ -111,6 +111,12 @@ Electron Forge can be configured to create distributables in different OS-specif
|
||||
|
||||
:::
|
||||
|
||||
:::tip Creating and Adding Application Icons
|
||||
|
||||
Setting custom application icons requires a few additions to your config. Check out [Forge's icon tutorial] for more information.
|
||||
|
||||
:::
|
||||
|
||||
:::note Packaging without Electron Forge
|
||||
|
||||
If you want to manually package your code, or if you're just interested understanding the
|
||||
@@ -214,6 +220,7 @@ information.
|
||||
[electron forge]: https://www.electronforge.io
|
||||
[electron forge cli documentation]: https://www.electronforge.io/cli#commands
|
||||
[makers]: https://www.electronforge.io/config/makers
|
||||
[Forge's icon tutorial]: https://www.electronforge.io/guides/create-and-add-icons
|
||||
|
||||
<!-- Tutorial links -->
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ filenames = {
|
||||
|
||||
lib_sources_linux = [
|
||||
"shell/browser/browser_linux.cc",
|
||||
"shell/browser/electron_browser_main_parts_linux.cc",
|
||||
"shell/browser/lib/power_observer_linux.cc",
|
||||
"shell/browser/lib/power_observer_linux.h",
|
||||
"shell/browser/linux/unity_service.cc",
|
||||
|
||||
@@ -18,4 +18,4 @@
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,9 +72,8 @@ BrowserWindow.getAllWindows = () => {
|
||||
|
||||
BrowserWindow.getFocusedWindow = () => {
|
||||
for (const window of BrowserWindow.getAllWindows()) {
|
||||
const hasWC = window.webContents && !window.webContents.isDestroyed();
|
||||
if (!window.isDestroyed() && hasWC) {
|
||||
if (window.isFocused() || window.isDevToolsFocused()) return window;
|
||||
if (!window.isDestroyed() && window.webContents && !window.webContents.isDestroyed()) {
|
||||
if (window.isFocused() || window.webContents.isDevToolsFocused()) return window;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
@@ -475,12 +475,14 @@ WebContents.prototype.loadURL = function (url, options) {
|
||||
const removeListeners = () => {
|
||||
this.removeListener('did-finish-load', finishListener);
|
||||
this.removeListener('did-fail-load', failListener);
|
||||
this.removeListener('did-navigate-in-page', finishListener);
|
||||
this.removeListener('did-start-navigation', navigationListener);
|
||||
this.removeListener('did-stop-loading', stopLoadingListener);
|
||||
this.removeListener('destroyed', stopLoadingListener);
|
||||
};
|
||||
this.on('did-finish-load', finishListener);
|
||||
this.on('did-fail-load', failListener);
|
||||
this.on('did-navigate-in-page', finishListener);
|
||||
this.on('did-start-navigation', navigationListener);
|
||||
this.on('did-stop-loading', stopLoadingListener);
|
||||
this.on('destroyed', stopLoadingListener);
|
||||
|
||||
@@ -7,7 +7,7 @@ import { webViewEvents } from '@electron/internal/browser/web-view-events';
|
||||
import { IPC_MESSAGES } from '@electron/internal/common/ipc-messages';
|
||||
|
||||
interface GuestInstance {
|
||||
elementInstanceId?: number;
|
||||
elementInstanceId: number;
|
||||
visibilityState?: VisibilityState;
|
||||
embedder: Electron.WebContents;
|
||||
guest: Electron.WebContents;
|
||||
@@ -46,6 +46,7 @@ function makeWebPreferences (embedder: Electron.WebContents, params: Record<stri
|
||||
webSecurity: !params.disablewebsecurity,
|
||||
enableBlinkFeatures: params.blinkfeatures,
|
||||
disableBlinkFeatures: params.disableblinkfeatures,
|
||||
partition: params.partition,
|
||||
...parsedWebPreferences
|
||||
};
|
||||
|
||||
@@ -87,14 +88,26 @@ function makeLoadURLOptions (params: Record<string, any>) {
|
||||
|
||||
// Create a new guest instance.
|
||||
const createGuest = function (embedder: Electron.WebContents, embedderFrameId: number, elementInstanceId: number, params: Record<string, any>) {
|
||||
const webPreferences = makeWebPreferences(embedder, params);
|
||||
const event = eventBinding.createWithSender(embedder);
|
||||
|
||||
const { instanceId } = params;
|
||||
|
||||
embedder.emit('will-attach-webview', event, webPreferences, params);
|
||||
if (event.defaultPrevented) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-undef
|
||||
const guest = (webContents as typeof ElectronInternal.WebContents).create({
|
||||
...webPreferences,
|
||||
type: 'webview',
|
||||
partition: params.partition,
|
||||
embedder
|
||||
});
|
||||
|
||||
const guestInstanceId = guest.id;
|
||||
guestInstances.set(guestInstanceId, {
|
||||
elementInstanceId,
|
||||
guest,
|
||||
embedder
|
||||
});
|
||||
@@ -108,11 +121,8 @@ const createGuest = function (embedder: Electron.WebContents, embedderFrameId: n
|
||||
|
||||
// Init guest web view after attached.
|
||||
guest.once('did-attach' as any, function (this: Electron.WebContents, event: Electron.Event) {
|
||||
const params = this.attachParams!;
|
||||
delete this.attachParams;
|
||||
|
||||
const previouslyAttached = this.viewInstanceId != null;
|
||||
this.viewInstanceId = params.instanceId;
|
||||
this.viewInstanceId = instanceId;
|
||||
|
||||
// Only load URL and set size on first attach
|
||||
if (previouslyAttached) {
|
||||
@@ -120,7 +130,7 @@ const createGuest = function (embedder: Electron.WebContents, embedderFrameId: n
|
||||
}
|
||||
|
||||
if (params.src) {
|
||||
this.loadURL(params.src, params.opts);
|
||||
this.loadURL(params.src, makeLoadURLOptions(params));
|
||||
}
|
||||
embedder.emit('did-attach-webview', event, guest);
|
||||
});
|
||||
@@ -173,78 +183,25 @@ const createGuest = function (embedder: Electron.WebContents, embedderFrameId: n
|
||||
}
|
||||
});
|
||||
|
||||
if (attachGuest(embedder, embedderFrameId, elementInstanceId, guestInstanceId, params)) {
|
||||
return guestInstanceId;
|
||||
}
|
||||
|
||||
return -1;
|
||||
};
|
||||
|
||||
// Attach the guest to an element of embedder.
|
||||
const attachGuest = function (embedder: Electron.WebContents, embedderFrameId: number, elementInstanceId: number, guestInstanceId: number, params: Record<string, any>) {
|
||||
// Destroy the old guest when attaching.
|
||||
const key = `${embedder.id}-${elementInstanceId}`;
|
||||
const oldGuestInstanceId = embedderElementsMap.get(key);
|
||||
if (oldGuestInstanceId != null) {
|
||||
// Reattachment to the same guest is just a no-op.
|
||||
if (oldGuestInstanceId === guestInstanceId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const oldGuestInstance = guestInstances.get(oldGuestInstanceId);
|
||||
if (oldGuestInstance) {
|
||||
oldGuestInstance.guest.detachFromOuterFrame();
|
||||
}
|
||||
}
|
||||
|
||||
const guestInstance = guestInstances.get(guestInstanceId);
|
||||
// If this isn't a valid guest instance then do nothing.
|
||||
if (!guestInstance) {
|
||||
console.error(new Error(`Guest attach failed: Invalid guestInstanceId ${guestInstanceId}`));
|
||||
return false;
|
||||
}
|
||||
const { guest } = guestInstance;
|
||||
if (guest.hostWebContents !== embedder) {
|
||||
console.error(new Error(`Guest attach failed: Access denied to guestInstanceId ${guestInstanceId}`));
|
||||
return false;
|
||||
}
|
||||
|
||||
const { instanceId } = params;
|
||||
|
||||
// If this guest is already attached to an element then remove it
|
||||
if (guestInstance.elementInstanceId) {
|
||||
const oldKey = `${guestInstance.embedder.id}-${guestInstance.elementInstanceId}`;
|
||||
embedderElementsMap.delete(oldKey);
|
||||
|
||||
// Remove guest from embedder if moving across web views
|
||||
if (guest.viewInstanceId !== instanceId) {
|
||||
webViewManager.removeGuest(guestInstance.embedder, guestInstanceId);
|
||||
guestInstance.embedder._sendInternal(`${IPC_MESSAGES.GUEST_VIEW_INTERNAL_DESTROY_GUEST}-${guest.viewInstanceId}`);
|
||||
}
|
||||
}
|
||||
|
||||
const webPreferences = makeWebPreferences(embedder, params);
|
||||
|
||||
const event = eventBinding.createWithSender(embedder);
|
||||
embedder.emit('will-attach-webview', event, webPreferences, params);
|
||||
if (event.defaultPrevented) {
|
||||
if (guest.viewInstanceId == null) guest.viewInstanceId = instanceId;
|
||||
guest.destroy();
|
||||
return false;
|
||||
}
|
||||
|
||||
guest.attachParams = { instanceId, src: params.src, opts: makeLoadURLOptions(params) };
|
||||
embedderElementsMap.set(key, guestInstanceId);
|
||||
|
||||
guest.setEmbedder(embedder);
|
||||
guestInstance.embedder = embedder;
|
||||
guestInstance.elementInstanceId = elementInstanceId;
|
||||
|
||||
watchEmbedder(embedder);
|
||||
|
||||
webViewManager.addGuest(guestInstanceId, embedder, guest, webPreferences);
|
||||
guest.attachToIframe(embedder, embedderFrameId);
|
||||
return true;
|
||||
|
||||
return guestInstanceId;
|
||||
};
|
||||
|
||||
// Remove an guest-embedder relationship.
|
||||
|
||||
23
lib/common/.eslintrc.json
Normal file
23
lib/common/.eslintrc.json
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"rules": {
|
||||
"no-restricted-imports": [
|
||||
"error",
|
||||
{
|
||||
"paths": [
|
||||
"electron",
|
||||
"electron/main",
|
||||
"electron/renderer"
|
||||
],
|
||||
"patterns": [
|
||||
"./*",
|
||||
"../*",
|
||||
"@electron/internal/browser/*",
|
||||
"@electron/internal/isolated_renderer/*",
|
||||
"@electron/internal/renderer/*",
|
||||
"@electron/internal/sandboxed_worker/*",
|
||||
"@electron/internal/worker/*"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
import { IPC_MESSAGES } from '@electron/internal/common/ipc-messages';
|
||||
|
||||
// eslint-disable-next-line no-restricted-imports
|
||||
import type * as ipcRendererUtilsModule from '@electron/internal/renderer/ipc-renderer-internal-utils';
|
||||
|
||||
const clipboard = process._linkedBinding('electron_common_clipboard');
|
||||
|
||||
@@ -9,7 +9,6 @@ export const enum IPC_MESSAGES {
|
||||
|
||||
GUEST_INSTANCE_VISIBILITY_CHANGE = 'GUEST_INSTANCE_VISIBILITY_CHANGE',
|
||||
|
||||
GUEST_VIEW_INTERNAL_DESTROY_GUEST = 'GUEST_VIEW_INTERNAL_DESTROY_GUEST',
|
||||
GUEST_VIEW_INTERNAL_DISPATCH_EVENT = 'GUEST_VIEW_INTERNAL_DISPATCH_EVENT',
|
||||
|
||||
GUEST_VIEW_MANAGER_CREATE_AND_ATTACH_GUEST = 'GUEST_VIEW_MANAGER_CREATE_AND_ATTACH_GUEST',
|
||||
|
||||
18
lib/isolated_renderer/.eslintrc.json
Normal file
18
lib/isolated_renderer/.eslintrc.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"rules": {
|
||||
"no-restricted-imports": [
|
||||
"error",
|
||||
{
|
||||
"paths": [
|
||||
"electron",
|
||||
"electron/main"
|
||||
],
|
||||
"patterns": [
|
||||
"./*",
|
||||
"../*",
|
||||
"@electron/internal/browser/*"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
18
lib/renderer/.eslintrc.json
Normal file
18
lib/renderer/.eslintrc.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"rules": {
|
||||
"no-restricted-imports": [
|
||||
"error",
|
||||
{
|
||||
"paths": [
|
||||
"electron",
|
||||
"electron/main"
|
||||
],
|
||||
"patterns": [
|
||||
"./*",
|
||||
"../*",
|
||||
"@electron/internal/browser/*"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ipcRenderer } from 'electron';
|
||||
import { ipcRenderer } from 'electron/renderer';
|
||||
import { ipcRendererInternal } from '@electron/internal/renderer/ipc-renderer-internal';
|
||||
|
||||
import type * as webViewInitModule from '@electron/internal/renderer/web-view/web-view-init';
|
||||
|
||||
@@ -2,7 +2,7 @@ import { internalContextBridge } from '@electron/internal/renderer/api/context-b
|
||||
import { ipcRendererInternal } from '@electron/internal/renderer/ipc-renderer-internal';
|
||||
import * as ipcRendererUtils from '@electron/internal/renderer/ipc-renderer-internal-utils';
|
||||
import { webFrame } from 'electron/renderer';
|
||||
import { IPC_MESSAGES } from '../common/ipc-messages';
|
||||
import { IPC_MESSAGES } from '@electron/internal/common/ipc-messages';
|
||||
|
||||
const { contextIsolationEnabled } = internalContextBridge;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { webFrame, WebFrame } from 'electron';
|
||||
import { webFrame, WebFrame } from 'electron/renderer';
|
||||
import * as ipcRendererUtils from '@electron/internal/renderer/ipc-renderer-internal-utils';
|
||||
import { IPC_MESSAGES } from '@electron/internal/common/ipc-messages';
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@ const { mainFrame: webFrame } = process._linkedBinding('electron_renderer_web_fr
|
||||
|
||||
export interface GuestViewDelegate {
|
||||
dispatchEvent (eventName: string, props: Record<string, any>): void;
|
||||
reset(): void;
|
||||
}
|
||||
|
||||
const DEPRECATED_EVENTS: Record<string, string> = {
|
||||
@@ -14,11 +13,6 @@ const DEPRECATED_EVENTS: Record<string, string> = {
|
||||
} as const;
|
||||
|
||||
export function registerEvents (viewInstanceId: number, delegate: GuestViewDelegate) {
|
||||
ipcRendererInternal.on(`${IPC_MESSAGES.GUEST_VIEW_INTERNAL_DESTROY_GUEST}-${viewInstanceId}`, function () {
|
||||
delegate.reset();
|
||||
delegate.dispatchEvent('destroyed', {});
|
||||
});
|
||||
|
||||
ipcRendererInternal.on(`${IPC_MESSAGES.GUEST_VIEW_INTERNAL_DISPATCH_EVENT}-${viewInstanceId}`, function (event, eventName, props) {
|
||||
if (DEPRECATED_EVENTS[eventName] != null) {
|
||||
delegate.dispatchEvent(DEPRECATED_EVENTS[eventName], props);
|
||||
@@ -29,7 +23,6 @@ export function registerEvents (viewInstanceId: number, delegate: GuestViewDeleg
|
||||
}
|
||||
|
||||
export function deregisterEvents (viewInstanceId: number) {
|
||||
ipcRendererInternal.removeAllListeners(`${IPC_MESSAGES.GUEST_VIEW_INTERNAL_DESTROY_GUEST}-${viewInstanceId}`);
|
||||
ipcRendererInternal.removeAllListeners(`${IPC_MESSAGES.GUEST_VIEW_INTERNAL_DISPATCH_EVENT}-${viewInstanceId}`);
|
||||
}
|
||||
|
||||
|
||||
@@ -186,7 +186,10 @@ export class SrcAttribute extends WebViewAttribute {
|
||||
opts.userAgent = useragent;
|
||||
}
|
||||
|
||||
(this.webViewImpl.webviewNode as Electron.WebviewTag).loadURL(this.getValue(), opts);
|
||||
(this.webViewImpl.webviewNode as Electron.WebviewTag).loadURL(this.getValue(), opts)
|
||||
.catch(err => {
|
||||
console.error('Unexpected error while loading URL', err);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -55,8 +55,7 @@ const defineWebViewElement = (hooks: WebViewImplHooks) => {
|
||||
}
|
||||
if (!internal.elementAttached) {
|
||||
hooks.guestViewInternal.registerEvents(internal.viewInstanceId, {
|
||||
dispatchEvent: internal.dispatchEvent.bind(internal),
|
||||
reset: internal.reset.bind(internal)
|
||||
dispatchEvent: internal.dispatchEvent.bind(internal)
|
||||
});
|
||||
internal.elementAttached = true;
|
||||
(internal.attributes.get(WEB_VIEW_CONSTANTS.ATTRIBUTE_SRC) as SrcAttribute).parse();
|
||||
|
||||
@@ -191,7 +191,7 @@ export class WebViewImpl {
|
||||
|
||||
attachGuestInstance (guestInstanceId: number) {
|
||||
if (guestInstanceId === -1) {
|
||||
// Do nothing
|
||||
this.dispatchEvent('destroyed');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
18
lib/sandboxed_renderer/.eslintrc.json
Normal file
18
lib/sandboxed_renderer/.eslintrc.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"rules": {
|
||||
"no-restricted-imports": [
|
||||
"error",
|
||||
{
|
||||
"paths": [
|
||||
"electron",
|
||||
"electron/main"
|
||||
],
|
||||
"patterns": [
|
||||
"./*",
|
||||
"../*",
|
||||
"@electron/internal/browser/*"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
18
lib/worker/.eslintrc.json
Normal file
18
lib/worker/.eslintrc.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"rules": {
|
||||
"no-restricted-imports": [
|
||||
"error",
|
||||
{
|
||||
"paths": [
|
||||
"electron",
|
||||
"electron/main"
|
||||
],
|
||||
"patterns": [
|
||||
"./*",
|
||||
"../*",
|
||||
"@electron/internal/browser/*"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -70,8 +70,30 @@ function isInstalled () {
|
||||
|
||||
// unzips and makes path.txt point at the correct executable
|
||||
function extractFile (zipPath) {
|
||||
return extract(zipPath, { dir: path.join(__dirname, 'dist') })
|
||||
.then(() => fs.promises.writeFile(path.join(__dirname, 'path.txt'), platformPath));
|
||||
return new Promise((resolve, reject) => {
|
||||
const distPath = process.env.ELECTRON_OVERRIDE_DIST_PATH || path.join(__dirname, 'dist');
|
||||
|
||||
extract(zipPath, { dir: path.join(__dirname, 'dist') })
|
||||
.then(() => {
|
||||
// If the zip contains an "electron.d.ts" file,
|
||||
// move that up
|
||||
const srcTypeDefPath = path.join(distPath, 'electron.d.ts');
|
||||
const targetTypeDefPath = path.join(__dirname, 'electron.d.ts');
|
||||
const hasTypeDefinitions = fs.existsSync(srcTypeDefPath);
|
||||
|
||||
if (hasTypeDefinitions) {
|
||||
try {
|
||||
fs.renameSync(srcTypeDefPath, targetTypeDefPath);
|
||||
} catch (err) {
|
||||
reject(err);
|
||||
}
|
||||
}
|
||||
|
||||
// Write a "path.txt" file.
|
||||
return fs.promises.writeFile(path.join(__dirname, 'path.txt'), platformPath);
|
||||
})
|
||||
.catch((err) => reject(err));
|
||||
});
|
||||
}
|
||||
|
||||
function getPlatformPath () {
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
{
|
||||
"name": "electron",
|
||||
"version": "20.0.0-beta.10",
|
||||
"version": "0.0.0-development",
|
||||
"repository": "https://github.com/electron/electron",
|
||||
"description": "Build cross platform desktop apps with JavaScript, HTML, and CSS",
|
||||
"devDependencies": {
|
||||
"@azure/storage-blob": "^12.9.0",
|
||||
"@electron/asar": "^3.2.1",
|
||||
"@electron/docs-parser": "^0.12.4",
|
||||
"@electron/typescript-definitions": "^8.9.5",
|
||||
"@octokit/auth-app": "^2.10.0",
|
||||
@@ -31,7 +32,6 @@
|
||||
"@types/webpack-env": "^1.16.3",
|
||||
"@typescript-eslint/eslint-plugin": "^4.4.1",
|
||||
"@typescript-eslint/parser": "^4.4.1",
|
||||
"asar": "^3.1.0",
|
||||
"aws-sdk": "^2.814.0",
|
||||
"check-for-leaks": "^1.2.1",
|
||||
"colors": "1.4.0",
|
||||
@@ -146,4 +146,4 @@
|
||||
"resolutions": {
|
||||
"nan": "nodejs/nan#16fa32231e2ccd89d2804b3f765319128b20c4ac"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
1
patches/angle/.patches
Normal file
1
patches/angle/.patches
Normal file
@@ -0,0 +1 @@
|
||||
cherry-pick-b8636b57b8f2.patch
|
||||
46
patches/angle/cherry-pick-b8636b57b8f2.patch
Normal file
46
patches/angle/cherry-pick-b8636b57b8f2.patch
Normal file
@@ -0,0 +1,46 @@
|
||||
From b8636b57b8f231994ecb3fb14f181c593c83a3fb Mon Sep 17 00:00:00 2001
|
||||
From: Jamie Madill <jmadill@chromium.org>
|
||||
Date: Mon, 29 Aug 2022 16:25:46 -0400
|
||||
Subject: [PATCH] [M106] Vulkan: Ensure we sync the draw FB before beingQuery.
|
||||
|
||||
Bug: chromium:1354271
|
||||
(cherry picked from commit 4ebdac790c76b65abf5703bcef9482c638076195)
|
||||
Change-Id: I7b715a9c28badfe58a0ae1a478d2b4e8bbd23c47
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3956939
|
||||
Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
|
||||
---
|
||||
|
||||
diff --git a/src/libANGLE/State.h b/src/libANGLE/State.h
|
||||
index 168104e..2f498d3 100644
|
||||
--- a/src/libANGLE/State.h
|
||||
+++ b/src/libANGLE/State.h
|
||||
@@ -603,6 +603,11 @@
|
||||
|
||||
bool isRobustResourceInitEnabled() const { return mRobustResourceInit; }
|
||||
|
||||
+ bool isDrawFramebufferBindingDirty() const
|
||||
+ {
|
||||
+ return mDirtyBits.test(DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING);
|
||||
+ }
|
||||
+
|
||||
// Sets the dirty bit for the program executable.
|
||||
angle::Result onProgramExecutableChange(const Context *context, Program *program);
|
||||
// Sets the dirty bit for the program pipeline executable.
|
||||
diff --git a/src/libANGLE/renderer/vulkan/QueryVk.cpp b/src/libANGLE/renderer/vulkan/QueryVk.cpp
|
||||
index 9f475e6..6ef5f72 100644
|
||||
--- a/src/libANGLE/renderer/vulkan/QueryVk.cpp
|
||||
+++ b/src/libANGLE/renderer/vulkan/QueryVk.cpp
|
||||
@@ -303,6 +303,13 @@
|
||||
{
|
||||
ContextVk *contextVk = vk::GetImpl(context);
|
||||
|
||||
+ // Ensure that we start with the right RenderPass when we begin a new query.
|
||||
+ if (contextVk->getState().isDrawFramebufferBindingDirty())
|
||||
+ {
|
||||
+ ANGLE_TRY(contextVk->flushCommandsAndEndRenderPass(
|
||||
+ RenderPassClosureReason::FramebufferBindingChange));
|
||||
+ }
|
||||
+
|
||||
mCachedResultValid = false;
|
||||
|
||||
// Transform feedback query is handled by a CPU-calculated value when emulated.
|
||||
@@ -113,3 +113,28 @@ feat_filter_out_non-shareable_windows_in_the_current_application_in.patch
|
||||
posix_replace_doubleforkandexec_with_forkandspawn.patch
|
||||
fix_allow_guest_webcontents_to_enter_fullscreen.patch
|
||||
disable_freezing_flags_after_init_in_node.patch
|
||||
chore_add_electron_deps_to_gitignores.patch
|
||||
chore_allow_chromium_to_handle_synthetic_mouse_events_for_touch.patch
|
||||
add_maximized_parameter_to_linuxui_getwindowframeprovider.patch
|
||||
fix_mac_build_with_enable_plugins_false.patch
|
||||
fix_windows_build_with_enable_plugins_false.patch
|
||||
remove_default_window_title.patch
|
||||
add_electron_deps_to_license_credits_file.patch
|
||||
feat_add_set_can_resize_mutator.patch
|
||||
cherry-pick-2083e894852c.patch
|
||||
cherry-pick-51daffbf5cd8.patch
|
||||
dpwa_enable_window_controls_overlay_by_default.patch
|
||||
create_browser_v8_snapshot_file_name_fuse.patch
|
||||
cherry-pick-fefd6198da31.patch
|
||||
cherry-pick-1eb1e18ad41d.patch
|
||||
cherry-pick-05a0d99c9715.patch
|
||||
cherry-pick-c83640db21b5.patch
|
||||
fix_on-screen-keyboard_hides_on_input_blur_in_webview.patch
|
||||
cherry-pick-65f0ef609c00.patch
|
||||
cherry-pick-cb9dff93f3d4.patch
|
||||
build_fix_building_with_enable_plugins_false.patch
|
||||
build_allow_electron_to_use_exec_script.patch
|
||||
cherry-pick-d5ffb4dd4112.patch
|
||||
cherry-pick-933cc81c6bad.patch
|
||||
cherry-pick-06c87f9f42ff.patch
|
||||
cherry-pick-67c9cbc784d6.patch
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Charles Kerr <charles@charleskerr.com>
|
||||
Date: Tue, 9 Aug 2022 12:35:36 -0500
|
||||
Subject: add electron deps to license credits file
|
||||
|
||||
Ensure that licenses for the dependencies introduced by Electron
|
||||
are included in `LICENSES.chromium.html`
|
||||
|
||||
diff --git a/tools/licenses.py b/tools/licenses.py
|
||||
index a58dbf44370baabbfa2986c734c96a210cc16f1d..1d6934460f788ab76275710e727fb062f5c92b5b 100755
|
||||
--- a/tools/licenses.py
|
||||
+++ b/tools/licenses.py
|
||||
@@ -347,6 +347,32 @@ SPECIAL_CASES = {
|
||||
"License File":
|
||||
"/third_party/swiftshader/third_party/SPIRV-Headers/LICENSE",
|
||||
},
|
||||
+
|
||||
+ os.path.join('third_party', 'electron_node'): {
|
||||
+ "Name": "Node.js",
|
||||
+ "URL": "https://github.com/nodejs/node",
|
||||
+ "License": "MIT",
|
||||
+ "License File": "/third_party/electron_node/LICENSE",
|
||||
+ },
|
||||
+ os.path.join('third_party', 'squirrel.mac'): {
|
||||
+ "Name": "Squirrel",
|
||||
+ "URL": "https://github.com/Squirrel/Squirrel.Mac",
|
||||
+ "License": "MIT",
|
||||
+ "License File": "/third_party/squirrel.mac/LICENSE",
|
||||
+ },
|
||||
+ os.path.join('third_party', 'squirrel.mac', 'vendor', 'mantle'): {
|
||||
+ "Name": "Mantle",
|
||||
+ "URL": "https://github.com/Mantle/Mantle",
|
||||
+ "License": "MIT",
|
||||
+ "License File": "/third_party/squirrel.mac/vendor/mantle/LICENSE.md",
|
||||
+ },
|
||||
+ os.path.join('third_party', 'squirrel.mac', 'vendor', 'ReactiveObjC'): {
|
||||
+ "Name": "ReactiveObjC",
|
||||
+ "URL": "https://github.com/ReactiveCocoa/ReactiveObjC",
|
||||
+ "License": "MIT",
|
||||
+ "License File":
|
||||
+ "/third_party/squirrel.mac/vendor/ReactiveObjC/LICENSE.md",
|
||||
+ },
|
||||
}
|
||||
|
||||
# Special value for 'License File' field used to indicate that the license file
|
||||
@@ -0,0 +1,176 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: msizanoen1 <msizanoen@qtmlabs.xyz>
|
||||
Date: Tue, 19 Jul 2022 05:11:06 +0200
|
||||
Subject: Add maximized parameter to LinuxUI::GetWindowFrameProvider
|
||||
|
||||
This allows ClientFrameViewLinux to instruct the toolkit to draw the window
|
||||
decorations in maximized mode where needed, preventing empty space caused
|
||||
by decoration shadows and rounded titlebars around the window while maximized.
|
||||
|
||||
diff --git a/ui/gtk/gtk_ui.cc b/ui/gtk/gtk_ui.cc
|
||||
index 12193ad9090de969b81fa6aa6bed9520aea5bae1..99ea60219b39a6864bdea45ba0917316bff7f2d9 100644
|
||||
--- a/ui/gtk/gtk_ui.cc
|
||||
+++ b/ui/gtk/gtk_ui.cc
|
||||
@@ -556,13 +556,15 @@ std::unique_ptr<views::NavButtonProvider> GtkUi::CreateNavButtonProvider() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
-views::WindowFrameProvider* GtkUi::GetWindowFrameProvider(bool solid_frame) {
|
||||
+views::WindowFrameProvider* GtkUi::GetWindowFrameProvider(bool solid_frame, bool maximized) {
|
||||
if (!GtkCheckVersion(3, 14))
|
||||
return nullptr;
|
||||
auto& provider =
|
||||
- solid_frame ? solid_frame_provider_ : transparent_frame_provider_;
|
||||
+ maximized
|
||||
+ ? (solid_frame ? solid_maximized_frame_provider_ : transparent_maximized_frame_provider_)
|
||||
+ : (solid_frame ? solid_frame_provider_ : transparent_frame_provider_);
|
||||
if (!provider)
|
||||
- provider = std::make_unique<gtk::WindowFrameProviderGtk>(solid_frame);
|
||||
+ provider = std::make_unique<gtk::WindowFrameProviderGtk>(solid_frame, maximized);
|
||||
return provider.get();
|
||||
}
|
||||
|
||||
diff --git a/ui/gtk/gtk_ui.h b/ui/gtk/gtk_ui.h
|
||||
index 65f9d6c81804d1b0efb88ced4a9c80c000ba0f5a..35d851a054a2b2f9887c77a9faaf16ce1aa363b9 100644
|
||||
--- a/ui/gtk/gtk_ui.h
|
||||
+++ b/ui/gtk/gtk_ui.h
|
||||
@@ -89,7 +89,7 @@ class GtkUi : public views::LinuxUI {
|
||||
bool PreferDarkTheme() const override;
|
||||
bool AnimationsEnabled() const override;
|
||||
std::unique_ptr<views::NavButtonProvider> CreateNavButtonProvider() override;
|
||||
- views::WindowFrameProvider* GetWindowFrameProvider(bool solid_frame) override;
|
||||
+ views::WindowFrameProvider* GetWindowFrameProvider(bool solid_frame, bool maximized) override;
|
||||
base::flat_map<std::string, std::string> GetKeyboardLayoutMap() override;
|
||||
std::string GetCursorThemeName() override;
|
||||
int GetCursorThemeSize() override;
|
||||
@@ -188,6 +188,8 @@ class GtkUi : public views::LinuxUI {
|
||||
// while Chrome is running.
|
||||
std::unique_ptr<views::WindowFrameProvider> solid_frame_provider_;
|
||||
std::unique_ptr<views::WindowFrameProvider> transparent_frame_provider_;
|
||||
+ std::unique_ptr<views::WindowFrameProvider> solid_maximized_frame_provider_;
|
||||
+ std::unique_ptr<views::WindowFrameProvider> transparent_maximized_frame_provider_;
|
||||
};
|
||||
|
||||
} // namespace gtk
|
||||
diff --git a/ui/gtk/window_frame_provider_gtk.cc b/ui/gtk/window_frame_provider_gtk.cc
|
||||
index e4dbdad327eb77994ffd7f068c67336a19897915..d3ae0636455489a7c7443df85cb769952c98aca2 100644
|
||||
--- a/ui/gtk/window_frame_provider_gtk.cc
|
||||
+++ b/ui/gtk/window_frame_provider_gtk.cc
|
||||
@@ -38,16 +38,18 @@ std::string GetThemeName() {
|
||||
return theme_string;
|
||||
}
|
||||
|
||||
-GtkCssContext WindowContext(bool solid_frame, bool focused) {
|
||||
+GtkCssContext WindowContext(bool solid_frame, bool maximized, bool focused) {
|
||||
std::string selector = "#window.background.";
|
||||
selector += solid_frame ? "solid-csd" : "csd";
|
||||
+ if (maximized)
|
||||
+ selector += ".maximized";
|
||||
if (!focused)
|
||||
selector += ":inactive";
|
||||
return AppendCssNodeToStyleContext({}, selector);
|
||||
}
|
||||
|
||||
-GtkCssContext DecorationContext(bool solid_frame, bool focused) {
|
||||
- auto context = WindowContext(solid_frame, focused);
|
||||
+GtkCssContext DecorationContext(bool solid_frame, bool maximized, bool focused) {
|
||||
+ auto context = WindowContext(solid_frame, maximized, focused);
|
||||
// GTK4 renders the decoration directly on the window.
|
||||
if (!GtkCheckVersion(4))
|
||||
context = AppendCssNodeToStyleContext(context, "#decoration");
|
||||
@@ -64,8 +66,8 @@ GtkCssContext DecorationContext(bool solid_frame, bool focused) {
|
||||
return context;
|
||||
}
|
||||
|
||||
-GtkCssContext HeaderContext(bool solid_frame, bool focused) {
|
||||
- auto context = WindowContext(solid_frame, focused);
|
||||
+GtkCssContext HeaderContext(bool solid_frame, bool maximized, bool focused) {
|
||||
+ auto context = WindowContext(solid_frame, maximized, focused);
|
||||
context =
|
||||
AppendCssNodeToStyleContext(context, "#headerbar.header-bar.titlebar");
|
||||
if (!focused)
|
||||
@@ -110,8 +112,8 @@ int ComputeTopCornerRadius() {
|
||||
// need to experimentally determine the corner radius by rendering a sample.
|
||||
// Additionally, in GTK4, the headerbar corners get clipped by the window
|
||||
// rather than the headerbar having its own rounded corners.
|
||||
- auto context = GtkCheckVersion(4) ? DecorationContext(false, false)
|
||||
- : HeaderContext(false, false);
|
||||
+ auto context = GtkCheckVersion(4) ? DecorationContext(false, false, false)
|
||||
+ : HeaderContext(false, false, false);
|
||||
ApplyCssToContext(context, R"(window, headerbar {
|
||||
background-image: none;
|
||||
background-color: black;
|
||||
@@ -169,8 +171,8 @@ void WindowFrameProviderGtk::Asset::CloneFrom(
|
||||
unfocused_bitmap = src.unfocused_bitmap;
|
||||
}
|
||||
|
||||
-WindowFrameProviderGtk::WindowFrameProviderGtk(bool solid_frame)
|
||||
- : solid_frame_(solid_frame) {}
|
||||
+WindowFrameProviderGtk::WindowFrameProviderGtk(bool solid_frame, bool maximized)
|
||||
+ : solid_frame_(solid_frame), maximized_(maximized) {}
|
||||
|
||||
WindowFrameProviderGtk::~WindowFrameProviderGtk() = default;
|
||||
|
||||
@@ -264,7 +266,7 @@ void WindowFrameProviderGtk::PaintWindowFrame(gfx::Canvas* canvas,
|
||||
top_area_height_dip * scale - asset.frame_thickness_px.top();
|
||||
|
||||
auto header = PaintHeaderbar({client_bounds_px.width(), top_area_height_px},
|
||||
- HeaderContext(solid_frame_, focused), scale);
|
||||
+ HeaderContext(solid_frame_, maximized_, focused), scale);
|
||||
image = gfx::ImageSkia::CreateFrom1xBitmap(header);
|
||||
// In GTK4, the headerbar gets clipped by the window.
|
||||
if (GtkCheckVersion(4)) {
|
||||
@@ -296,7 +298,7 @@ void WindowFrameProviderGtk::MaybeUpdateBitmaps(float scale) {
|
||||
|
||||
gfx::Rect frame_bounds_dip(kMaxFrameSizeDip, kMaxFrameSizeDip,
|
||||
2 * kMaxFrameSizeDip, 2 * kMaxFrameSizeDip);
|
||||
- auto focused_context = DecorationContext(solid_frame_, true);
|
||||
+ auto focused_context = DecorationContext(solid_frame_, maximized_, true);
|
||||
frame_bounds_dip.Inset(-GtkStyleContextGetPadding(focused_context));
|
||||
frame_bounds_dip.Inset(-GtkStyleContextGetBorder(focused_context));
|
||||
gfx::Size bitmap_size(BitmapSizePx(asset), BitmapSizePx(asset));
|
||||
@@ -304,7 +306,7 @@ void WindowFrameProviderGtk::MaybeUpdateBitmaps(float scale) {
|
||||
PaintBitmap(bitmap_size, frame_bounds_dip, focused_context, scale);
|
||||
asset.unfocused_bitmap =
|
||||
PaintBitmap(bitmap_size, frame_bounds_dip,
|
||||
- DecorationContext(solid_frame_, false), scale);
|
||||
+ DecorationContext(solid_frame_, maximized_, false), scale);
|
||||
|
||||
// In GTK4, there's no way to obtain the frame thickness from CSS values
|
||||
// directly, so we must determine it experimentally based on the drawn
|
||||
diff --git a/ui/gtk/window_frame_provider_gtk.h b/ui/gtk/window_frame_provider_gtk.h
|
||||
index d3039d73161378197557947aece88d2710c1e486..f7d4605938210b0b75517bb7bcab28b588a16520 100644
|
||||
--- a/ui/gtk/window_frame_provider_gtk.h
|
||||
+++ b/ui/gtk/window_frame_provider_gtk.h
|
||||
@@ -14,7 +14,7 @@ namespace gtk {
|
||||
|
||||
class WindowFrameProviderGtk : public views::WindowFrameProvider {
|
||||
public:
|
||||
- explicit WindowFrameProviderGtk(bool solid_frame);
|
||||
+ explicit WindowFrameProviderGtk(bool solid_frame, bool maximized);
|
||||
|
||||
WindowFrameProviderGtk(const WindowFrameProviderGtk&) = delete;
|
||||
WindowFrameProviderGtk& operator=(const WindowFrameProviderGtk&) = delete;
|
||||
@@ -69,6 +69,9 @@ class WindowFrameProviderGtk : public views::WindowFrameProvider {
|
||||
|
||||
// Cached bitmaps and metrics. The scale is rounded to percent.
|
||||
base::flat_map<int, Asset> assets_;
|
||||
+
|
||||
+ // Whether to draw the window decorations as maximized.
|
||||
+ bool maximized_;
|
||||
};
|
||||
|
||||
} // namespace gtk
|
||||
diff --git a/ui/views/linux_ui/linux_ui.h b/ui/views/linux_ui/linux_ui.h
|
||||
index 7d59a2c9ff87cf9d8cb3ed0b45e34e2831545d28..a6ae4feec8df8f149a9ebbe1c3d2252db73135db 100644
|
||||
--- a/ui/views/linux_ui/linux_ui.h
|
||||
+++ b/ui/views/linux_ui/linux_ui.h
|
||||
@@ -170,7 +170,7 @@ class VIEWS_EXPORT LinuxUI : public ui::LinuxInputMethodContextFactory,
|
||||
// if transparency is unsupported and the frame should be rendered opaque.
|
||||
// The returned object is not owned by the caller and will remain alive until
|
||||
// the process ends.
|
||||
- virtual WindowFrameProvider* GetWindowFrameProvider(bool solid_frame) = 0;
|
||||
+ virtual WindowFrameProvider* GetWindowFrameProvider(bool solid_frame, bool maximized) = 0;
|
||||
|
||||
// Returns a map of KeyboardEvent code to KeyboardEvent key values.
|
||||
virtual base::flat_map<std::string, std::string> GetKeyboardLayoutMap() = 0;
|
||||
@@ -0,0 +1,18 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Samuel Attard <sattard@salesforce.com>
|
||||
Date: Fri, 21 Oct 2022 16:29:06 -0700
|
||||
Subject: build: allow electron to use exec_script
|
||||
|
||||
This is similar to the //build usecase so we're OK adding ourselves here
|
||||
|
||||
diff --git a/.gn b/.gn
|
||||
index 7d538f812d72e0937e7a031e1c53651c352149c5..1cad40a9825f3c6df67dbcc12d2f9650aad809b2 100644
|
||||
--- a/.gn
|
||||
+++ b/.gn
|
||||
@@ -169,4 +169,6 @@ exec_script_whitelist =
|
||||
|
||||
"//tools/grit/grit_rule.gni",
|
||||
"//tools/gritsettings/BUILD.gn",
|
||||
+
|
||||
+ "//electron/BUILD.gn"
|
||||
]
|
||||
@@ -46,10 +46,10 @@ index bbe8847b3da8d6ec9c5d10bbe875de8c34e060d3..e2e12c141932f52f49d24a0bad4a5300
|
||||
sources += [ "certificate_viewer_stub.cc" ]
|
||||
}
|
||||
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
|
||||
index cd30ea6c938860837d7427fee851974b0ec5831b..d88eb38a8ce9a0f607b85e7efe40fe23f6ab5f08 100644
|
||||
index e791e09b43760ecc3aac9af7bac252233e6bae0b..baacf6bf01fa9df05bd9c2d87d3519666f41fc77 100644
|
||||
--- a/chrome/test/BUILD.gn
|
||||
+++ b/chrome/test/BUILD.gn
|
||||
@@ -5912,7 +5912,6 @@ test("unit_tests") {
|
||||
@@ -5913,7 +5913,6 @@ test("unit_tests") {
|
||||
|
||||
deps += [
|
||||
"//chrome:other_version",
|
||||
@@ -57,7 +57,7 @@ index cd30ea6c938860837d7427fee851974b0ec5831b..d88eb38a8ce9a0f607b85e7efe40fe23
|
||||
"//chrome//services/util_win:unit_tests",
|
||||
"//chrome/app:chrome_dll_resources",
|
||||
"//chrome/browser:chrome_process_finder",
|
||||
@@ -5936,6 +5935,10 @@ test("unit_tests") {
|
||||
@@ -5937,6 +5936,10 @@ test("unit_tests") {
|
||||
"//ui/resources",
|
||||
]
|
||||
|
||||
@@ -68,7 +68,7 @@ index cd30ea6c938860837d7427fee851974b0ec5831b..d88eb38a8ce9a0f607b85e7efe40fe23
|
||||
ldflags = [
|
||||
"/DELAYLOAD:api-ms-win-core-winrt-error-l1-1-0.dll",
|
||||
"/DELAYLOAD:api-ms-win-core-winrt-l1-1-0.dll",
|
||||
@@ -6826,7 +6829,6 @@ test("unit_tests") {
|
||||
@@ -6827,7 +6830,6 @@ test("unit_tests") {
|
||||
}
|
||||
|
||||
deps += [
|
||||
@@ -76,7 +76,7 @@ index cd30ea6c938860837d7427fee851974b0ec5831b..d88eb38a8ce9a0f607b85e7efe40fe23
|
||||
"//chrome/browser:cart_db_content_proto",
|
||||
"//chrome/browser:coupon_db_content_proto",
|
||||
"//chrome/browser/media/router:test_support",
|
||||
@@ -6932,6 +6934,10 @@ test("unit_tests") {
|
||||
@@ -6933,6 +6935,10 @@ test("unit_tests") {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Milan Burda <miburda@microsoft.com>
|
||||
Date: Sun, 30 Oct 2022 22:32:39 +0100
|
||||
Subject: build: fix building with enable_plugins = false
|
||||
|
||||
This issue is fixed in latest Chromium
|
||||
|
||||
diff --git a/tools/ipc_fuzzer/message_lib/BUILD.gn b/tools/ipc_fuzzer/message_lib/BUILD.gn
|
||||
index 00618d9f81cabd5084218431658fd91d22fb4208..26be64a51fc5767e0ee97681a0b3f2dfd74159fe 100644
|
||||
--- a/tools/ipc_fuzzer/message_lib/BUILD.gn
|
||||
+++ b/tools/ipc_fuzzer/message_lib/BUILD.gn
|
||||
@@ -3,6 +3,7 @@
|
||||
# found in the LICENSE file.
|
||||
|
||||
import("//components/nacl/features.gni")
|
||||
+import("//ppapi/buildflags/buildflags.gni")
|
||||
import("//remoting/remoting_enable.gni")
|
||||
|
||||
static_library("ipc_message_lib") {
|
||||
@@ -22,7 +23,6 @@ static_library("ipc_message_lib") {
|
||||
"//ipc",
|
||||
"//media/cast:net",
|
||||
"//media/gpu/ipc/common",
|
||||
- "//ppapi/proxy:ipc",
|
||||
"//skia",
|
||||
"//third_party/blink/public:blink",
|
||||
"//third_party/blink/public:blink_headers",
|
||||
@@ -49,4 +49,7 @@ static_library("ipc_message_lib") {
|
||||
if (enable_remoting) {
|
||||
public_deps += [ "//remoting/host" ]
|
||||
}
|
||||
+ if (enable_plugins) {
|
||||
+ public_deps += [ "//ppapi/proxy:ipc" ]
|
||||
+ }
|
||||
}
|
||||
@@ -9,10 +9,10 @@ potentially prevent a window from being created.
|
||||
TODO(loc): this patch is currently broken.
|
||||
|
||||
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc
|
||||
index b857d325233430a5b79b3022d33823486e558309..83cc6ded4b3354f37b8e1dc0d9e4f3289863fa09 100644
|
||||
index 28c7136b21d058e3daa7570af558f5a415b000a7..d1b7d15a7e4dede5b030e4ae9fb2ab8aa8196446 100644
|
||||
--- a/content/browser/renderer_host/render_frame_host_impl.cc
|
||||
+++ b/content/browser/renderer_host/render_frame_host_impl.cc
|
||||
@@ -6966,6 +6966,7 @@ void RenderFrameHostImpl::CreateNewWindow(
|
||||
@@ -7006,6 +7006,7 @@ void RenderFrameHostImpl::CreateNewWindow(
|
||||
last_committed_origin_, params->window_container_type,
|
||||
params->target_url, params->referrer.To<Referrer>(),
|
||||
params->frame_name, params->disposition, *params->features,
|
||||
@@ -21,10 +21,10 @@ index b857d325233430a5b79b3022d33823486e558309..83cc6ded4b3354f37b8e1dc0d9e4f328
|
||||
&no_javascript_access);
|
||||
|
||||
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
|
||||
index 33f6efe4df4eecabcbcd08f908ed3ef12d056eb2..0e1e25d40ebf3ca92c57dfdfb52c5269198aa6f7 100644
|
||||
index cb74ef64fc8d4014fb57f098df6440dda5e896d4..c7d376b31e0fb570c934c6a8846e37bf1f3b3262 100644
|
||||
--- a/content/browser/web_contents/web_contents_impl.cc
|
||||
+++ b/content/browser/web_contents/web_contents_impl.cc
|
||||
@@ -3947,6 +3947,14 @@ FrameTree* WebContentsImpl::CreateNewWindow(
|
||||
@@ -3965,6 +3965,14 @@ FrameTree* WebContentsImpl::CreateNewWindow(
|
||||
}
|
||||
auto* new_contents_impl = new_contents.get();
|
||||
|
||||
@@ -39,7 +39,7 @@ index 33f6efe4df4eecabcbcd08f908ed3ef12d056eb2..0e1e25d40ebf3ca92c57dfdfb52c5269
|
||||
new_contents_impl->GetController().SetSessionStorageNamespace(
|
||||
partition_config, session_storage_namespace);
|
||||
|
||||
@@ -3991,12 +3999,6 @@ FrameTree* WebContentsImpl::CreateNewWindow(
|
||||
@@ -4009,12 +4017,6 @@ FrameTree* WebContentsImpl::CreateNewWindow(
|
||||
AddWebContentsDestructionObserver(new_contents_impl);
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ index 9c3a03faeee19f6f0a250680db36906ee64bf55a..0450700d02c74e047fa5124aa43b9f75
|
||||
|
||||
// Operation result when the renderer asks the browser to create a new window.
|
||||
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc
|
||||
index 69bcd725d0f86bf3b175fde86bd2dbd85b59f002..b72d89b19024a9074108dde4c5c9cd0f45b719bb 100644
|
||||
index c1beba6701e68255c212e56d78ae8259e2ffdab9..9f77c2a5df8f25876f875c4a7148d82c3dd79db8 100644
|
||||
--- a/content/public/browser/content_browser_client.cc
|
||||
+++ b/content/public/browser/content_browser_client.cc
|
||||
@@ -595,6 +595,8 @@ bool ContentBrowserClient::CanCreateWindow(
|
||||
@@ -81,7 +81,7 @@ index 69bcd725d0f86bf3b175fde86bd2dbd85b59f002..b72d89b19024a9074108dde4c5c9cd0f
|
||||
bool opener_suppressed,
|
||||
bool* no_javascript_access) {
|
||||
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h
|
||||
index d0b7aed3162b8ea7673ab3ef31d2a3302f4e6456..6328fc21548f2b8277b461f9938dbcc50f6853f1 100644
|
||||
index a49794184baa977ddf03cd911f8d8d7d671df65f..7997c0de85315e30b350316f33e598a0221d583f 100644
|
||||
--- a/content/public/browser/content_browser_client.h
|
||||
+++ b/content/public/browser/content_browser_client.h
|
||||
@@ -164,6 +164,7 @@ class NetworkService;
|
||||
|
||||
34
patches/chromium/cherry-pick-05a0d99c9715.patch
Normal file
34
patches/chromium/cherry-pick-05a0d99c9715.patch
Normal file
@@ -0,0 +1,34 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: David Bokan <bokan@chromium.org>
|
||||
Date: Thu, 28 Jul 2022 18:09:13 +0000
|
||||
Subject: Prevent handling input for provisional frames
|
||||
|
||||
Bug: 1347644,1322812
|
||||
Change-Id: Ifd60f6aa593ce23ca6cbb65552fc9fb8f8690035
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3791883
|
||||
Commit-Queue: David Bokan <bokan@chromium.org>
|
||||
Reviewed-by: Dave Tapuska <dtapuska@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/main@{#1029361}
|
||||
|
||||
diff --git a/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc b/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc
|
||||
index fe775337fbc22817d7489df143821eea2d9425ec..13a241273090e54fabdba9d82510e36d2386c4a4 100644
|
||||
--- a/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc
|
||||
+++ b/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc
|
||||
@@ -2460,10 +2460,15 @@ WebInputEventResult WebFrameWidgetImpl::HandleInputEvent(
|
||||
DCHECK(!WebInputEvent::IsTouchEventType(input_event.GetType()));
|
||||
CHECK(LocalRootImpl());
|
||||
|
||||
+ // Clients shouldn't be dispatching events to a provisional frame but this
|
||||
+ // can happen. Ensure that event handling can assume we're in a committed
|
||||
+ // frame.
|
||||
+ if (IsProvisional())
|
||||
+ return WebInputEventResult::kHandledSuppressed;
|
||||
+
|
||||
// Only record metrics for the root frame.
|
||||
- if (ForTopMostMainFrame()) {
|
||||
+ if (ForTopMostMainFrame())
|
||||
GetPage()->GetVisualViewport().StartTrackingPinchStats();
|
||||
- }
|
||||
|
||||
// If a drag-and-drop operation is in progress, ignore input events except
|
||||
// PointerCancel and GestureLongPress.
|
||||
153
patches/chromium/cherry-pick-06c87f9f42ff.patch
Normal file
153
patches/chromium/cherry-pick-06c87f9f42ff.patch
Normal file
@@ -0,0 +1,153 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Rune Lillesveen <futhark@chromium.org>
|
||||
Date: Fri, 14 Oct 2022 09:52:34 +0000
|
||||
Subject: Avoid layout roots in subtrees skipped for style recalc
|
||||
|
||||
Layout roots are laid out from inner to outer in LocalFrameView. DOM
|
||||
mutations may have added layout roots inside size container subtrees
|
||||
before style recalc. If we decide to postpone style recalc until layout
|
||||
of the size container, it means we may try to layout a root inside a
|
||||
subtree skipped for style recalc. That causes a DCHECK and possibly
|
||||
other issues.
|
||||
|
||||
This also fixes the use-after-poison issue 1365330.
|
||||
|
||||
(cherry picked from commit 0f0f1e99201fadb3c68518350e1cd6af1b665346)
|
||||
|
||||
Bug: 1371820, 1365330
|
||||
Change-Id: Ia48890c08aacfe7b9a3e660817702abce0570564
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3934847
|
||||
Reviewed-by: Ian Kilpatrick <ikilpatrick@chromium.org>
|
||||
Commit-Queue: Rune Lillesveen <futhark@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1055853}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3953455
|
||||
Auto-Submit: Rune Lillesveen <futhark@chromium.org>
|
||||
Commit-Queue: Anders Hartvoll Ruud <andruud@chromium.org>
|
||||
Reviewed-by: Anders Hartvoll Ruud <andruud@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/5249@{#836}
|
||||
Cr-Branched-From: 4f7bea5de862aaa52e6bde5920755a9ef9db120b-refs/heads/main@{#1036826}
|
||||
|
||||
diff --git a/third_party/blink/renderer/core/css/style_engine.cc b/third_party/blink/renderer/core/css/style_engine.cc
|
||||
index f51b8878eb0abe23889a07277efeaf7cdf961cc8..ddcef20b47357e58acae08b4183db6187b046f80 100644
|
||||
--- a/third_party/blink/renderer/core/css/style_engine.cc
|
||||
+++ b/third_party/blink/renderer/core/css/style_engine.cc
|
||||
@@ -2808,6 +2808,7 @@ void StyleEngine::RecalcStyle(StyleRecalcChange change,
|
||||
const StyleRecalcContext& style_recalc_context) {
|
||||
DCHECK(GetDocument().documentElement());
|
||||
ScriptForbiddenScope forbid_script;
|
||||
+ SkipStyleRecalcScope skip_scope(*this);
|
||||
CheckPseudoHasCacheScope check_pseudo_has_cache_scope(&GetDocument());
|
||||
Element& root_element = style_recalc_root_.RootElement();
|
||||
Element* parent = FlatTreeTraversal::ParentElement(root_element);
|
||||
@@ -3400,4 +3401,17 @@ void StyleEngine::MarkForLayoutTreeChangesAfterDetach() {
|
||||
parent_for_detached_subtree_ = nullptr;
|
||||
}
|
||||
|
||||
+bool StyleEngine::AllowSkipStyleRecalcForScope() const {
|
||||
+ if (InContainerQueryStyleRecalc())
|
||||
+ return true;
|
||||
+ if (LocalFrameView* view = GetDocument().View()) {
|
||||
+ // Existing layout roots before starting style recalc may end up being
|
||||
+ // inside skipped subtrees if we allowed skipping. If we start out with an
|
||||
+ // empty list, any added ones will be a result of an element style recalc,
|
||||
+ // which means the will not be inside a skipped subtree.
|
||||
+ return !view->IsSubtreeLayout();
|
||||
+ }
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
} // namespace blink
|
||||
diff --git a/third_party/blink/renderer/core/css/style_engine.h b/third_party/blink/renderer/core/css/style_engine.h
|
||||
index a6c325b69e5bc43c657519f4c0730f6e2efd4f71..f7ccc6c2b7b306d76bba60cf46da91a5b291c29e 100644
|
||||
--- a/third_party/blink/renderer/core/css/style_engine.h
|
||||
+++ b/third_party/blink/renderer/core/css/style_engine.h
|
||||
@@ -178,6 +178,20 @@ class CORE_EXPORT StyleEngine final : public GarbageCollected<StyleEngine>,
|
||||
base::AutoReset<bool> allow_marking_;
|
||||
};
|
||||
|
||||
+ // Set up the condition for allowing to skip style recalc before starting
|
||||
+ // RecalcStyle().
|
||||
+ class SkipStyleRecalcScope {
|
||||
+ STACK_ALLOCATED();
|
||||
+
|
||||
+ public:
|
||||
+ explicit SkipStyleRecalcScope(StyleEngine& engine)
|
||||
+ : allow_skip_(&engine.allow_skip_style_recalc_,
|
||||
+ engine.AllowSkipStyleRecalcForScope()) {}
|
||||
+
|
||||
+ private:
|
||||
+ base::AutoReset<bool> allow_skip_;
|
||||
+ };
|
||||
+
|
||||
explicit StyleEngine(Document&);
|
||||
~StyleEngine() override;
|
||||
|
||||
@@ -342,6 +356,10 @@ class CORE_EXPORT StyleEngine final : public GarbageCollected<StyleEngine>,
|
||||
|
||||
bool MarkReattachAllowed() const;
|
||||
|
||||
+ // Returns true if we can skip style recalc for a size container subtree and
|
||||
+ // resume it during layout.
|
||||
+ bool SkipStyleRecalcAllowed() const { return allow_skip_style_recalc_; }
|
||||
+
|
||||
CSSFontSelector* GetFontSelector() { return font_selector_; }
|
||||
|
||||
void RemoveFontFaceRules(const HeapVector<Member<const StyleRuleFontFace>>&);
|
||||
@@ -743,6 +761,9 @@ class CORE_EXPORT StyleEngine final : public GarbageCollected<StyleEngine>,
|
||||
Element& changed_element,
|
||||
bool for_pseudo_change);
|
||||
|
||||
+ // Initialization value for SkipStyleRecalcScope.
|
||||
+ bool AllowSkipStyleRecalcForScope() const;
|
||||
+
|
||||
Member<Document> document_;
|
||||
|
||||
// Tracks the number of currently loading top-level stylesheets. Sheets loaded
|
||||
@@ -812,6 +833,9 @@ class CORE_EXPORT StyleEngine final : public GarbageCollected<StyleEngine>,
|
||||
// AllowMarkStyleDirtyFromRecalcScope.
|
||||
bool allow_mark_for_reattach_from_rebuild_layout_tree_{false};
|
||||
|
||||
+ // Set to true if we are allowed to skip recalc for a size container subtree.
|
||||
+ bool allow_skip_style_recalc_{false};
|
||||
+
|
||||
// See enum ViewportUnitFlag.
|
||||
unsigned viewport_unit_dirty_flags_{0};
|
||||
|
||||
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc
|
||||
index 8e5c4aab2e37ed0acda0ef56273d007fbaa58780..2df360c33c54e12af341b77771fcda95e562fa92 100644
|
||||
--- a/third_party/blink/renderer/core/dom/element.cc
|
||||
+++ b/third_party/blink/renderer/core/dom/element.cc
|
||||
@@ -3532,6 +3532,10 @@ bool Element::SkipStyleRecalcForContainer(
|
||||
const ComputedStyle& style,
|
||||
const StyleRecalcChange& child_change) {
|
||||
DCHECK(RuntimeEnabledFeatures::CSSContainerSkipStyleRecalcEnabled());
|
||||
+
|
||||
+ if (!GetDocument().GetStyleEngine().SkipStyleRecalcAllowed())
|
||||
+ return false;
|
||||
+
|
||||
if (!child_change.TraversePseudoElements(*this)) {
|
||||
// If none of the children or pseudo elements need to be traversed for style
|
||||
// recalc, there is no point in marking the subtree as skipped.
|
||||
diff --git a/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/crashtests/chrome-layout-root-crash.html b/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/crashtests/chrome-layout-root-crash.html
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..e3e709a240bd870250b2747c94fe96880bdf52e3
|
||||
--- /dev/null
|
||||
+++ b/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/crashtests/chrome-layout-root-crash.html
|
||||
@@ -0,0 +1,17 @@
|
||||
+<!doctype html>
|
||||
+<html class="reftest-wait">
|
||||
+<link rel="help" href="https://crbug.com/1371820">
|
||||
+<style>
|
||||
+ body, div, img { container-type: size; }
|
||||
+</style>
|
||||
+<p>Pass if no crash.</p>
|
||||
+<div id="div"><img id="img" alt="a"></div>
|
||||
+<script>
|
||||
+ requestAnimationFrame(() => requestAnimationFrame(() => {
|
||||
+ // Adds a layout root inside the div size container.
|
||||
+ img.alt = img.src = "b";
|
||||
+ // Marks div size container for layout which skips style recalc for the sub-tree.
|
||||
+ div.style.width = "500px";
|
||||
+ document.documentElement.classList.remove("reftest-wait");
|
||||
+ }));
|
||||
+</script>
|
||||
184
patches/chromium/cherry-pick-1eb1e18ad41d.patch
Normal file
184
patches/chromium/cherry-pick-1eb1e18ad41d.patch
Normal file
@@ -0,0 +1,184 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Anders Hartvoll Ruud <andruud@chromium.org>
|
||||
Date: Tue, 20 Sep 2022 17:43:47 +0000
|
||||
Subject: Add CSSTokenizer-created strings to CSSVariableData's backing strings
|
||||
|
||||
When computing the value of a registered custom property, we create
|
||||
a CSSVariableData object equivalent to the computed CSSValue by
|
||||
serializing that CSSValue to a String, then tokenizing that value.
|
||||
|
||||
The problem is that CSSTokenizer can create *new* string objects
|
||||
during the tokenization process (see calls to CSSTokenizer::
|
||||
RegisterString), without communicating that fact to the call-site.
|
||||
|
||||
Therefore, this CL adds a way to access those strings so they can
|
||||
be added to the backing strings of the CSSVariableData.
|
||||
|
||||
Also added a DCHECK to verify that we don't have any tokens with
|
||||
non-backed string pointers.
|
||||
|
||||
Fixed: 1358907
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3892782
|
||||
Reviewed-by: Steinar H Gunderson <sesse@chromium.org>
|
||||
Commit-Queue: Anders Hartvoll Ruud <andruud@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1046868}
|
||||
Change-Id: Ifb6d194508e99030a5a3ed5fbad5496b7263bdc1
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3905727
|
||||
Auto-Submit: Anders Hartvoll Ruud <andruud@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/5249@{#518}
|
||||
Cr-Branched-From: 4f7bea5de862aaa52e6bde5920755a9ef9db120b-refs/heads/main@{#1036826}
|
||||
|
||||
diff --git a/third_party/blink/renderer/core/css/css_variable_data.cc b/third_party/blink/renderer/core/css/css_variable_data.cc
|
||||
index a2294cc70c59ac0357dddf0f7719cc3c09d23554..b3a61b312eb5f0360e8aa4cb706c60f0085fead9 100644
|
||||
--- a/third_party/blink/renderer/core/css/css_variable_data.cc
|
||||
+++ b/third_party/blink/renderer/core/css/css_variable_data.cc
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include "third_party/blink/renderer/core/css/css_variable_data.h"
|
||||
|
||||
+#include "base/containers/span.h"
|
||||
#include "third_party/blink/renderer/core/css/css_syntax_definition.h"
|
||||
#include "third_party/blink/renderer/core/css/parser/css_parser_context.h"
|
||||
#include "third_party/blink/renderer/platform/wtf/text/character_names.h"
|
||||
@@ -109,6 +110,51 @@ void CSSVariableData::ConsumeAndUpdateTokens(const CSSParserTokenRange& range) {
|
||||
UpdateTokens<UChar>(range, backing_string, tokens_);
|
||||
}
|
||||
|
||||
+#if EXPENSIVE_DCHECKS_ARE_ON()
|
||||
+
|
||||
+namespace {
|
||||
+
|
||||
+template <typename CharacterType>
|
||||
+bool IsSubspan(base::span<const CharacterType> inner,
|
||||
+ base::span<const CharacterType> outer) {
|
||||
+ // Note that base::span uses CheckedContiguousIterator, which restricts
|
||||
+ // which comparisons are allowed. Therefore we must avoid begin()/end() here.
|
||||
+ return inner.data() >= outer.data() &&
|
||||
+ (inner.data() + inner.size()) <= (outer.data() + outer.size());
|
||||
+}
|
||||
+
|
||||
+bool TokenValueIsBacked(const CSSParserToken& token,
|
||||
+ const String& backing_string) {
|
||||
+ StringView value = token.Value();
|
||||
+ if (value.Is8Bit() != backing_string.Is8Bit())
|
||||
+ return false;
|
||||
+ return value.Is8Bit() ? IsSubspan(value.Span8(), backing_string.Span8())
|
||||
+ : IsSubspan(value.Span16(), backing_string.Span16());
|
||||
+}
|
||||
+
|
||||
+bool TokenValueIsBacked(const CSSParserToken& token,
|
||||
+ const Vector<String>& backing_strings) {
|
||||
+ DCHECK(token.HasStringBacking());
|
||||
+ for (const String& backing_string : backing_strings) {
|
||||
+ if (TokenValueIsBacked(token, backing_string)) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ }
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
+} // namespace
|
||||
+
|
||||
+void CSSVariableData::VerifyStringBacking() const {
|
||||
+ for (const CSSParserToken& token : tokens_) {
|
||||
+ DCHECK(!token.HasStringBacking() ||
|
||||
+ TokenValueIsBacked(token, backing_strings_))
|
||||
+ << "Token value is not backed: " << token.Value().ToString();
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+#endif // EXPENSIVE_DCHECKS_ARE_ON()
|
||||
+
|
||||
CSSVariableData::CSSVariableData(const CSSTokenizedValue& tokenized_value,
|
||||
bool is_animation_tainted,
|
||||
bool needs_variable_resolution,
|
||||
@@ -120,6 +166,9 @@ CSSVariableData::CSSVariableData(const CSSTokenizedValue& tokenized_value,
|
||||
base_url_(base_url.IsValid() ? base_url.GetString() : String()),
|
||||
charset_(charset) {
|
||||
ConsumeAndUpdateTokens(tokenized_value.range);
|
||||
+#if EXPENSIVE_DCHECKS_ARE_ON()
|
||||
+ VerifyStringBacking();
|
||||
+#endif // EXPENSIVE_DCHECKS_ARE_ON()
|
||||
}
|
||||
|
||||
const CSSValue* CSSVariableData::ParseForSyntax(
|
||||
diff --git a/third_party/blink/renderer/core/css/css_variable_data.h b/third_party/blink/renderer/core/css/css_variable_data.h
|
||||
index f042f85736c2c49f8337c29cb742976c5e97a14b..7be7d201313ec3e591e2c45c9fd5bda327856645 100644
|
||||
--- a/third_party/blink/renderer/core/css/css_variable_data.h
|
||||
+++ b/third_party/blink/renderer/core/css/css_variable_data.h
|
||||
@@ -100,11 +100,18 @@ class CORE_EXPORT CSSVariableData : public RefCounted<CSSVariableData> {
|
||||
has_font_units_(has_font_units),
|
||||
has_root_font_units_(has_root_font_units),
|
||||
base_url_(base_url),
|
||||
- charset_(charset) {}
|
||||
+ charset_(charset) {
|
||||
+#if EXPENSIVE_DCHECKS_ARE_ON()
|
||||
+ VerifyStringBacking();
|
||||
+#endif // EXPENSIVE_DCHECKS_ARE_ON()
|
||||
+ }
|
||||
CSSVariableData(const CSSVariableData&) = delete;
|
||||
CSSVariableData& operator=(const CSSVariableData&) = delete;
|
||||
|
||||
void ConsumeAndUpdateTokens(const CSSParserTokenRange&);
|
||||
+#if EXPENSIVE_DCHECKS_ARE_ON()
|
||||
+ void VerifyStringBacking() const;
|
||||
+#endif // EXPENSIVE_DCHECKS_ARE_ON()
|
||||
|
||||
// tokens_ may have raw pointers to string data, we store the String objects
|
||||
// owning that data in backing_strings_ to keep it alive alongside the
|
||||
diff --git a/third_party/blink/renderer/core/css/parser/css_tokenizer.h b/third_party/blink/renderer/core/css/parser/css_tokenizer.h
|
||||
index 817bcbd4b6b9a9a5519bb92d6870c5b16a19278f..682a44a478bcd0ee3aa1638601650fd420033625 100644
|
||||
--- a/third_party/blink/renderer/core/css/parser/css_tokenizer.h
|
||||
+++ b/third_party/blink/renderer/core/css/parser/css_tokenizer.h
|
||||
@@ -33,6 +33,7 @@ class CORE_EXPORT CSSTokenizer {
|
||||
wtf_size_t Offset() const { return input_.Offset(); }
|
||||
wtf_size_t PreviousOffset() const { return prev_offset_; }
|
||||
StringView StringRangeAt(wtf_size_t start, wtf_size_t length) const;
|
||||
+ const Vector<String>& StringPool() const { return string_pool_; }
|
||||
|
||||
private:
|
||||
CSSParserToken TokenizeSingle();
|
||||
diff --git a/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc b/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc
|
||||
index 6739b9de4b500d6173c04966905e26f856594502..f0082d88d70d4ea76604cfac77c09727de134f2a 100644
|
||||
--- a/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc
|
||||
+++ b/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc
|
||||
@@ -2176,6 +2176,10 @@ StyleBuilderConverter::ConvertRegisteredPropertyVariableData(
|
||||
|
||||
Vector<String> backing_strings;
|
||||
backing_strings.push_back(text);
|
||||
+ // CSSTokenizer may allocate new strings for some tokens (e.g. for escapes)
|
||||
+ // and produce tokens that point to those strings. We need to retain those
|
||||
+ // strings (if any) as well.
|
||||
+ backing_strings.AppendVector(tokenizer.StringPool());
|
||||
|
||||
const bool has_font_units = false;
|
||||
const bool has_root_font_units = false;
|
||||
diff --git a/third_party/blink/web_tests/external/wpt/css/css-properties-values-api/registered-property-computation.html b/third_party/blink/web_tests/external/wpt/css/css-properties-values-api/registered-property-computation.html
|
||||
index f03b257246e520bd93055203a5cb27188babc8ca..168495247a3b16a2203fb361f662b6db83044d09 100644
|
||||
--- a/third_party/blink/web_tests/external/wpt/css/css-properties-values-api/registered-property-computation.html
|
||||
+++ b/third_party/blink/web_tests/external/wpt/css/css-properties-values-api/registered-property-computation.html
|
||||
@@ -167,4 +167,6 @@ test_computed_value('<resolution>', '1dppx', '1dppx');
|
||||
test_computed_value('<resolution>', '96dpi', '1dppx');
|
||||
test_computed_value('<resolution>', 'calc(1dppx + 96dpi)', '2dppx');
|
||||
|
||||
+test_computed_value('*', 'url(why)', 'url(why)');
|
||||
+
|
||||
</script>
|
||||
diff --git a/third_party/blink/web_tests/platform/generic/external/wpt/css/css-properties-values-api/registered-property-computation-expected.txt b/third_party/blink/web_tests/platform/generic/external/wpt/css/css-properties-values-api/registered-property-computation-expected.txt
|
||||
index 3823a752b99f506d11c50aee36474c6c51c849cd..eeed0dfc0def17b1ba636f7f6a076caf770e1327 100644
|
||||
--- a/third_party/blink/web_tests/platform/generic/external/wpt/css/css-properties-values-api/registered-property-computation-expected.txt
|
||||
+++ b/third_party/blink/web_tests/platform/generic/external/wpt/css/css-properties-values-api/registered-property-computation-expected.txt
|
||||
@@ -1,5 +1,5 @@
|
||||
This is a testharness.js-based test.
|
||||
-Found 60 tests; 59 PASS, 1 FAIL, 0 TIMEOUT, 0 NOTRUN.
|
||||
+Found 61 tests; 60 PASS, 1 FAIL, 0 TIMEOUT, 0 NOTRUN.
|
||||
PASS <length> values computed are correctly via var()-reference
|
||||
PASS <length> values computed are correctly via var()-reference when font-size is inherited
|
||||
PASS <length> values are computed correctly when font-size is inherited [14em]
|
||||
@@ -60,5 +60,6 @@ PASS * values are computed correctly [50dpi]
|
||||
PASS <resolution> values are computed correctly [1dppx]
|
||||
PASS <resolution> values are computed correctly [96dpi]
|
||||
FAIL <resolution> values are computed correctly [calc(1dppx + 96dpi)] assert_equals: expected "2dppx" but got "0dppx"
|
||||
+PASS * values are computed correctly [url(why)]
|
||||
Harness: the test ran to completion.
|
||||
|
||||
29
patches/chromium/cherry-pick-2083e894852c.patch
Normal file
29
patches/chromium/cherry-pick-2083e894852c.patch
Normal file
@@ -0,0 +1,29 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Anton Bikineev <bikineev@chromium.org>
|
||||
Date: Sun, 10 Jul 2022 22:17:03 +0000
|
||||
Subject: Fix heap-overflow in blink::TableLayoutAlgorithmAuto::InsertSpanCell
|
||||
|
||||
The CL fixes size confusion between Member<> and raw pointers.
|
||||
|
||||
The bug was found (and the fix was proposed) by m.cooolie@gmail.com.
|
||||
|
||||
Bug: 1341539
|
||||
Change-Id: I99d524fd65c2d6305693d09ad274c23178271269
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3751138
|
||||
Reviewed-by: Kentaro Hara <haraken@chromium.org>
|
||||
Commit-Queue: Anton Bikineev <bikineev@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/main@{#1022529}
|
||||
|
||||
diff --git a/third_party/blink/renderer/core/layout/table_layout_algorithm_auto.cc b/third_party/blink/renderer/core/layout/table_layout_algorithm_auto.cc
|
||||
index 1e1575cf47027584a9d06d7c5f6046fa15990b10..1a4a06a4761c52b8dd9ae9052b7c51b9236694a5 100644
|
||||
--- a/third_party/blink/renderer/core/layout/table_layout_algorithm_auto.cc
|
||||
+++ b/third_party/blink/renderer/core/layout/table_layout_algorithm_auto.cc
|
||||
@@ -673,7 +673,7 @@ void TableLayoutAlgorithmAuto::InsertSpanCell(LayoutTableCell* cell) {
|
||||
span > span_cells_[pos]->ColSpan())
|
||||
pos++;
|
||||
memmove(span_cells_.data() + pos + 1, span_cells_.data() + pos,
|
||||
- (size - pos - 1) * sizeof(LayoutTableCell*));
|
||||
+ (size - pos - 1) * sizeof(decltype(span_cells_)::value_type));
|
||||
span_cells_[pos] = cell;
|
||||
}
|
||||
|
||||
45
patches/chromium/cherry-pick-51daffbf5cd8.patch
Normal file
45
patches/chromium/cherry-pick-51daffbf5cd8.patch
Normal file
@@ -0,0 +1,45 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Yutaka Hirano <yhirano@chromium.org>
|
||||
Date: Mon, 4 Jul 2022 11:48:20 +0000
|
||||
Subject: Fix UAF on network::URLLoader
|
||||
|
||||
network::URLLoader::SetUpUpload calls NotifyCompleted asynchronously,
|
||||
as it can be called in the constructor and we don't want to run
|
||||
NotifyCompleted in the constructor.
|
||||
|
||||
The problem is that it attaches a raw pointer to the method, which leads to a use-after-free problem if the URLLoader is destructed before
|
||||
NotifyCompleted is called.
|
||||
|
||||
Use weak pointers instead of raw pointers to avoid the problem.
|
||||
|
||||
Bug: 1340253
|
||||
Change-Id: Iacb1e772bf7a8e3de4a7bb9de342fea9ba0f3f3c
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3740150
|
||||
Reviewed-by: Kenichi Ishibashi <bashi@chromium.org>
|
||||
Commit-Queue: Yutaka Hirano <yhirano@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/main@{#1020539}
|
||||
|
||||
diff --git a/services/network/url_loader.cc b/services/network/url_loader.cc
|
||||
index 62201fd4f11ce500b3a9d82fffe7776bf8a15eb0..433edfd8be00d912ffe482283d0e0d1b093b8039 100644
|
||||
--- a/services/network/url_loader.cc
|
||||
+++ b/services/network/url_loader.cc
|
||||
@@ -989,8 +989,8 @@ void URLLoader::OpenFilesForUpload(const ResourceRequest& request) {
|
||||
// initializing before getting deleted.
|
||||
base::SequencedTaskRunnerHandle::Get()->PostTask(
|
||||
FROM_HERE,
|
||||
- base::BindOnce(&URLLoader::NotifyCompleted, base::Unretained(this),
|
||||
- net::ERR_ACCESS_DENIED));
|
||||
+ base::BindOnce(&URLLoader::NotifyCompleted,
|
||||
+ weak_ptr_factory_.GetWeakPtr(), net::ERR_ACCESS_DENIED));
|
||||
return;
|
||||
}
|
||||
url_request_->LogBlockedBy("Opening Files");
|
||||
@@ -1009,7 +1009,7 @@ void URLLoader::SetUpUpload(const ResourceRequest& request,
|
||||
// initializing before getting deleted.
|
||||
base::SequencedTaskRunnerHandle::Get()->PostTask(
|
||||
FROM_HERE, base::BindOnce(&URLLoader::NotifyCompleted,
|
||||
- base::Unretained(this), error_code));
|
||||
+ weak_ptr_factory_.GetWeakPtr(), error_code));
|
||||
return;
|
||||
}
|
||||
scoped_refptr<base::SequencedTaskRunner> task_runner =
|
||||
46
patches/chromium/cherry-pick-65f0ef609c00.patch
Normal file
46
patches/chromium/cherry-pick-65f0ef609c00.patch
Normal file
@@ -0,0 +1,46 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Andy Paicu <andypaicu@chromium.org>
|
||||
Date: Thu, 6 Oct 2022 21:04:23 +0000
|
||||
Subject: Fix UAF issue around permission status observer list
|
||||
|
||||
(cherry picked from commit 4df595127d95d4b0bf115be1ab4604d95b75273c)
|
||||
|
||||
(cherry picked from commit 1dc5dda6112bdd811c923520cc728a474583409e)
|
||||
|
||||
Bug: 1363040
|
||||
Change-Id: I1f64a901b83aa834ae652c8041456e9b7d253c1f
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3907744
|
||||
Reviewed-by: Kamila Hasanbega <hkamila@chromium.org>
|
||||
Commit-Queue: Andy Paicu <andypaicu@chromium.org>
|
||||
Cr-Original-Original-Commit-Position: refs/heads/main@{#1049058}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3929034
|
||||
Reviewed-by: Illia Klimov <elklm@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/branch-heads/5304@{#483}
|
||||
Cr-Original-Branched-From: 5d7b1fc9cb7103d9c82eed647cf4be38cf09738b-refs/heads/main@{#1047731}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3936291
|
||||
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
|
||||
Cr-Commit-Position: refs/branch-heads/5249@{#764}
|
||||
Cr-Branched-From: 4f7bea5de862aaa52e6bde5920755a9ef9db120b-refs/heads/main@{#1036826}
|
||||
|
||||
diff --git a/third_party/blink/renderer/modules/permissions/permission_status_listener.cc b/third_party/blink/renderer/modules/permissions/permission_status_listener.cc
|
||||
index 424314c1dd49bd693643e41adb537f7a9d01e5d2..946e28ac3139a1927ac36281f04cec9f5faf76d2 100644
|
||||
--- a/third_party/blink/renderer/modules/permissions/permission_status_listener.cc
|
||||
+++ b/third_party/blink/renderer/modules/permissions/permission_status_listener.cc
|
||||
@@ -62,7 +62,17 @@ void PermissionStatusListener::OnPermissionStatusChange(
|
||||
|
||||
status_ = status;
|
||||
|
||||
+ // The `observers_` list can change in response to permission status change
|
||||
+ // events as the observers map to PermissionStatus JS objects which can be
|
||||
+ // created and destroyed in the JS event handler function. To avoid UAF and
|
||||
+ // list modification issues, a temporary snapshot of the observers is made and
|
||||
+ // used instead.
|
||||
+ HeapHashSet<WeakMember<Observer>> observers;
|
||||
for (const auto& observer : observers_) {
|
||||
+ observers.insert(observer);
|
||||
+ }
|
||||
+
|
||||
+ for (const auto& observer : observers) {
|
||||
if (observer)
|
||||
observer->OnPermissionStatusChange(status);
|
||||
else
|
||||
622
patches/chromium/cherry-pick-67c9cbc784d6.patch
Normal file
622
patches/chromium/cherry-pick-67c9cbc784d6.patch
Normal file
@@ -0,0 +1,622 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Lukasz Anforowicz <lukasza@chromium.org>
|
||||
Date: Tue, 30 Aug 2022 19:18:15 +0000
|
||||
Subject: Validate `source_context` in ExtensionHostMsg_OpenChannelToNativeApp.
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
After this CL, the Browser process will verify `source_context` in the
|
||||
IPC payload of the ExtensionHostMsg_OpenChannelToNativeApp message and
|
||||
avoid processing malformed or spoofed IPCs.
|
||||
|
||||
Change-Id: I9466dc076c4d07dbb4bec38973000dc0418565f6
|
||||
Bug: 1356234
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3854987
|
||||
Commit-Queue: Łukasz Anforowicz <lukasza@chromium.org>
|
||||
Reviewed-by: Devlin Cronin <rdevlin.cronin@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/main@{#1041118}
|
||||
|
||||
diff --git a/chrome/browser/extensions/extension_security_exploit_browsertest.cc b/chrome/browser/extensions/extension_security_exploit_browsertest.cc
|
||||
index 19c9c52fa5a796c93e80f77029727d64acfdfa07..4e5215739f8533d25831f3302515861df179525f 100644
|
||||
--- a/chrome/browser/extensions/extension_security_exploit_browsertest.cc
|
||||
+++ b/chrome/browser/extensions/extension_security_exploit_browsertest.cc
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "base/memory/scoped_refptr.h"
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "base/test/bind.h"
|
||||
+#include "build/build_config.h"
|
||||
#include "chrome/browser/chrome_content_browser_client.h"
|
||||
#include "chrome/browser/extensions/extension_browsertest.h"
|
||||
#include "chrome/browser/extensions/extension_tab_util.h"
|
||||
@@ -40,6 +41,10 @@
|
||||
#include "third_party/blink/public/mojom/service_worker/service_worker_database.mojom-forward.h"
|
||||
#include "url/gurl.h"
|
||||
|
||||
+#if !(BUILDFLAG(IS_FUCHSIA))
|
||||
+#include "chrome/browser/extensions/api/messaging/native_messaging_test_util.h"
|
||||
+#endif
|
||||
+
|
||||
namespace extensions {
|
||||
|
||||
// Waits for a kill of the given RenderProcessHost and returns the
|
||||
@@ -233,6 +238,10 @@ class OpenChannelToExtensionExploitTest : public ExtensionBrowserTest {
|
||||
return ipc_message_waiter_->WaitForMessage();
|
||||
}
|
||||
|
||||
+ content::WebContents* active_web_contents() {
|
||||
+ return browser()->tab_strip_model()->GetActiveWebContents();
|
||||
+ }
|
||||
+
|
||||
// Asks the `extension_id` to inject `content_script` into `web_contents`.
|
||||
// Returns true if the content script execution started successfully.
|
||||
bool ExecuteProgrammaticContentScript(content::WebContents* web_contents,
|
||||
@@ -246,63 +255,86 @@ class OpenChannelToExtensionExploitTest : public ExtensionBrowserTest {
|
||||
browser()->profile(), extension_id, background_script);
|
||||
}
|
||||
|
||||
+ const Extension& active_extension() { return *active_extension_; }
|
||||
const ExtensionId& active_extension_id() { return active_extension_->id(); }
|
||||
|
||||
const ExtensionId& spoofed_extension_id() { return spoofed_extension_->id(); }
|
||||
|
||||
private:
|
||||
+ // Installs an `active_extension` and a separate, but otherwise identical
|
||||
+ // `spoofed_extension` (the only difference will be the extension id).
|
||||
void InstallTestExtensions() {
|
||||
- // Install an `active_extension` and a separate, but otherwise identical
|
||||
- // `spoofed_extension` (the only difference will be the extension id).
|
||||
- auto install_extension = [this](TestExtensionDir& dir) -> const Extension* {
|
||||
+ auto install_extension =
|
||||
+ [this](TestExtensionDir& dir,
|
||||
+ const char* extra_manifest_bits) -> const Extension* {
|
||||
const char kManifestTemplate[] = R"(
|
||||
{
|
||||
+ %s
|
||||
"name": "ContentScriptTrackerBrowserTest - Programmatic",
|
||||
"version": "1.0",
|
||||
"manifest_version": 2,
|
||||
- "permissions": [ "tabs", "<all_urls>" ],
|
||||
+ "permissions": [
|
||||
+ "tabs",
|
||||
+ "<all_urls>",
|
||||
+ "nativeMessaging"
|
||||
+ ],
|
||||
"background": {"scripts": ["background_script.js"]}
|
||||
} )";
|
||||
- dir.WriteManifest(kManifestTemplate);
|
||||
+ dir.WriteManifest(
|
||||
+ base::StringPrintf(kManifestTemplate, extra_manifest_bits));
|
||||
dir.WriteFile(FILE_PATH_LITERAL("background_script.js"), "");
|
||||
+ dir.WriteFile(FILE_PATH_LITERAL("page.html"), "<p>page</p>");
|
||||
return LoadExtension(dir.UnpackedPath());
|
||||
};
|
||||
- TestExtensionDir active_dir;
|
||||
- TestExtensionDir spoofed_dir;
|
||||
- active_extension_ = install_extension(active_dir);
|
||||
- spoofed_extension_ = install_extension(spoofed_dir);
|
||||
+#if !(BUILDFLAG(IS_FUCHSIA))
|
||||
+ // The key below corresponds to the extension ID used by
|
||||
+ // ScopedTestNativeMessagingHost::kExtensionId.
|
||||
+ const char kActiveExtensionKey[] = R"(
|
||||
+ "key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDcBHwzDvyBQ6bDppkIs9MP4ksKqCMyXQ/A52JivHZKh4YO/9vJsT3oaYhSpDCE9RPocOEQvwsHsFReW2nUEc6OLLyoCFFxIb7KkLGsmfakkut/fFdNJYh0xOTbSN8YvLWcqph09XAY2Y/f0AL7vfO1cuCqtkMt8hFrBGWxDdf9CQIDAQAB",
|
||||
+ )";
|
||||
+#else
|
||||
+ // Native messaging is not available on Fuchsia (i.e.
|
||||
+ // //chrome/browser/extensions/BUILD.gn excludes
|
||||
+ // api/messaging/native_messaging_test_util.h on Fuchsia).
|
||||
+ const char kActiveExtensionKey[] = "";
|
||||
+#endif
|
||||
+ active_extension_ = install_extension(active_dir_, kActiveExtensionKey);
|
||||
+ spoofed_extension_ = install_extension(spoofed_dir_, "");
|
||||
ASSERT_TRUE(active_extension_);
|
||||
ASSERT_TRUE(spoofed_extension_);
|
||||
+#if !(BUILDFLAG(IS_FUCHSIA))
|
||||
+ ASSERT_EQ(active_extension_id(),
|
||||
+ ScopedTestNativeMessagingHost::kExtensionId);
|
||||
+#endif
|
||||
ASSERT_NE(active_extension_id(), spoofed_extension_id());
|
||||
}
|
||||
|
||||
using OpenChannelMessageWaiter =
|
||||
ExtensionMessageWaiter<ExtensionHostMsg_OpenChannelToExtension>;
|
||||
- std::unique_ptr<OpenChannelMessageWaiter> StartInterceptingIpcs(
|
||||
- const GURL& test_page_url) {
|
||||
// Start capturing IPC messages in all future/new RenderProcessHosts.
|
||||
- auto ipc_message_waiter = std::make_unique<OpenChannelMessageWaiter>();
|
||||
+ ipc_message_waiter_ = std::make_unique<OpenChannelMessageWaiter>();
|
||||
|
||||
// Navigate to an arbitrary, mostly empty test page. Make sure that a new
|
||||
// RenderProcessHost is created to make sure it is covered by the
|
||||
- // `ipc_message_waiter`. (A WebUI -> http navigation should swap the
|
||||
+ // `ipc_message_waiter_`. (A WebUI -> http navigation should swap the
|
||||
// RenderProcessHost on all platforms.)
|
||||
- content::WebContents* web_contents =
|
||||
- browser()->tab_strip_model()->GetActiveWebContents();
|
||||
+ GURL test_page_url =
|
||||
+ embedded_test_server()->GetURL("foo.com", "/title1.html");
|
||||
int old_process_id =
|
||||
- web_contents->GetPrimaryMainFrame()->GetProcess()->GetID();
|
||||
+ active_web_contents()->GetPrimaryMainFrame()->GetProcess()->GetID();
|
||||
EXPECT_TRUE(
|
||||
ui_test_utils::NavigateToURL(browser(), GURL("chrome://version")));
|
||||
EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), test_page_url));
|
||||
int new_process_id =
|
||||
- web_contents->GetPrimaryMainFrame()->GetProcess()->GetID();
|
||||
+ active_web_contents()->GetPrimaryMainFrame()->GetProcess()->GetID();
|
||||
EXPECT_NE(old_process_id, new_process_id);
|
||||
|
||||
// Only intercept messages from `active_extension`'s content script running
|
||||
// in the main frame's process.
|
||||
std::string matching_extension_id = active_extension_id();
|
||||
- int matching_process_id = new_process_id;
|
||||
- ipc_message_waiter->SetIpcMatcher(base::BindLambdaForTesting(
|
||||
+ int matching_process_id =
|
||||
+ active_web_contents()->GetPrimaryMainFrame()->GetProcess()->GetID();
|
||||
+ ipc_message_waiter_->SetIpcMatcher(base::BindLambdaForTesting(
|
||||
[matching_extension_id, matching_process_id](
|
||||
int captured_render_process_id,
|
||||
const ExtensionHostMsg_OpenChannelToExtension::Param& param) {
|
||||
@@ -319,12 +351,19 @@ class OpenChannelToExtensionExploitTest : public ExtensionBrowserTest {
|
||||
|
||||
return true;
|
||||
}));
|
||||
+ }
|
||||
|
||||
- return ipc_message_waiter;
|
||||
+ // Waits for ExtensionHostMsg_OpenChannelToExtension IPC and returns its
|
||||
+ // payload.
|
||||
+ ExtensionHostMsg_OpenChannelToExtension::Param WaitForMessage() {
|
||||
+ return ipc_message_waiter_->WaitForMessage();
|
||||
}
|
||||
|
||||
+ private:
|
||||
std::unique_ptr<OpenChannelMessageWaiter> ipc_message_waiter_;
|
||||
|
||||
+ TestExtensionDir active_dir_;
|
||||
+ TestExtensionDir spoofed_dir_;
|
||||
raw_ptr<const Extension> active_extension_ = nullptr;
|
||||
raw_ptr<const Extension> spoofed_extension_ = nullptr;
|
||||
};
|
||||
@@ -340,24 +379,22 @@ IN_PROC_BROWSER_TEST_F(OpenChannelToExtensionExploitTest,
|
||||
|
||||
// Trigger sending of a valid ExtensionHostMsg_OpenChannelToExtension IPC
|
||||
// from a content script of an `active_extension_id`.
|
||||
- content::WebContents* web_contents =
|
||||
- browser()->tab_strip_model()->GetActiveWebContents();
|
||||
ASSERT_TRUE(ExecuteProgrammaticContentScript(
|
||||
- web_contents, active_extension_id(),
|
||||
+ active_web_contents(), active_extension_id(),
|
||||
"chrome.runtime.sendMessage({greeting: 'hello'}, (response) => {});"));
|
||||
|
||||
// Capture the IPC.
|
||||
auto [source_context, info, channel_name, port_id] = WaitForMessage();
|
||||
-
|
||||
- // Mutate the IPC payload.
|
||||
EXPECT_EQ(MessagingEndpoint::Type::kTab, info.source_endpoint.type);
|
||||
EXPECT_EQ(active_extension_id(), info.source_endpoint.extension_id);
|
||||
+
|
||||
+ // Mutate the IPC payload.
|
||||
info.source_endpoint.extension_id = spoofed_extension_id();
|
||||
|
||||
// Inject the malformed/mutated IPC and verify that the renderer is terminated
|
||||
// as expected.
|
||||
content::RenderProcessHost* main_frame_process =
|
||||
- web_contents->GetPrimaryMainFrame()->GetProcess();
|
||||
+ active_web_contents()->GetPrimaryMainFrame()->GetProcess();
|
||||
RenderProcessHostBadIpcMessageWaiter kill_waiter(main_frame_process);
|
||||
IPC::IpcSecurityTestUtil::PwnMessageReceived(
|
||||
main_frame_process->GetChannel(),
|
||||
@@ -371,24 +408,22 @@ IN_PROC_BROWSER_TEST_F(OpenChannelToExtensionExploitTest,
|
||||
FromContentScript_UnexpectedNativeAppType) {
|
||||
// Trigger sending of a valid ExtensionHostMsg_OpenChannelToExtension IPC
|
||||
// from a content script of an `active_extension_id`.
|
||||
- content::WebContents* web_contents =
|
||||
- browser()->tab_strip_model()->GetActiveWebContents();
|
||||
ASSERT_TRUE(ExecuteProgrammaticContentScript(
|
||||
- web_contents, active_extension_id(),
|
||||
+ active_web_contents(), active_extension_id(),
|
||||
"chrome.runtime.sendMessage({greeting: 'hello'}, (response) => {});"));
|
||||
|
||||
// Capture the IPC.
|
||||
auto [source_context, info, channel_name, port_id] = WaitForMessage();
|
||||
-
|
||||
- // Mutate the IPC payload.
|
||||
EXPECT_EQ(MessagingEndpoint::Type::kTab, info.source_endpoint.type);
|
||||
EXPECT_EQ(active_extension_id(), info.source_endpoint.extension_id);
|
||||
+
|
||||
+ // Mutate the IPC payload.
|
||||
info.source_endpoint.type = MessagingEndpoint::Type::kNativeApp;
|
||||
|
||||
// Inject the malformed/mutated IPC and verify that the renderer is terminated
|
||||
// as expected.
|
||||
content::RenderProcessHost* main_frame_process =
|
||||
- web_contents->GetPrimaryMainFrame()->GetProcess();
|
||||
+ active_web_contents()->GetPrimaryMainFrame()->GetProcess();
|
||||
RenderProcessHostBadIpcMessageWaiter kill_waiter(main_frame_process);
|
||||
IPC::IpcSecurityTestUtil::PwnMessageReceived(
|
||||
main_frame_process->GetChannel(),
|
||||
@@ -401,24 +436,22 @@ IN_PROC_BROWSER_TEST_F(OpenChannelToExtensionExploitTest,
|
||||
FromContentScript_UnexpectedExtensionType) {
|
||||
// Trigger sending of a valid ExtensionHostMsg_OpenChannelToExtension IPC
|
||||
// from a content script of an `active_extension_id`.
|
||||
- content::WebContents* web_contents =
|
||||
- browser()->tab_strip_model()->GetActiveWebContents();
|
||||
ASSERT_TRUE(ExecuteProgrammaticContentScript(
|
||||
- web_contents, active_extension_id(),
|
||||
+ active_web_contents(), active_extension_id(),
|
||||
"chrome.runtime.sendMessage({greeting: 'hello'}, (response) => {});"));
|
||||
|
||||
// Capture the IPC.
|
||||
auto [source_context, info, channel_name, port_id] = WaitForMessage();
|
||||
-
|
||||
- // Mutate the IPC payload.
|
||||
EXPECT_EQ(MessagingEndpoint::Type::kTab, info.source_endpoint.type);
|
||||
EXPECT_EQ(active_extension_id(), info.source_endpoint.extension_id);
|
||||
+
|
||||
+ // Mutate the IPC payload.
|
||||
info.source_endpoint.type = MessagingEndpoint::Type::kExtension;
|
||||
|
||||
// Inject the malformed/mutated IPC and verify that the renderer is terminated
|
||||
// as expected.
|
||||
content::RenderProcessHost* main_frame_process =
|
||||
- web_contents->GetPrimaryMainFrame()->GetProcess();
|
||||
+ active_web_contents()->GetPrimaryMainFrame()->GetProcess();
|
||||
RenderProcessHostBadIpcMessageWaiter kill_waiter(main_frame_process);
|
||||
IPC::IpcSecurityTestUtil::PwnMessageReceived(
|
||||
main_frame_process->GetChannel(),
|
||||
@@ -432,25 +465,23 @@ IN_PROC_BROWSER_TEST_F(OpenChannelToExtensionExploitTest,
|
||||
FromContentScript_NoExtensionIdForExtensionType) {
|
||||
// Trigger sending of a valid ExtensionHostMsg_OpenChannelToExtension IPC
|
||||
// from a content script of an `active_extension_id`.
|
||||
- content::WebContents* web_contents =
|
||||
- browser()->tab_strip_model()->GetActiveWebContents();
|
||||
ASSERT_TRUE(ExecuteProgrammaticContentScript(
|
||||
- web_contents, active_extension_id(),
|
||||
+ active_web_contents(), active_extension_id(),
|
||||
"chrome.runtime.sendMessage({greeting: 'hello'}, (response) => {});"));
|
||||
|
||||
// Capture the IPC.
|
||||
auto [source_context, info, channel_name, port_id] = WaitForMessage();
|
||||
-
|
||||
- // Mutate the IPC payload.
|
||||
EXPECT_EQ(MessagingEndpoint::Type::kTab, info.source_endpoint.type);
|
||||
EXPECT_EQ(active_extension_id(), info.source_endpoint.extension_id);
|
||||
+
|
||||
+ // Mutate the IPC payload.
|
||||
info.source_endpoint.type = MessagingEndpoint::Type::kExtension;
|
||||
info.source_endpoint.extension_id = absl::nullopt;
|
||||
|
||||
// Inject the malformed/mutated IPC and verify that the renderer is terminated
|
||||
// as expected.
|
||||
content::RenderProcessHost* main_frame_process =
|
||||
- web_contents->GetPrimaryMainFrame()->GetProcess();
|
||||
+ active_web_contents()->GetPrimaryMainFrame()->GetProcess();
|
||||
RenderProcessHostBadIpcMessageWaiter kill_waiter(main_frame_process);
|
||||
IPC::IpcSecurityTestUtil::PwnMessageReceived(
|
||||
main_frame_process->GetChannel(),
|
||||
@@ -464,18 +495,16 @@ IN_PROC_BROWSER_TEST_F(OpenChannelToExtensionExploitTest,
|
||||
FromContentScript_UnexpectedWorkerContext) {
|
||||
// Trigger sending of a valid ExtensionHostMsg_OpenChannelToExtension IPC
|
||||
// from a content script of an `active_extension_id`.
|
||||
- content::WebContents* web_contents =
|
||||
- browser()->tab_strip_model()->GetActiveWebContents();
|
||||
ASSERT_TRUE(ExecuteProgrammaticContentScript(
|
||||
- web_contents, active_extension_id(),
|
||||
+ active_web_contents(), active_extension_id(),
|
||||
"chrome.runtime.sendMessage({greeting: 'hello'}, (response) => {});"));
|
||||
|
||||
// Capture the IPC.
|
||||
auto [source_context, info, channel_name, port_id] = WaitForMessage();
|
||||
-
|
||||
- // Mutate the IPC payload.
|
||||
EXPECT_TRUE(source_context.is_for_render_frame());
|
||||
EXPECT_FALSE(source_context.is_for_service_worker());
|
||||
+
|
||||
+ // Mutate the IPC payload.
|
||||
source_context.frame = absl::nullopt;
|
||||
source_context.worker = PortContext::WorkerContext(
|
||||
/* thread_id = */ 123, /* version_id = */ 456,
|
||||
@@ -484,7 +513,7 @@ IN_PROC_BROWSER_TEST_F(OpenChannelToExtensionExploitTest,
|
||||
// Inject the malformed/mutated IPC and verify that the renderer is terminated
|
||||
// as expected.
|
||||
content::RenderProcessHost* main_frame_process =
|
||||
- web_contents->GetPrimaryMainFrame()->GetProcess();
|
||||
+ active_web_contents()->GetPrimaryMainFrame()->GetProcess();
|
||||
RenderProcessHostBadIpcMessageWaiter kill_waiter(main_frame_process);
|
||||
IPC::IpcSecurityTestUtil::PwnMessageReceived(
|
||||
main_frame_process->GetChannel(),
|
||||
@@ -494,4 +523,98 @@ IN_PROC_BROWSER_TEST_F(OpenChannelToExtensionExploitTest,
|
||||
kill_waiter.Wait());
|
||||
}
|
||||
|
||||
+// Native messaging is not available on Fuchsia (i.e.
|
||||
+// //chrome/browser/extensions/BUILD.gn excludes
|
||||
+// api/messaging/native_messaging_test_util.h on Fuchsia).
|
||||
+#if !(BUILDFLAG(IS_FUCHSIA))
|
||||
+
|
||||
+// Test suite for covering ExtensionHostMsg_OpenChannelToNativeApp IPC.
|
||||
+class OpenChannelToNativeAppExploitTest
|
||||
+ : public ExtensionSecurityExploitBrowserTest {
|
||||
+ public:
|
||||
+ OpenChannelToNativeAppExploitTest() = default;
|
||||
+
|
||||
+ using OpenChannelMessageWaiter =
|
||||
+ ExtensionMessageWaiter<ExtensionHostMsg_OpenChannelToNativeApp>;
|
||||
+ void SetUpOnMainThread() override {
|
||||
+ // Set up ExtensionMessageWaiter *before* installing the extensions (i.e.
|
||||
+ // *before* the corresponding RenderProcessHost objects are created).
|
||||
+ ipc_message_waiter_ = std::make_unique<OpenChannelMessageWaiter>();
|
||||
+
|
||||
+ // SetUpOnMainThread in the base class will install the test extensions.
|
||||
+ ExtensionSecurityExploitBrowserTest::SetUpOnMainThread();
|
||||
+
|
||||
+ // Register a (fake, test-only) native messaging host.
|
||||
+ test_native_messaging_host_.RegisterTestHost(/* user_level= */ false);
|
||||
+
|
||||
+ // Navigate the test tab to an extension page.
|
||||
+ GURL test_page_url = active_extension().GetResourceURL("page.html");
|
||||
+ EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), test_page_url));
|
||||
+
|
||||
+ // Only intercept messages from the test process.
|
||||
+ int matching_process_id =
|
||||
+ active_web_contents()->GetPrimaryMainFrame()->GetProcess()->GetID();
|
||||
+ ipc_message_waiter_->SetIpcMatcher(base::BindLambdaForTesting(
|
||||
+ [matching_process_id](
|
||||
+ int captured_render_process_id,
|
||||
+ const ExtensionHostMsg_OpenChannelToNativeApp::Param& param) {
|
||||
+ if (captured_render_process_id != matching_process_id)
|
||||
+ return false;
|
||||
+
|
||||
+ return true;
|
||||
+ }));
|
||||
+ }
|
||||
+
|
||||
+ // Waits for ExtensionHostMsg_OpenChannelToNativeApp IPC and returns its
|
||||
+ // payload.
|
||||
+ ExtensionHostMsg_OpenChannelToNativeApp::Param WaitForMessage() {
|
||||
+ return ipc_message_waiter_->WaitForMessage();
|
||||
+ }
|
||||
+
|
||||
+ private:
|
||||
+ ScopedTestNativeMessagingHost test_native_messaging_host_;
|
||||
+ std::unique_ptr<OpenChannelMessageWaiter> ipc_message_waiter_;
|
||||
+};
|
||||
+
|
||||
+IN_PROC_BROWSER_TEST_F(OpenChannelToNativeAppExploitTest,
|
||||
+ SourceContextWithSpoofedExtensionId) {
|
||||
+ // Trigger sending of a valid ExtensionHostMsg_OpenChannelToNativeApp IPC
|
||||
+ // from a frame of an `active_extension`.
|
||||
+ const char kScript[] = R"(
|
||||
+ var message = {text: 'Hello!'};
|
||||
+ var host = $1;
|
||||
+ chrome.runtime.sendNativeMessage(host, message);
|
||||
+ )";
|
||||
+ ASSERT_EQ(
|
||||
+ active_extension().origin(),
|
||||
+ active_web_contents()->GetPrimaryMainFrame()->GetLastCommittedOrigin());
|
||||
+ ASSERT_TRUE(content::ExecuteScript(
|
||||
+ active_web_contents(),
|
||||
+ content::JsReplace(kScript, ScopedTestNativeMessagingHost::kHostName)));
|
||||
+
|
||||
+ // Capture the IPC.
|
||||
+ auto [source_context, native_app_name, port_id] = WaitForMessage();
|
||||
+ EXPECT_EQ(native_app_name, ScopedTestNativeMessagingHost::kHostName);
|
||||
+ EXPECT_TRUE(source_context.is_for_render_frame());
|
||||
+
|
||||
+ // Mutate the IPC payload.
|
||||
+ source_context = PortContext::ForWorker(123, // thread_id
|
||||
+ 456, // version_id
|
||||
+ spoofed_extension_id());
|
||||
+
|
||||
+ // Inject the malformed/mutated IPC and verify that the renderer is terminated
|
||||
+ // as expected.
|
||||
+ content::RenderProcessHost* main_frame_process =
|
||||
+ active_web_contents()->GetPrimaryMainFrame()->GetProcess();
|
||||
+ RenderProcessHostBadIpcMessageWaiter kill_waiter(main_frame_process);
|
||||
+ IPC::IpcSecurityTestUtil::PwnMessageReceived(
|
||||
+ main_frame_process->GetChannel(),
|
||||
+ ExtensionHostMsg_OpenChannelToNativeApp(source_context, native_app_name,
|
||||
+ port_id));
|
||||
+ EXPECT_EQ(bad_message::EMF_INVALID_EXTENSION_ID_FOR_WORKER_CONTEXT,
|
||||
+ kill_waiter.Wait());
|
||||
+}
|
||||
+
|
||||
+#endif // !(BUILDFLAG(IS_FUCHSIA)) - native messaging is available
|
||||
+
|
||||
} // namespace extensions
|
||||
diff --git a/docs/security/compromised-renderers.md b/docs/security/compromised-renderers.md
|
||||
index b7e56be454f2d42dc4ae4ac875586a01f2354d9a..2155a399e0e432fedc2792b6893440efd7fca572 100644
|
||||
--- a/docs/security/compromised-renderers.md
|
||||
+++ b/docs/security/compromised-renderers.md
|
||||
@@ -213,14 +213,21 @@ Compromised renderers shouldn’t be able to:
|
||||
- Spoof the `MessageEvent.origin` seen by a recipient of a `postMessage`.
|
||||
- Bypass enforcement of the `targetOrigin` argument of `postMessage`.
|
||||
- Send or receive `BroadcastChannel` messages for another origin.
|
||||
-- Spoof the `MessageSender.origin` seen by a recipient of a
|
||||
- `chrome.runtime.sendMessage`
|
||||
- (see also [MessageSender documentation](https://developers.chrome.com/extensions/runtime#type-MessageSender) and [content script security guidance](https://groups.google.com/a/chromium.org/forum/#!topic/chromium-extensions/0ei-UCHNm34)).
|
||||
+- Spoof the `MessageSender.origin`, nor `MessageSender.id` (i.e. an
|
||||
+ extension id which can differ from the origin when the message is sent
|
||||
+ from a content script), as seen by a recipient of a
|
||||
+ `chrome.runtime.sendMessage`.
|
||||
+ See also [MessageSender documentation](https://developers.chrome.com/extensions/runtime#type-MessageSender) and [content script security guidance](https://groups.google.com/a/chromium.org/forum/#!topic/chromium-extensions/0ei-UCHNm34).
|
||||
+- Spoof the id of a Chrome extension initiating
|
||||
+ [native messaging](https://developer.chrome.com/docs/apps/nativeMessaging/)
|
||||
+ communication.
|
||||
|
||||
Protection techniques:
|
||||
- Using `CanAccessDataForOrigin` to verify IPCs sent by a renderer process
|
||||
(e.g. in `RenderFrameProxyHost::OnRouteMessageEvent` or
|
||||
`BroadcastChannelProvider::ConnectToChannel`).
|
||||
+- Using `ContentScriptTracker` to check if IPCs from a given renderer process
|
||||
+ can legitimately claim to act on behalf content scripts of a given extension.
|
||||
|
||||
**Known gaps in protection**:
|
||||
- Spoofing of `MessageSender.id` object
|
||||
diff --git a/extensions/browser/api/messaging/messaging_api_message_filter.cc b/extensions/browser/api/messaging/messaging_api_message_filter.cc
|
||||
index 5469f5e91bfbb98aece208e9fffa8139dc9dacdf..e57cffb46d74229fff2534f7bb9f9fa3ddbc3d26 100644
|
||||
--- a/extensions/browser/api/messaging/messaging_api_message_filter.cc
|
||||
+++ b/extensions/browser/api/messaging/messaging_api_message_filter.cc
|
||||
@@ -156,6 +156,16 @@ bool IsValidSourceContext(RenderProcessHost& process,
|
||||
}
|
||||
}
|
||||
|
||||
+ // This function doesn't validate frame-flavoured `source_context`s, because
|
||||
+ // PortContext::FrameContext only contains frame's `routing_id` and therefore
|
||||
+ // inherently cannot spoof frames in another process (a frame is identified
|
||||
+ // by its `routing_id` *and* the `process_id` of the Renderer process hosting
|
||||
+ // the frame; the latter is trustworthy / doesn't come from an IPC payload).
|
||||
+
|
||||
+ // This function doesn't validate native app `source_context`s, because
|
||||
+ // `PortContext::ForNativeHost()` is called with trustoworthy inputs (e.g. it
|
||||
+ // doesn't take input from IPCs sent by a Renderer process).
|
||||
+
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -227,6 +237,18 @@ void MessagingAPIMessageFilter::Shutdown() {
|
||||
shutdown_notifier_subscription_ = {};
|
||||
}
|
||||
|
||||
+content::RenderProcessHost* MessagingAPIMessageFilter::GetRenderProcessHost() {
|
||||
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||
+ if (!browser_context_)
|
||||
+ return nullptr;
|
||||
+
|
||||
+ // The IPC might race with RenderProcessHost destruction. This may only
|
||||
+ // happen in scenarios that are already inherently racey, so returning nullptr
|
||||
+ // (and dropping the IPC) is okay and won't lead to any additional risk of
|
||||
+ // data loss.
|
||||
+ return content::RenderProcessHost::FromID(render_process_id_);
|
||||
+}
|
||||
+
|
||||
void MessagingAPIMessageFilter::OverrideThreadForMessage(
|
||||
const IPC::Message& message,
|
||||
BrowserThread::ID* thread) {
|
||||
@@ -272,19 +294,14 @@ void MessagingAPIMessageFilter::OnOpenChannelToExtension(
|
||||
const std::string& channel_name,
|
||||
const PortId& port_id) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||
- if (!browser_context_)
|
||||
- return;
|
||||
-
|
||||
- // The IPC might race with RenderProcessHost destruction. This may only
|
||||
- // happen in scenarios that are already inherently racey, so dropping the IPC
|
||||
- // is okay and won't lead to any additional risk of data loss.
|
||||
- auto* process = content::RenderProcessHost::FromID(render_process_id_);
|
||||
+ auto* process = GetRenderProcessHost();
|
||||
if (!process)
|
||||
return;
|
||||
TRACE_EVENT("extensions", "MessageFilter::OnOpenChannelToExtension",
|
||||
ChromeTrackEvent::kRenderProcessHost, *process);
|
||||
|
||||
ScopedExternalConnectionInfoCrashKeys info_crash_keys(info);
|
||||
+ debug::ScopedPortContextCrashKeys port_context_crash_keys(source_context);
|
||||
if (!IsValidMessagingSource(*process, info.source_endpoint) ||
|
||||
!IsValidSourceContext(*process, source_context)) {
|
||||
return;
|
||||
@@ -303,7 +320,14 @@ void MessagingAPIMessageFilter::OnOpenChannelToNativeApp(
|
||||
const std::string& native_app_name,
|
||||
const PortId& port_id) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||
- if (!browser_context_)
|
||||
+ auto* process = GetRenderProcessHost();
|
||||
+ if (!process)
|
||||
+ return;
|
||||
+ TRACE_EVENT("extensions", "MessageFilter::OnOpenChannelToNativeApp",
|
||||
+ ChromeTrackEvent::kRenderProcessHost, *process);
|
||||
+
|
||||
+ debug::ScopedPortContextCrashKeys port_context_crash_keys(source_context);
|
||||
+ if (!IsValidSourceContext(*process, source_context))
|
||||
return;
|
||||
|
||||
ChannelEndpoint source_endpoint(browser_context_, render_process_id_,
|
||||
diff --git a/extensions/browser/api/messaging/messaging_api_message_filter.h b/extensions/browser/api/messaging/messaging_api_message_filter.h
|
||||
index 6a0ccd698629f650d68f2b4ee168aa2b3b3a116c..3358187387cd9a5765a7bd4e522aeecfd787e06b 100644
|
||||
--- a/extensions/browser/api/messaging/messaging_api_message_filter.h
|
||||
+++ b/extensions/browser/api/messaging/messaging_api_message_filter.h
|
||||
@@ -14,6 +14,7 @@ struct ExtensionMsg_TabTargetConnectionInfo;
|
||||
|
||||
namespace content {
|
||||
class BrowserContext;
|
||||
+class RenderProcessHost;
|
||||
}
|
||||
|
||||
namespace extensions {
|
||||
@@ -40,6 +41,11 @@ class MessagingAPIMessageFilter : public content::BrowserMessageFilter {
|
||||
|
||||
void Shutdown();
|
||||
|
||||
+ // Returns the process that the IPC came from, or `nullptr` if the IPC should
|
||||
+ // be dropped (in case the IPC arrived racily after the process or its
|
||||
+ // BrowserContext already got destructed).
|
||||
+ content::RenderProcessHost* GetRenderProcessHost();
|
||||
+
|
||||
// content::BrowserMessageFilter implementation:
|
||||
void OverrideThreadForMessage(const IPC::Message& message,
|
||||
content::BrowserThread::ID* thread) override;
|
||||
diff --git a/extensions/common/api/messaging/port_context.cc b/extensions/common/api/messaging/port_context.cc
|
||||
index 6872179450d8295de7f15dc1437e9d6edefe4fde..319e2f34eca730c5eb7cf94ef8cdede0ddc3f8e1 100644
|
||||
--- a/extensions/common/api/messaging/port_context.cc
|
||||
+++ b/extensions/common/api/messaging/port_context.cc
|
||||
@@ -40,4 +40,27 @@ PortContext PortContext::ForNativeHost() {
|
||||
return PortContext();
|
||||
}
|
||||
|
||||
+namespace debug {
|
||||
+
|
||||
+namespace {
|
||||
+
|
||||
+base::debug::CrashKeyString* GetServiceWorkerExtensionIdCrashKey() {
|
||||
+ static auto* crash_key = base::debug::AllocateCrashKeyString(
|
||||
+ "PortContext-worker-extension_id", base::debug::CrashKeySize::Size64);
|
||||
+ return crash_key;
|
||||
+}
|
||||
+
|
||||
+} // namespace
|
||||
+
|
||||
+ScopedPortContextCrashKeys::ScopedPortContextCrashKeys(
|
||||
+ const PortContext& port_context) {
|
||||
+ if (port_context.is_for_service_worker()) {
|
||||
+ extension_id_.emplace(GetServiceWorkerExtensionIdCrashKey(),
|
||||
+ port_context.worker->extension_id);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+ScopedPortContextCrashKeys::~ScopedPortContextCrashKeys() = default;
|
||||
+
|
||||
+} // namespace debug
|
||||
} // namespace extensions
|
||||
diff --git a/extensions/common/api/messaging/port_context.h b/extensions/common/api/messaging/port_context.h
|
||||
index b2e9f057b531d90dc256773959cd586953e4915c..53d94c2ad73c58d45b186a32989e2f4864e67d79 100644
|
||||
--- a/extensions/common/api/messaging/port_context.h
|
||||
+++ b/extensions/common/api/messaging/port_context.h
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
+#include "base/debug/crash_logging.h"
|
||||
#include "third_party/abseil-cpp/absl/types/optional.h"
|
||||
|
||||
namespace extensions {
|
||||
@@ -59,6 +60,19 @@ struct PortContext {
|
||||
absl::optional<WorkerContext> worker;
|
||||
};
|
||||
|
||||
+namespace debug {
|
||||
+
|
||||
+class ScopedPortContextCrashKeys {
|
||||
+ public:
|
||||
+ explicit ScopedPortContextCrashKeys(const PortContext& port_context);
|
||||
+ ~ScopedPortContextCrashKeys();
|
||||
+
|
||||
+ private:
|
||||
+ absl::optional<base::debug::ScopedCrashKeyString> extension_id_;
|
||||
+};
|
||||
+
|
||||
+} // namespace debug
|
||||
+
|
||||
} // namespace extensions
|
||||
|
||||
#endif // EXTENSIONS_COMMON_API_MESSAGING_PORT_CONTEXT_H_
|
||||
323
patches/chromium/cherry-pick-933cc81c6bad.patch
Normal file
323
patches/chromium/cherry-pick-933cc81c6bad.patch
Normal file
@@ -0,0 +1,323 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Xiaocheng Hu <xiaochengh@chromium.org>
|
||||
Date: Sat, 10 Sep 2022 05:53:49 +0000
|
||||
Subject: Remove symlinks from FileChooserImpl folder upload result
|
||||
|
||||
FileChooserImpl is the browser-side implementation of
|
||||
<input type=file>. When uploading a whole folder, it
|
||||
currently uses DirectoryLister to list all the files in a
|
||||
directory. The result also includes resolved symbolic links
|
||||
(which may even hide deep in some subfolder), which is not a
|
||||
desired behavior.
|
||||
|
||||
Therefore, this patch removes all symbolic links from the
|
||||
result by checking each file against `base::IsLink()`. Since
|
||||
the function needs blocking calls to access file data, the
|
||||
job is sent to a worker pool thread.
|
||||
|
||||
Fixed: 1345275
|
||||
Change-Id: I8ab58214c87944408c64b177e915247a7485925b
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3866767
|
||||
Reviewed-by: Austin Sullivan <asully@chromium.org>
|
||||
Commit-Queue: Xiaocheng Hu <xiaochengh@chromium.org>
|
||||
Reviewed-by: Mason Freed <masonf@chromium.org>
|
||||
Reviewed-by: Alex Moshchuk <alexmos@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/main@{#1045491}
|
||||
|
||||
diff --git a/content/browser/web_contents/file_chooser_impl.cc b/content/browser/web_contents/file_chooser_impl.cc
|
||||
index 7a3ea45d32c97980c141662f6a071cc517a15ad8..1aa19f7a735b444f2c33d5084edcdd14e3c2f5c5 100644
|
||||
--- a/content/browser/web_contents/file_chooser_impl.cc
|
||||
+++ b/content/browser/web_contents/file_chooser_impl.cc
|
||||
@@ -4,8 +4,11 @@
|
||||
|
||||
#include "content/browser/web_contents/file_chooser_impl.h"
|
||||
|
||||
+#include "base/files/file_util.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/memory/ptr_util.h"
|
||||
+#include "base/ranges/algorithm.h"
|
||||
+#include "base/task/thread_pool.h"
|
||||
#include "content/browser/child_process_security_policy_impl.h"
|
||||
#include "content/browser/renderer_host/back_forward_cache_disable.h"
|
||||
#include "content/browser/renderer_host/render_frame_host_delegate.h"
|
||||
@@ -18,6 +21,19 @@
|
||||
|
||||
namespace content {
|
||||
|
||||
+namespace {
|
||||
+
|
||||
+std::vector<blink::mojom::FileChooserFileInfoPtr> RemoveSymlinks(
|
||||
+ std::vector<blink::mojom::FileChooserFileInfoPtr> files) {
|
||||
+ auto new_end = base::ranges::remove_if(
|
||||
+ files, &base::IsLink,
|
||||
+ [](const auto& file) { return file->get_native_file()->file_path; });
|
||||
+ files.erase(new_end, files.end());
|
||||
+ return files;
|
||||
+}
|
||||
+
|
||||
+} // namespace
|
||||
+
|
||||
FileChooserImpl::FileSelectListenerImpl::~FileSelectListenerImpl() {
|
||||
#if DCHECK_IS_ON()
|
||||
if (!was_file_select_listener_function_called_) {
|
||||
@@ -51,8 +67,20 @@ void FileChooserImpl::FileSelectListenerImpl::FileSelected(
|
||||
"FileSelectListener::FileSelectionCanceled()";
|
||||
was_file_select_listener_function_called_ = true;
|
||||
#endif
|
||||
- if (owner_)
|
||||
- owner_->FileSelected(std::move(files), base_dir, mode);
|
||||
+ if (!owner_)
|
||||
+ return;
|
||||
+
|
||||
+ if (mode != blink::mojom::FileChooserParams::Mode::kUploadFolder) {
|
||||
+ owner_->FileSelected(base_dir, mode, std::move(files));
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ base::ThreadPool::PostTaskAndReplyWithResult(
|
||||
+ FROM_HERE,
|
||||
+ {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
|
||||
+ base::BindOnce(&RemoveSymlinks, std::move(files)),
|
||||
+ base::BindOnce(&FileChooserImpl::FileSelected, owner_->GetWeakPtr(),
|
||||
+ base_dir, mode));
|
||||
}
|
||||
|
||||
void FileChooserImpl::FileSelectListenerImpl::FileSelectionCanceled() {
|
||||
@@ -162,9 +190,9 @@ void FileChooserImpl::EnumerateChosenDirectory(
|
||||
}
|
||||
|
||||
void FileChooserImpl::FileSelected(
|
||||
- std::vector<blink::mojom::FileChooserFileInfoPtr> files,
|
||||
const base::FilePath& base_dir,
|
||||
- blink::mojom::FileChooserParams::Mode mode) {
|
||||
+ blink::mojom::FileChooserParams::Mode mode,
|
||||
+ std::vector<blink::mojom::FileChooserFileInfoPtr> files) {
|
||||
listener_impl_ = nullptr;
|
||||
if (!render_frame_host_) {
|
||||
std::move(callback_).Run(nullptr);
|
||||
diff --git a/content/browser/web_contents/file_chooser_impl.h b/content/browser/web_contents/file_chooser_impl.h
|
||||
index b9f11f9e6a0b548cb5ab8ca721ae823e079ce6fa..b628b29a5f84264e62bb3fa9e92550787b8342de 100644
|
||||
--- a/content/browser/web_contents/file_chooser_impl.h
|
||||
+++ b/content/browser/web_contents/file_chooser_impl.h
|
||||
@@ -37,6 +37,8 @@ class CONTENT_EXPORT FileChooserImpl : public blink::mojom::FileChooser,
|
||||
|
||||
// FileSelectListener overrides:
|
||||
|
||||
+ // TODO(xiaochengh): Move |file| to the end of the argument list to match
|
||||
+ // the argument ordering of FileChooserImpl::FileSelected().
|
||||
void FileSelected(std::vector<blink::mojom::FileChooserFileInfoPtr> files,
|
||||
const base::FilePath& base_dir,
|
||||
blink::mojom::FileChooserParams::Mode mode) override;
|
||||
@@ -68,9 +70,9 @@ class CONTENT_EXPORT FileChooserImpl : public blink::mojom::FileChooser,
|
||||
|
||||
~FileChooserImpl() override;
|
||||
|
||||
- void FileSelected(std::vector<blink::mojom::FileChooserFileInfoPtr> files,
|
||||
- const base::FilePath& base_dir,
|
||||
- blink::mojom::FileChooserParams::Mode mode);
|
||||
+ void FileSelected(const base::FilePath& base_dir,
|
||||
+ blink::mojom::FileChooserParams::Mode mode,
|
||||
+ std::vector<blink::mojom::FileChooserFileInfoPtr> files);
|
||||
|
||||
void FileSelectionCanceled();
|
||||
|
||||
@@ -82,6 +84,10 @@ class CONTENT_EXPORT FileChooserImpl : public blink::mojom::FileChooser,
|
||||
const base::FilePath& directory_path,
|
||||
EnumerateChosenDirectoryCallback callback) override;
|
||||
|
||||
+ base::WeakPtr<FileChooserImpl> GetWeakPtr() {
|
||||
+ return weak_factory_.GetWeakPtr();
|
||||
+ }
|
||||
+
|
||||
private:
|
||||
explicit FileChooserImpl(RenderFrameHostImpl* render_frame_host);
|
||||
|
||||
@@ -95,6 +101,8 @@ class CONTENT_EXPORT FileChooserImpl : public blink::mojom::FileChooser,
|
||||
raw_ptr<RenderFrameHostImpl> render_frame_host_;
|
||||
scoped_refptr<FileSelectListenerImpl> listener_impl_;
|
||||
base::OnceCallback<void(blink::mojom::FileChooserResultPtr)> callback_;
|
||||
+
|
||||
+ base::WeakPtrFactory<FileChooserImpl> weak_factory_{this};
|
||||
};
|
||||
|
||||
} // namespace content
|
||||
diff --git a/content/browser/web_contents/file_chooser_impl_browsertest.cc b/content/browser/web_contents/file_chooser_impl_browsertest.cc
|
||||
index ced9bfd8fe905acbb6ab5c3e52a9882fc23a7303..f7519189638ece437c4285ddd490be3ea59e638d 100644
|
||||
--- a/content/browser/web_contents/file_chooser_impl_browsertest.cc
|
||||
+++ b/content/browser/web_contents/file_chooser_impl_browsertest.cc
|
||||
@@ -5,14 +5,18 @@
|
||||
#include "content/browser/web_contents/file_chooser_impl.h"
|
||||
|
||||
#include "base/bind.h"
|
||||
+#include "base/files/file_util.h"
|
||||
+#include "base/path_service.h"
|
||||
#include "base/run_loop.h"
|
||||
#include "content/browser/renderer_host/render_frame_host_impl.h"
|
||||
#include "content/public/browser/web_contents_delegate.h"
|
||||
+#include "content/public/common/content_paths.h"
|
||||
#include "content/public/test/browser_test.h"
|
||||
#include "content/public/test/browser_test_utils.h"
|
||||
#include "content/public/test/content_browser_test.h"
|
||||
#include "content/public/test/content_browser_test_utils.h"
|
||||
#include "content/shell/browser/shell.h"
|
||||
+#include "content/test/content_browser_test_utils_internal.h"
|
||||
#include "url/gurl.h"
|
||||
#include "url/url_constants.h"
|
||||
|
||||
@@ -143,11 +147,52 @@ IN_PROC_BROWSER_TEST_F(FileChooserImplBrowserTest,
|
||||
->SetListenerFunctionCalledTrueForTesting();
|
||||
std::vector<blink::mojom::FileChooserFileInfoPtr> files;
|
||||
files.emplace_back(blink::mojom::FileChooserFileInfoPtr(nullptr));
|
||||
- chooser->FileSelected(std::move(files), base::FilePath(),
|
||||
- blink::mojom::FileChooserParams::Mode::kOpen);
|
||||
+ chooser->FileSelected(base::FilePath(),
|
||||
+ blink::mojom::FileChooserParams::Mode::kOpen,
|
||||
+ std::move(files));
|
||||
|
||||
// Test passes if this run_loop.Run() returns instead of timing out.
|
||||
run_loop.Run();
|
||||
}
|
||||
|
||||
+// https://crbug.com/1345275
|
||||
+IN_PROC_BROWSER_TEST_F(FileChooserImplBrowserTest, UploadFolderWithSymlink) {
|
||||
+ EXPECT_TRUE(NavigateToURL(
|
||||
+ shell(), GetTestUrl(".", "file_input_webkitdirectory.html")));
|
||||
+
|
||||
+ // The folder contains a regular file and a symbolic link.
|
||||
+ // When uploading the folder, the symbolic link should be excluded.
|
||||
+ base::FilePath dir_test_data;
|
||||
+ ASSERT_TRUE(base::PathService::Get(DIR_TEST_DATA, &dir_test_data));
|
||||
+ base::FilePath folder_to_upload =
|
||||
+ dir_test_data.AppendASCII("file_chooser").AppendASCII("dir_with_symlink");
|
||||
+
|
||||
+ base::FilePath text_file = folder_to_upload.AppendASCII("text_file.txt");
|
||||
+ base::FilePath symlink_file = folder_to_upload.AppendASCII("symlink");
|
||||
+
|
||||
+ // Skip the test if symbolic links are not supported.
|
||||
+ {
|
||||
+ base::ScopedAllowBlockingForTesting allow_blocking;
|
||||
+ if (!base::IsLink(symlink_file))
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ std::unique_ptr<FileChooserDelegate> delegate(
|
||||
+ new FileChooserDelegate({text_file, symlink_file}, base::OnceClosure()));
|
||||
+ shell()->web_contents()->SetDelegate(delegate.get());
|
||||
+ EXPECT_TRUE(ExecJs(shell(),
|
||||
+ "(async () => {"
|
||||
+ " let listener = new Promise("
|
||||
+ " resolve => fileinput.onchange = resolve);"
|
||||
+ " fileinput.click();"
|
||||
+ " await listener;"
|
||||
+ "})()"));
|
||||
+
|
||||
+ EXPECT_EQ(
|
||||
+ 1, EvalJs(shell(), "document.getElementById('fileinput').files.length;"));
|
||||
+ EXPECT_EQ(
|
||||
+ "text_file.txt",
|
||||
+ EvalJs(shell(), "document.getElementById('fileinput').files[0].name;"));
|
||||
+}
|
||||
+
|
||||
} // namespace content
|
||||
diff --git a/content/test/content_browser_test_utils_internal.cc b/content/test/content_browser_test_utils_internal.cc
|
||||
index d8e63b56c8ac89a08cd7c40cabb156eb4d1923aa..c70d088bfd007e9a6cd9cfcb6f92b07b99653048 100644
|
||||
--- a/content/test/content_browser_test_utils_internal.cc
|
||||
+++ b/content/test/content_browser_test_utils_internal.cc
|
||||
@@ -446,9 +446,14 @@ Shell* OpenPopup(const ToRenderFrameHost& opener,
|
||||
return new_shell_observer.GetShell();
|
||||
}
|
||||
|
||||
+FileChooserDelegate::FileChooserDelegate(std::vector<base::FilePath> files,
|
||||
+ base::OnceClosure callback)
|
||||
+ : files_(std::move(files)), callback_(std::move(callback)) {}
|
||||
+
|
||||
FileChooserDelegate::FileChooserDelegate(const base::FilePath& file,
|
||||
base::OnceClosure callback)
|
||||
- : file_(file), callback_(std::move(callback)) {}
|
||||
+ : FileChooserDelegate(std::vector<base::FilePath>(1, file),
|
||||
+ std::move(callback)) {}
|
||||
|
||||
FileChooserDelegate::~FileChooserDelegate() = default;
|
||||
|
||||
@@ -456,16 +461,18 @@ void FileChooserDelegate::RunFileChooser(
|
||||
RenderFrameHost* render_frame_host,
|
||||
scoped_refptr<content::FileSelectListener> listener,
|
||||
const blink::mojom::FileChooserParams& params) {
|
||||
- // Send the selected file to the renderer process.
|
||||
- auto file_info = blink::mojom::FileChooserFileInfo::NewNativeFile(
|
||||
- blink::mojom::NativeFileInfo::New(file_, std::u16string()));
|
||||
+ // Send the selected files to the renderer process.
|
||||
std::vector<blink::mojom::FileChooserFileInfoPtr> files;
|
||||
- files.push_back(std::move(file_info));
|
||||
- listener->FileSelected(std::move(files), base::FilePath(),
|
||||
- blink::mojom::FileChooserParams::Mode::kOpen);
|
||||
+ for (const auto& file : files_) {
|
||||
+ auto file_info = blink::mojom::FileChooserFileInfo::NewNativeFile(
|
||||
+ blink::mojom::NativeFileInfo::New(file, std::u16string()));
|
||||
+ files.push_back(std::move(file_info));
|
||||
+ }
|
||||
+ listener->FileSelected(std::move(files), base::FilePath(), params.mode);
|
||||
|
||||
params_ = params.Clone();
|
||||
- std::move(callback_).Run();
|
||||
+ if (callback_)
|
||||
+ std::move(callback_).Run();
|
||||
}
|
||||
|
||||
FrameTestNavigationManager::FrameTestNavigationManager(
|
||||
diff --git a/content/test/content_browser_test_utils_internal.h b/content/test/content_browser_test_utils_internal.h
|
||||
index 73be6e8a2f458128b08aae34d951c7a80139997d..43c6aabc5414d0cc12fb5a03142e8b20e2a7fab3 100644
|
||||
--- a/content/test/content_browser_test_utils_internal.h
|
||||
+++ b/content/test/content_browser_test_utils_internal.h
|
||||
@@ -176,9 +176,11 @@ Shell* OpenPopup(const ToRenderFrameHost& opener,
|
||||
class FileChooserDelegate : public WebContentsDelegate {
|
||||
public:
|
||||
// Constructs a WebContentsDelegate that mocks a file dialog.
|
||||
- // The mocked file dialog will always reply that the user selected |file|.
|
||||
- // |callback| is invoked when RunFileChooser() is called.
|
||||
+ // The mocked file dialog will always reply that the user selected |file| or
|
||||
+ // |files|. |callback| is invoked when RunFileChooser() is called.
|
||||
FileChooserDelegate(const base::FilePath& file, base::OnceClosure callback);
|
||||
+ FileChooserDelegate(std::vector<base::FilePath> files,
|
||||
+ base::OnceClosure callback);
|
||||
~FileChooserDelegate() override;
|
||||
|
||||
// Implementation of WebContentsDelegate::RunFileChooser.
|
||||
@@ -190,7 +192,7 @@ class FileChooserDelegate : public WebContentsDelegate {
|
||||
const blink::mojom::FileChooserParams& params() const { return *params_; }
|
||||
|
||||
private:
|
||||
- base::FilePath file_;
|
||||
+ std::vector<base::FilePath> files_;
|
||||
base::OnceClosure callback_;
|
||||
blink::mojom::FileChooserParamsPtr params_;
|
||||
};
|
||||
diff --git a/content/test/data/file_chooser/dir_with_symlink/symlink b/content/test/data/file_chooser/dir_with_symlink/symlink
|
||||
new file mode 120000
|
||||
index 0000000000000000000000000000000000000000..7857c689f7043265b4e6d4dcdf6d40d0be2d3d60
|
||||
--- /dev/null
|
||||
+++ b/content/test/data/file_chooser/dir_with_symlink/symlink
|
||||
@@ -0,0 +1 @@
|
||||
+../linked_text_file.txt
|
||||
\ No newline at end of file
|
||||
diff --git a/content/test/data/file_chooser/dir_with_symlink/text_file.txt b/content/test/data/file_chooser/dir_with_symlink/text_file.txt
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..8e27be7d6154a1f68ea9160ef0e18691d20560dc
|
||||
--- /dev/null
|
||||
+++ b/content/test/data/file_chooser/dir_with_symlink/text_file.txt
|
||||
@@ -0,0 +1 @@
|
||||
+text
|
||||
diff --git a/content/test/data/file_chooser/linked_text_file.txt b/content/test/data/file_chooser/linked_text_file.txt
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..9a1f4bc60917c014eac1464ad664a0271c288b84
|
||||
--- /dev/null
|
||||
+++ b/content/test/data/file_chooser/linked_text_file.txt
|
||||
@@ -0,0 +1 @@
|
||||
+linked text file
|
||||
diff --git a/content/test/data/file_input_webkitdirectory.html b/content/test/data/file_input_webkitdirectory.html
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..5b7bb501f7eb5d9f28751f36380e4ad01d2da0c7
|
||||
--- /dev/null
|
||||
+++ b/content/test/data/file_input_webkitdirectory.html
|
||||
@@ -0,0 +1 @@
|
||||
+<input type="file" id="fileinput" webkitdirectory />
|
||||
122
patches/chromium/cherry-pick-c83640db21b5.patch
Normal file
122
patches/chromium/cherry-pick-c83640db21b5.patch
Normal file
@@ -0,0 +1,122 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Samuel Attard <samuel.r.attard@gmail.com>
|
||||
Date: Wed, 5 Oct 2022 06:03:23 +0000
|
||||
Subject: build: set DTSDKBuild correctly when generating plist files
|
||||
|
||||
Currently we set DTSDKBuild to the version of the SDK used to build
|
||||
Chromium. This value is supposed to be the build version (this is
|
||||
what xcode sets it to for instance). We read this value out of the
|
||||
SDK directly and use it instead.
|
||||
|
||||
Change-Id: Ieb7990f13095683ad8c026f027b2605ae39523a4
|
||||
|
||||
diff --git a/build/config/mac/mac_sdk.gni b/build/config/mac/mac_sdk.gni
|
||||
index 7b1761607c853ae79619d6b872167a00a39f8236..c8e07ad62519236ead55c9b7ce1b1a4c3d5491af 100644
|
||||
--- a/build/config/mac/mac_sdk.gni
|
||||
+++ b/build/config/mac/mac_sdk.gni
|
||||
@@ -40,6 +40,11 @@ declare_args() {
|
||||
# will fail.
|
||||
mac_sdk_official_version = "12.3"
|
||||
|
||||
+ # The SDK build version used when making official builds. This is a single
|
||||
+ # exact version found at "System/Library/CoreServices/SystemVersion.plist"
|
||||
+ # inside the SDK.
|
||||
+ mac_sdk_official_build_version = "21E226"
|
||||
+
|
||||
# Production builds should use hermetic Xcode. If you want to do production
|
||||
# builds with system Xcode to test new SDKs, set this.
|
||||
# Don't set this on any bots.
|
||||
@@ -101,11 +106,13 @@ if (use_system_xcode) {
|
||||
find_sdk_args = [
|
||||
"--print_sdk_path",
|
||||
"--print_bin_path",
|
||||
+ "--print_sdk_build",
|
||||
mac_sdk_min,
|
||||
]
|
||||
find_sdk_lines =
|
||||
exec_script("//build/mac/find_sdk.py", find_sdk_args, "list lines")
|
||||
- mac_sdk_version = find_sdk_lines[2]
|
||||
+ mac_sdk_version = find_sdk_lines[3]
|
||||
+ mac_sdk_build_version = find_sdk_lines[2]
|
||||
if (mac_sdk_path == "") {
|
||||
mac_sdk_path = find_sdk_lines[0]
|
||||
mac_bin_path = find_sdk_lines[1]
|
||||
@@ -114,6 +121,7 @@ if (use_system_xcode) {
|
||||
}
|
||||
} else {
|
||||
mac_sdk_version = mac_sdk_official_version
|
||||
+ mac_sdk_build_version = mac_sdk_official_build_version
|
||||
_dev = _hermetic_xcode_path + "/Contents/Developer"
|
||||
_sdk = "MacOSX${mac_sdk_version}.sdk"
|
||||
mac_sdk_path = _dev + "/Platforms/MacOSX.platform/Developer/SDKs/$_sdk"
|
||||
diff --git a/build/config/mac/rules.gni b/build/config/mac/rules.gni
|
||||
index 03073f830401c4891376a3b59e2e7a870e3d34b7..04d403054c1a83fcbbc70be7cfd239ecbec315d3 100644
|
||||
--- a/build/config/mac/rules.gni
|
||||
+++ b/build/config/mac/rules.gni
|
||||
@@ -41,7 +41,7 @@ template("mac_info_plist") {
|
||||
apple_info_plist(target_name) {
|
||||
format = "xml1"
|
||||
extra_substitutions = [
|
||||
- "MAC_SDK_BUILD=$mac_sdk_version",
|
||||
+ "MAC_SDK_BUILD=$mac_sdk_build_version",
|
||||
"MAC_SDK_NAME=$mac_sdk_name$mac_sdk_version",
|
||||
"MACOSX_DEPLOYMENT_TARGET=$mac_deployment_target",
|
||||
"CHROMIUM_MIN_SYSTEM_VERSION=$mac_min_system_version",
|
||||
diff --git a/build/mac/find_sdk.py b/build/mac/find_sdk.py
|
||||
index d86f3109357a9246d570cb02992dc82552ba7c20..b2400c7e8c70957e364444f509880900ce3b641f 100755
|
||||
--- a/build/mac/find_sdk.py
|
||||
+++ b/build/mac/find_sdk.py
|
||||
@@ -24,6 +24,7 @@ Sample Output:
|
||||
from __future__ import print_function
|
||||
|
||||
import os
|
||||
+import plistlib
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
@@ -51,6 +52,9 @@ def main():
|
||||
parser.add_option("--print_bin_path",
|
||||
action="store_true", dest="print_bin_path", default=False,
|
||||
help="Additionally print the path the toolchain bin dir.")
|
||||
+ parser.add_option("--print_sdk_build",
|
||||
+ action="store_true", dest="print_sdk_build", default=False,
|
||||
+ help="Additionally print the build version of the SDK.")
|
||||
options, args = parser.parse_args()
|
||||
if len(args) != 1:
|
||||
parser.error('Please specify a minimum SDK version')
|
||||
@@ -80,20 +84,30 @@ def main():
|
||||
if not sdks:
|
||||
raise Exception('No %s+ SDK found' % min_sdk_version)
|
||||
best_sdk = sorted(sdks, key=parse_version)[0]
|
||||
+ sdk_name = 'MacOSX' + best_sdk + '.sdk'
|
||||
+ sdk_path = os.path.join(sdk_dir, sdk_name)
|
||||
|
||||
if options.print_sdk_path:
|
||||
- sdk_name = 'MacOSX' + best_sdk + '.sdk'
|
||||
- print(os.path.join(sdk_dir, sdk_name))
|
||||
+ print(sdk_path)
|
||||
|
||||
if options.print_bin_path:
|
||||
bin_path = 'Toolchains/XcodeDefault.xctoolchain/usr/bin/'
|
||||
print(os.path.join(dev_dir, bin_path))
|
||||
|
||||
- return best_sdk
|
||||
+ if options.print_sdk_build:
|
||||
+ system_version_plist = os.path.join(sdk_path,
|
||||
+ 'System/Library/CoreServices/SystemVersion.plist')
|
||||
+ with open(system_version_plist, 'rb') as f:
|
||||
+ system_version_info = plistlib.load(f)
|
||||
+ if 'ProductBuildVersion' not in system_version_info:
|
||||
+ raise Exception('Failed to determine ProductBuildVersion' +
|
||||
+ 'for SDK at path %s' % system_version_plist)
|
||||
+ print(system_version_info['ProductBuildVersion'])
|
||||
+
|
||||
+ print(best_sdk)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if sys.platform != 'darwin':
|
||||
raise Exception("This script only runs on Mac")
|
||||
- print(main())
|
||||
- sys.exit(0)
|
||||
+ sys.exit(main())
|
||||
86
patches/chromium/cherry-pick-cb9dff93f3d4.patch
Normal file
86
patches/chromium/cherry-pick-cb9dff93f3d4.patch
Normal file
@@ -0,0 +1,86 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Harald Alvestrand <hta@chromium.org>
|
||||
Date: Mon, 10 Oct 2022 08:37:15 +0000
|
||||
Subject: Use HeapMojoReceiver rather than mojo::Receiver for
|
||||
PeerConnectionTracker
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
HeapMojoReceiver is recommended for garbage collected objects, avoiding
|
||||
problems with conflicting lifetimes.
|
||||
|
||||
(cherry picked from commit e3437317c4cd8401f0f0d599b61751bbe0e1ec70)
|
||||
|
||||
Bug: chromium:1369882
|
||||
Change-Id: Ic38e761cf4275e6d7b30a6d7e2daa5d1596e67a4
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3936144
|
||||
Reviewed-by: Henrik Boström <hbos@chromium.org>
|
||||
Commit-Queue: Harald Alvestrand <hta@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1055630}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3934344
|
||||
Commit-Queue: Henrik Boström <hbos@chromium.org>
|
||||
Auto-Submit: Harald Alvestrand <hta@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/5249@{#790}
|
||||
Cr-Branched-From: 4f7bea5de862aaa52e6bde5920755a9ef9db120b-refs/heads/main@{#1036826}
|
||||
|
||||
diff --git a/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.cc b/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.cc
|
||||
index 30e5b6bfb365a738d72fdab31fee0d657cbc26c7..e77370db8ae1115a9e99e658364b14efe8d27cd3 100644
|
||||
--- a/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.cc
|
||||
+++ b/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.cc
|
||||
@@ -644,16 +644,20 @@ PeerConnectionTracker::PeerConnectionTracker(
|
||||
scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner,
|
||||
base::PassKey<PeerConnectionTracker>)
|
||||
: Supplement<LocalDOMWindow>(window),
|
||||
+ receiver_(this, &window),
|
||||
main_thread_task_runner_(std::move(main_thread_task_runner)) {
|
||||
window.GetBrowserInterfaceBroker().GetInterface(
|
||||
peer_connection_tracker_host_.BindNewPipeAndPassReceiver());
|
||||
}
|
||||
|
||||
+// Constructor used for testing. Note that receiver_ doesn't have a context
|
||||
+// notifier in this case.
|
||||
PeerConnectionTracker::PeerConnectionTracker(
|
||||
mojo::Remote<blink::mojom::blink::PeerConnectionTrackerHost> host,
|
||||
scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner)
|
||||
: Supplement(nullptr),
|
||||
peer_connection_tracker_host_(std::move(host)),
|
||||
+ receiver_(this, nullptr),
|
||||
main_thread_task_runner_(std::move(main_thread_task_runner)) {}
|
||||
|
||||
PeerConnectionTracker::~PeerConnectionTracker() {}
|
||||
diff --git a/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.h b/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.h
|
||||
index 477dfc3a5384643f46804966888afa549769d39d..6a31cf39f3d1a03981ff438c9c1463f168f53423 100644
|
||||
--- a/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.h
|
||||
+++ b/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.h
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
|
||||
#include "third_party/blink/renderer/modules/mediastream/media_stream.h"
|
||||
#include "third_party/blink/renderer/modules/modules_export.h"
|
||||
+#include "third_party/blink/renderer/platform/mojo/heap_mojo_receiver.h"
|
||||
#include "third_party/blink/renderer/platform/peerconnection/rtc_peer_connection_handler_client.h"
|
||||
#include "third_party/blink/renderer/platform/peerconnection/rtc_rtp_transceiver_platform.h"
|
||||
#include "third_party/blink/renderer/platform/peerconnection/rtc_session_description_platform.h"
|
||||
@@ -252,6 +253,11 @@ class MODULES_EXPORT PeerConnectionTracker
|
||||
virtual void TrackRtcEventLogWrite(RTCPeerConnectionHandler* pc_handler,
|
||||
const WTF::Vector<uint8_t>& output);
|
||||
|
||||
+ void Trace(Visitor* visitor) const override {
|
||||
+ visitor->Trace(receiver_);
|
||||
+ Supplement<LocalDOMWindow>::Trace(visitor);
|
||||
+ }
|
||||
+
|
||||
private:
|
||||
FRIEND_TEST_ALL_PREFIXES(PeerConnectionTrackerTest, OnSuspend);
|
||||
FRIEND_TEST_ALL_PREFIXES(PeerConnectionTrackerTest, OnThermalStateChange);
|
||||
@@ -320,7 +326,9 @@ class MODULES_EXPORT PeerConnectionTracker
|
||||
THREAD_CHECKER(main_thread_);
|
||||
mojo::Remote<blink::mojom::blink::PeerConnectionTrackerHost>
|
||||
peer_connection_tracker_host_;
|
||||
- mojo::Receiver<blink::mojom::blink::PeerConnectionManager> receiver_{this};
|
||||
+ HeapMojoReceiver<blink::mojom::blink::PeerConnectionManager,
|
||||
+ PeerConnectionTracker>
|
||||
+ receiver_;
|
||||
|
||||
scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
|
||||
};
|
||||
70
patches/chromium/cherry-pick-d5ffb4dd4112.patch
Normal file
70
patches/chromium/cherry-pick-d5ffb4dd4112.patch
Normal file
@@ -0,0 +1,70 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shrek Shao <shrekshao@google.com>
|
||||
Date: Tue, 18 Oct 2022 01:30:12 +0000
|
||||
Subject: WebGPU: use CHECK instead of DCHECK to crash out of bounds write in
|
||||
SerializeDataUpdate
|
||||
|
||||
A comprised renderer could have a shared memory size not large enough
|
||||
to fit the GPU buffer contents. Instead of DCHECK, do a CHECK here to
|
||||
crash the release build. The crash is fine since it is not reachable
|
||||
from normal behavior. WebGPU post-V1 will have a refactored API.
|
||||
|
||||
(cherry picked from commit 9bcbce75d5feaa1ba48a5d0d8036b5c77500bb67)
|
||||
|
||||
Fixed: 1373314
|
||||
Change-Id: I8d8e1a469c2b10ff16e7363f9b6f7b63587cb007
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3946246
|
||||
Reviewed-by: Austin Eng <enga@chromium.org>
|
||||
Commit-Queue: Shrek Shao <shrekshao@google.com>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1058233}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3956286
|
||||
Owners-Override: Prudhvikumar Bommana <pbommana@google.com>
|
||||
Reviewed-by: Prudhvikumar Bommana <pbommana@google.com>
|
||||
Commit-Queue: Prudhvikumar Bommana <pbommana@google.com>
|
||||
Cr-Commit-Position: refs/branch-heads/5249@{#850}
|
||||
Cr-Branched-From: 4f7bea5de862aaa52e6bde5920755a9ef9db120b-refs/heads/main@{#1036826}
|
||||
|
||||
diff --git a/gpu/command_buffer/service/dawn_service_memory_transfer_service.cc b/gpu/command_buffer/service/dawn_service_memory_transfer_service.cc
|
||||
index 579cd3cbdfcd5990db02960413bcac86e41c69b2..a15b6f9b3b345079d8cf8251ca5f77b6e7ef647a 100644
|
||||
--- a/gpu/command_buffer/service/dawn_service_memory_transfer_service.cc
|
||||
+++ b/gpu/command_buffer/service/dawn_service_memory_transfer_service.cc
|
||||
@@ -30,8 +30,13 @@ class ReadHandleImpl
|
||||
size_t offset,
|
||||
size_t size,
|
||||
void* serializePointer) override {
|
||||
- DCHECK_LE(offset, size_);
|
||||
- DCHECK_LE(size, size_ - offset);
|
||||
+ // TODO(crbug.com/1373314): A compromised renderer could have a shared
|
||||
+ // memory size not large enough to fit the GPU buffer contents. Instead of
|
||||
+ // DCHECK, do a CHECK here to crash the release build. The crash is fine
|
||||
+ // since it is not reachable from normal behavior. WebGPU post-V1 will have
|
||||
+ // a refactored API.
|
||||
+ CHECK_LE(offset, size_);
|
||||
+ CHECK_LE(size, size_ - offset);
|
||||
// Copy the data into the shared memory allocation.
|
||||
// In the case of buffer mapping, this is the mapped GPU memory which we
|
||||
// copy into client-visible shared memory.
|
||||
@@ -94,7 +99,10 @@ bool DawnServiceMemoryTransferService::DeserializeReadHandle(
|
||||
size_t deserialize_size,
|
||||
ReadHandle** read_handle) {
|
||||
DCHECK(deserialize_pointer);
|
||||
- DCHECK_EQ(deserialize_size, sizeof(MemoryTransferHandle));
|
||||
+ // Use CHECK instead of DCHECK because the cast of the memory to
|
||||
+ // MemoryTransferHandle and subsequent reads won't be safe if deserialize_size
|
||||
+ // is too small.
|
||||
+ CHECK_EQ(deserialize_size, sizeof(MemoryTransferHandle));
|
||||
const volatile MemoryTransferHandle* handle =
|
||||
reinterpret_cast<const volatile MemoryTransferHandle*>(
|
||||
deserialize_pointer);
|
||||
@@ -119,7 +127,10 @@ bool DawnServiceMemoryTransferService::DeserializeWriteHandle(
|
||||
size_t deserialize_size,
|
||||
WriteHandle** write_handle) {
|
||||
DCHECK(deserialize_pointer);
|
||||
- DCHECK_EQ(deserialize_size, sizeof(MemoryTransferHandle));
|
||||
+ // Use CHECK instead of DCHECK because the cast of the memory to
|
||||
+ // MemoryTransferHandle and subsequent reads won't be safe if deserialize_size
|
||||
+ // is too small.
|
||||
+ CHECK_EQ(deserialize_size, sizeof(MemoryTransferHandle));
|
||||
const volatile MemoryTransferHandle* handle =
|
||||
reinterpret_cast<const volatile MemoryTransferHandle*>(
|
||||
deserialize_pointer);
|
||||
305
patches/chromium/cherry-pick-fefd6198da31.patch
Normal file
305
patches/chromium/cherry-pick-fefd6198da31.patch
Normal file
@@ -0,0 +1,305 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Ben Wagner <benjaminwagner@google.com>
|
||||
Date: Tue, 20 Sep 2022 18:38:53 +0000
|
||||
Subject: Fix races in FrameQueueUnderlyingSource related to
|
||||
CrossThreadPersistent
|
||||
|
||||
The repro in bug 1323488 unfortunately does not reliably reproduce
|
||||
the races when run as a web test. I was also not able to repro the
|
||||
races in a unit test.
|
||||
|
||||
There are actually three fixes in this CL; it was easiest to fix them
|
||||
all together so that I can run the repro locally for an extended period
|
||||
without it being stopped by a crash.
|
||||
|
||||
The underlying cause for all three races is that CrossThreadPersistent
|
||||
can refer to an object whose heap has already been destroyed. When
|
||||
accessed on the thread corresponding to that heap, there is no race,
|
||||
but when accessed from a different thread, there is a period of time
|
||||
after the heap is destroyed before the CrossThreadPersistent is
|
||||
cleared.
|
||||
|
||||
1. The FrameQueueUnderlyingSource::transferred_source_ member's pointer
|
||||
is accessed in FrameQueueUnderlyingSource::Close. This CL adds a
|
||||
callback to clear the pointer in
|
||||
TransferredFrameQueueUnderlyingSource::ContextDestroyed.
|
||||
|
||||
2. The TransferredFrameQueueUnderlyingSource constructor takes a raw
|
||||
pointer to the original FrameQueueUnderlyingSource, which is
|
||||
associated with a different thread. GC won't be able to update this
|
||||
raw pointer since it's on the wrong stack. This CL changes the raw
|
||||
pointer to a CrossThreadPersistent which is visible to GC.
|
||||
|
||||
3. Same as 2, but for the callstack ConnectHostCallback,
|
||||
MediaStream(Audio|Video)TrackUnderlyingSource::OnSourceTransferStarted
|
||||
and FrameQueueUnderlyingSource::TransferSource.
|
||||
|
||||
(cherry picked from commit 63ce9c40e1a67395278dfc70ecfb545a818747bb)
|
||||
|
||||
Bug: 1323488
|
||||
Change-Id: Id63484eebefd2e003959b25bd752ac8263caab4f
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3865452
|
||||
Commit-Queue: Ben Wagner <benjaminwagner@google.com>
|
||||
Reviewed-by: Thomas Guilbert <tguilbert@chromium.org>
|
||||
Auto-Submit: Ben Wagner <benjaminwagner@google.com>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1041434}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3908010
|
||||
Commit-Queue: Srinivas Sista <srinivassista@chromium.org>
|
||||
Reviewed-by: Srinivas Sista <srinivassista@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/5249@{#521}
|
||||
Cr-Branched-From: 4f7bea5de862aaa52e6bde5920755a9ef9db120b-refs/heads/main@{#1036826}
|
||||
|
||||
diff --git a/third_party/blink/renderer/modules/breakout_box/frame_queue_transferring_optimizer.cc b/third_party/blink/renderer/modules/breakout_box/frame_queue_transferring_optimizer.cc
|
||||
index 2cc89e8cd32421bf80b262bac2e4a7cb685db62f..ab41fa086ad9eb8c1cd66db74ea1f05a66ac56a4 100644
|
||||
--- a/third_party/blink/renderer/modules/breakout_box/frame_queue_transferring_optimizer.cc
|
||||
+++ b/third_party/blink/renderer/modules/breakout_box/frame_queue_transferring_optimizer.cc
|
||||
@@ -19,10 +19,13 @@ FrameQueueTransferringOptimizer<NativeFrameType>::
|
||||
FrameQueueHost* host,
|
||||
scoped_refptr<base::SequencedTaskRunner> host_runner,
|
||||
wtf_size_t max_queue_size,
|
||||
- ConnectHostCallback connect_host_callback)
|
||||
+ ConnectHostCallback connect_host_callback,
|
||||
+ CrossThreadOnceClosure transferred_source_destroyed_callback)
|
||||
: host_(host),
|
||||
host_runner_(std::move(host_runner)),
|
||||
connect_host_callback_(std::move(connect_host_callback)),
|
||||
+ transferred_source_destroyed_callback_(
|
||||
+ std::move(transferred_source_destroyed_callback)),
|
||||
max_queue_size_(max_queue_size) {}
|
||||
|
||||
template <typename NativeFrameType>
|
||||
@@ -40,7 +43,8 @@ FrameQueueTransferringOptimizer<NativeFrameType>::PerformInProcessOptimization(
|
||||
|
||||
auto* source = MakeGarbageCollected<
|
||||
TransferredFrameQueueUnderlyingSource<NativeFrameType>>(
|
||||
- script_state, host, host_runner_);
|
||||
+ script_state, host, host_runner_,
|
||||
+ std::move(transferred_source_destroyed_callback_));
|
||||
|
||||
PostCrossThreadTask(
|
||||
*host_runner_, FROM_HERE,
|
||||
diff --git a/third_party/blink/renderer/modules/breakout_box/frame_queue_transferring_optimizer.h b/third_party/blink/renderer/modules/breakout_box/frame_queue_transferring_optimizer.h
|
||||
index 6d33945b7c840e55ae73a1efd1f1cf33ccfaaa71..336073235ba7f6c05cf2cf19fccbfac0be9597c9 100644
|
||||
--- a/third_party/blink/renderer/modules/breakout_box/frame_queue_transferring_optimizer.h
|
||||
+++ b/third_party/blink/renderer/modules/breakout_box/frame_queue_transferring_optimizer.h
|
||||
@@ -25,13 +25,15 @@ class FrameQueueTransferringOptimizer final
|
||||
|
||||
using ConnectHostCallback = CrossThreadOnceFunction<void(
|
||||
scoped_refptr<base::SequencedTaskRunner>,
|
||||
- TransferredFrameQueueUnderlyingSource<NativeFrameType>*)>;
|
||||
+ CrossThreadPersistent<
|
||||
+ TransferredFrameQueueUnderlyingSource<NativeFrameType>>)>;
|
||||
|
||||
FrameQueueTransferringOptimizer(
|
||||
FrameQueueHost*,
|
||||
scoped_refptr<base::SequencedTaskRunner> host_runner,
|
||||
wtf_size_t max_queue_size,
|
||||
- ConnectHostCallback callback);
|
||||
+ ConnectHostCallback connect_host_callback,
|
||||
+ CrossThreadOnceFunction<void()> transferred_source_destroyed_callback);
|
||||
~FrameQueueTransferringOptimizer() override = default;
|
||||
|
||||
UnderlyingSourceBase* PerformInProcessOptimization(
|
||||
@@ -41,6 +43,7 @@ class FrameQueueTransferringOptimizer final
|
||||
CrossThreadWeakPersistent<FrameQueueHost> host_;
|
||||
scoped_refptr<base::SequencedTaskRunner> host_runner_;
|
||||
ConnectHostCallback connect_host_callback_;
|
||||
+ CrossThreadOnceFunction<void()> transferred_source_destroyed_callback_;
|
||||
wtf_size_t max_queue_size_;
|
||||
};
|
||||
|
||||
diff --git a/third_party/blink/renderer/modules/breakout_box/frame_queue_underlying_source.cc b/third_party/blink/renderer/modules/breakout_box/frame_queue_underlying_source.cc
|
||||
index b93b67f131e1e58118e32d2c9b29e472a28d4664..fcd676b3035e19c6e0b28ee1c44109c6737a1c35 100644
|
||||
--- a/third_party/blink/renderer/modules/breakout_box/frame_queue_underlying_source.cc
|
||||
+++ b/third_party/blink/renderer/modules/breakout_box/frame_queue_underlying_source.cc
|
||||
@@ -266,15 +266,22 @@ double FrameQueueUnderlyingSource<NativeFrameType>::DesiredSizeForTesting()
|
||||
|
||||
template <typename NativeFrameType>
|
||||
void FrameQueueUnderlyingSource<NativeFrameType>::TransferSource(
|
||||
- FrameQueueUnderlyingSource<NativeFrameType>* transferred_source) {
|
||||
+ CrossThreadPersistent<FrameQueueUnderlyingSource<NativeFrameType>>
|
||||
+ transferred_source) {
|
||||
DCHECK(realm_task_runner_->RunsTasksInCurrentSequence());
|
||||
MutexLocker locker(mutex_);
|
||||
DCHECK(!transferred_source_);
|
||||
- transferred_source_ = transferred_source;
|
||||
+ transferred_source_ = std::move(transferred_source);
|
||||
CloseController();
|
||||
frame_queue_handle_.Invalidate();
|
||||
}
|
||||
|
||||
+template <typename NativeFrameType>
|
||||
+void FrameQueueUnderlyingSource<NativeFrameType>::ClearTransferredSource() {
|
||||
+ MutexLocker locker(mutex_);
|
||||
+ transferred_source_.Clear();
|
||||
+}
|
||||
+
|
||||
template <typename NativeFrameType>
|
||||
void FrameQueueUnderlyingSource<NativeFrameType>::CloseController() {
|
||||
DCHECK(realm_task_runner_->RunsTasksInCurrentSequence());
|
||||
diff --git a/third_party/blink/renderer/modules/breakout_box/frame_queue_underlying_source.h b/third_party/blink/renderer/modules/breakout_box/frame_queue_underlying_source.h
|
||||
index 7e097b4eb6e9085be73ceb7fd84a4588baf64471..3908909d04f5b6cf4a9be4a3a3e004c3775a3d42 100644
|
||||
--- a/third_party/blink/renderer/modules/breakout_box/frame_queue_underlying_source.h
|
||||
+++ b/third_party/blink/renderer/modules/breakout_box/frame_queue_underlying_source.h
|
||||
@@ -85,7 +85,13 @@ class FrameQueueUnderlyingSource
|
||||
// QueueFrame(). |transferred_source| will pull frames from the same circular
|
||||
// queue. Must be called on |realm_task_runner_|.
|
||||
void TransferSource(
|
||||
- FrameQueueUnderlyingSource<NativeFrameType>* transferred_source);
|
||||
+ CrossThreadPersistent<FrameQueueUnderlyingSource<NativeFrameType>>
|
||||
+ transferred_source);
|
||||
+
|
||||
+ // Due to a potential race condition between |transferred_source_|'s heap
|
||||
+ // being destroyed and the Close() method being called, we need to explicitly
|
||||
+ // clear |transferred_source_| when its context is being destroyed.
|
||||
+ void ClearTransferredSource();
|
||||
|
||||
protected:
|
||||
bool MustUseMonitor() const;
|
||||
diff --git a/third_party/blink/renderer/modules/breakout_box/media_stream_audio_track_underlying_source.cc b/third_party/blink/renderer/modules/breakout_box/media_stream_audio_track_underlying_source.cc
|
||||
index bfc966452e4134e5133d559698497ce82f89aad4..da9a4bffc3a8c9ec5a1595a7cd78110bfadbfb5e 100644
|
||||
--- a/third_party/blink/renderer/modules/breakout_box/media_stream_audio_track_underlying_source.cc
|
||||
+++ b/third_party/blink/renderer/modules/breakout_box/media_stream_audio_track_underlying_source.cc
|
||||
@@ -93,14 +93,17 @@ MediaStreamAudioTrackUnderlyingSource::GetTransferringOptimizer() {
|
||||
this, GetRealmRunner(), MaxQueueSize(),
|
||||
CrossThreadBindOnce(
|
||||
&MediaStreamAudioTrackUnderlyingSource::OnSourceTransferStarted,
|
||||
+ WrapCrossThreadWeakPersistent(this)),
|
||||
+ CrossThreadBindOnce(
|
||||
+ &MediaStreamAudioTrackUnderlyingSource::ClearTransferredSource,
|
||||
WrapCrossThreadWeakPersistent(this)));
|
||||
}
|
||||
|
||||
void MediaStreamAudioTrackUnderlyingSource::OnSourceTransferStarted(
|
||||
scoped_refptr<base::SequencedTaskRunner> transferred_runner,
|
||||
- TransferredAudioDataQueueUnderlyingSource* source) {
|
||||
+ CrossThreadPersistent<TransferredAudioDataQueueUnderlyingSource> source) {
|
||||
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
||||
- TransferSource(source);
|
||||
+ TransferSource(std::move(source));
|
||||
RecordBreakoutBoxUsage(BreakoutBoxUsage::kReadableAudioWorker);
|
||||
}
|
||||
|
||||
diff --git a/third_party/blink/renderer/modules/breakout_box/media_stream_audio_track_underlying_source.h b/third_party/blink/renderer/modules/breakout_box/media_stream_audio_track_underlying_source.h
|
||||
index 19a290ea6b83e4b56b8d96cb7632fca55bd65fd0..73c16dc5ff3855e258e1e70397def478485f1481 100644
|
||||
--- a/third_party/blink/renderer/modules/breakout_box/media_stream_audio_track_underlying_source.h
|
||||
+++ b/third_party/blink/renderer/modules/breakout_box/media_stream_audio_track_underlying_source.h
|
||||
@@ -56,7 +56,7 @@ class MODULES_EXPORT MediaStreamAudioTrackUnderlyingSource
|
||||
void DisconnectFromTrack();
|
||||
void OnSourceTransferStarted(
|
||||
scoped_refptr<base::SequencedTaskRunner> transferred_runner,
|
||||
- TransferredAudioDataQueueUnderlyingSource* source);
|
||||
+ CrossThreadPersistent<TransferredAudioDataQueueUnderlyingSource> source);
|
||||
|
||||
// Only used to prevent the gargabe collector from reclaiming the media
|
||||
// stream track processor that created |this|.
|
||||
diff --git a/third_party/blink/renderer/modules/breakout_box/media_stream_video_track_underlying_source.cc b/third_party/blink/renderer/modules/breakout_box/media_stream_video_track_underlying_source.cc
|
||||
index bcb941aca4e4d0729dc1253e01ef477fdaae1877..e748bf6eaf8f9d1acf8519c38a5a8cb53b031d0e 100644
|
||||
--- a/third_party/blink/renderer/modules/breakout_box/media_stream_video_track_underlying_source.cc
|
||||
+++ b/third_party/blink/renderer/modules/breakout_box/media_stream_video_track_underlying_source.cc
|
||||
@@ -66,6 +66,9 @@ MediaStreamVideoTrackUnderlyingSource::GetStreamTransferOptimizer() {
|
||||
this, GetRealmRunner(), MaxQueueSize(),
|
||||
CrossThreadBindOnce(
|
||||
&MediaStreamVideoTrackUnderlyingSource::OnSourceTransferStarted,
|
||||
+ WrapCrossThreadWeakPersistent(this)),
|
||||
+ CrossThreadBindOnce(
|
||||
+ &MediaStreamVideoTrackUnderlyingSource::ClearTransferredSource,
|
||||
WrapCrossThreadWeakPersistent(this)));
|
||||
}
|
||||
|
||||
@@ -76,9 +79,9 @@ MediaStreamVideoTrackUnderlyingSource::GetIOTaskRunner() {
|
||||
|
||||
void MediaStreamVideoTrackUnderlyingSource::OnSourceTransferStarted(
|
||||
scoped_refptr<base::SequencedTaskRunner> transferred_runner,
|
||||
- TransferredVideoFrameQueueUnderlyingSource* source) {
|
||||
+ CrossThreadPersistent<TransferredVideoFrameQueueUnderlyingSource> source) {
|
||||
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
||||
- TransferSource(source);
|
||||
+ TransferSource(std::move(source));
|
||||
RecordBreakoutBoxUsage(BreakoutBoxUsage::kReadableVideoWorker);
|
||||
}
|
||||
|
||||
diff --git a/third_party/blink/renderer/modules/breakout_box/media_stream_video_track_underlying_source.h b/third_party/blink/renderer/modules/breakout_box/media_stream_video_track_underlying_source.h
|
||||
index 1bbd4f6bbf20eaf168bf1319f1b35819dabe3cce..8964eb5eb83964c4bb2633092a12cb144da4e9b0 100644
|
||||
--- a/third_party/blink/renderer/modules/breakout_box/media_stream_video_track_underlying_source.h
|
||||
+++ b/third_party/blink/renderer/modules/breakout_box/media_stream_video_track_underlying_source.h
|
||||
@@ -59,8 +59,9 @@ class MODULES_EXPORT MediaStreamVideoTrackUnderlyingSource
|
||||
bool StartFrameDelivery() override;
|
||||
void StopFrameDelivery() override;
|
||||
|
||||
- void OnSourceTransferStarted(scoped_refptr<base::SequencedTaskRunner>,
|
||||
- TransferredVideoFrameQueueUnderlyingSource*);
|
||||
+ void OnSourceTransferStarted(
|
||||
+ scoped_refptr<base::SequencedTaskRunner>,
|
||||
+ CrossThreadPersistent<TransferredVideoFrameQueueUnderlyingSource>);
|
||||
|
||||
void OnFrameFromTrack(
|
||||
scoped_refptr<media::VideoFrame> media_frame,
|
||||
diff --git a/third_party/blink/renderer/modules/breakout_box/transferred_frame_queue_underlying_source.cc b/third_party/blink/renderer/modules/breakout_box/transferred_frame_queue_underlying_source.cc
|
||||
index 5c62b8f1b752c24f8b8d0048d646ea64dba0e49c..e38173482d455788861a1d831dd3422119d4d4d6 100644
|
||||
--- a/third_party/blink/renderer/modules/breakout_box/transferred_frame_queue_underlying_source.cc
|
||||
+++ b/third_party/blink/renderer/modules/breakout_box/transferred_frame_queue_underlying_source.cc
|
||||
@@ -15,11 +15,14 @@ template <typename NativeFrameType>
|
||||
TransferredFrameQueueUnderlyingSource<NativeFrameType>::
|
||||
TransferredFrameQueueUnderlyingSource(
|
||||
ScriptState* script_state,
|
||||
- FrameQueueHost* host,
|
||||
- scoped_refptr<base::SequencedTaskRunner> host_runner)
|
||||
+ CrossThreadPersistent<FrameQueueHost> host,
|
||||
+ scoped_refptr<base::SequencedTaskRunner> host_runner,
|
||||
+ CrossThreadOnceClosure transferred_source_destroyed_callback)
|
||||
: FrameQueueUnderlyingSource<NativeFrameType>(script_state, host),
|
||||
host_runner_(host_runner),
|
||||
- host_(host) {}
|
||||
+ host_(std::move(host)),
|
||||
+ transferred_source_destroyed_callback_(
|
||||
+ std::move(transferred_source_destroyed_callback)) {}
|
||||
|
||||
template <typename NativeFrameType>
|
||||
bool TransferredFrameQueueUnderlyingSource<
|
||||
@@ -44,6 +47,13 @@ void TransferredFrameQueueUnderlyingSource<
|
||||
CrossThreadBindOnce(&FrameQueueHost::Close, host_));
|
||||
}
|
||||
|
||||
+template <typename NativeFrameType>
|
||||
+void TransferredFrameQueueUnderlyingSource<
|
||||
+ NativeFrameType>::ContextDestroyed() {
|
||||
+ std::move(transferred_source_destroyed_callback_).Run();
|
||||
+ FrameQueueUnderlyingSource<NativeFrameType>::ContextDestroyed();
|
||||
+}
|
||||
+
|
||||
template <typename NativeFrameType>
|
||||
void TransferredFrameQueueUnderlyingSource<NativeFrameType>::Trace(
|
||||
Visitor* visitor) const {
|
||||
diff --git a/third_party/blink/renderer/modules/breakout_box/transferred_frame_queue_underlying_source.h b/third_party/blink/renderer/modules/breakout_box/transferred_frame_queue_underlying_source.h
|
||||
index 5f8a36719407a404756d672530c0b9fcff9d6924..7cd3270fbb3cf5b0e2c09b16000ea5c0e4247866 100644
|
||||
--- a/third_party/blink/renderer/modules/breakout_box/transferred_frame_queue_underlying_source.h
|
||||
+++ b/third_party/blink/renderer/modules/breakout_box/transferred_frame_queue_underlying_source.h
|
||||
@@ -19,8 +19,9 @@ class TransferredFrameQueueUnderlyingSource
|
||||
|
||||
TransferredFrameQueueUnderlyingSource(
|
||||
ScriptState*,
|
||||
- FrameQueueHost*,
|
||||
- scoped_refptr<base::SequencedTaskRunner> host_runner);
|
||||
+ CrossThreadPersistent<FrameQueueHost>,
|
||||
+ scoped_refptr<base::SequencedTaskRunner> host_runner,
|
||||
+ CrossThreadOnceClosure transferred_source_destroyed_callback);
|
||||
~TransferredFrameQueueUnderlyingSource() override = default;
|
||||
|
||||
TransferredFrameQueueUnderlyingSource(
|
||||
@@ -32,11 +33,15 @@ class TransferredFrameQueueUnderlyingSource
|
||||
bool StartFrameDelivery() override;
|
||||
void StopFrameDelivery() override;
|
||||
|
||||
+ // ExecutionLifecycleObserver
|
||||
+ void ContextDestroyed() override;
|
||||
+
|
||||
void Trace(Visitor*) const override;
|
||||
|
||||
private:
|
||||
scoped_refptr<base::SequencedTaskRunner> host_runner_;
|
||||
CrossThreadPersistent<FrameQueueHost> host_;
|
||||
+ CrossThreadOnceClosure transferred_source_destroyed_callback_;
|
||||
};
|
||||
|
||||
extern template class MODULES_EXTERN_TEMPLATE_EXPORT
|
||||
47
patches/chromium/chore_add_electron_deps_to_gitignores.patch
Normal file
47
patches/chromium/chore_add_electron_deps_to_gitignores.patch
Normal file
@@ -0,0 +1,47 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Samuel Attard <sattard@salesforce.com>
|
||||
Date: Tue, 26 Jul 2022 00:05:29 -0700
|
||||
Subject: chore: add electron deps to gitignores
|
||||
|
||||
Makes things like "git status" quicker when developing electron locally
|
||||
|
||||
diff --git a/.gitignore b/.gitignore
|
||||
index b58c0d6e0a610837436ba0f45d31738edcc46a4f..5dc9f119a0a5b8dd64373ccf1bf2b2b752be8c0f 100644
|
||||
--- a/.gitignore
|
||||
+++ b/.gitignore
|
||||
@@ -229,6 +229,7 @@ vs-chromium-project.txt
|
||||
/delegate_execute
|
||||
/device/serial/device_serial_mojo.xml
|
||||
/docs/website
|
||||
+/electron
|
||||
/google_apis/gcm/gcm.xml
|
||||
/google_apis/internal
|
||||
/googleurl
|
||||
diff --git a/third_party/.gitignore b/third_party/.gitignore
|
||||
index 4d334479b45b93a182e9b92d889193726bb8e996..14663fdd6b909cd8b7c0538ebf9b2e5c19c3b75c 100644
|
||||
--- a/third_party/.gitignore
|
||||
+++ b/third_party/.gitignore
|
||||
@@ -83,6 +83,7 @@
|
||||
/directxsdk
|
||||
/dom_distiller_js/dist
|
||||
/eigen3/src
|
||||
+/electron_node
|
||||
/elfutils/src
|
||||
/emoji-segmenter/src
|
||||
/emoji-metadata/src
|
||||
@@ -178,6 +179,7 @@
|
||||
/mocha
|
||||
/mockito/src
|
||||
/nacl_sdk_binaries/
|
||||
+/nan
|
||||
/nasm
|
||||
/nearby/src
|
||||
/neon_2_sse/src
|
||||
@@ -241,6 +243,7 @@
|
||||
/speex
|
||||
/sqlite/src
|
||||
/sqlite4java/lib/
|
||||
+/squirrel.mac
|
||||
/subresource-filter-ruleset/data/UnindexedRules
|
||||
/swift-format
|
||||
/swiftshader/
|
||||
@@ -0,0 +1,76 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: deepak1556 <hop2deep@gmail.com>
|
||||
Date: Fri, 29 Jul 2022 00:29:35 +0900
|
||||
Subject: chore: allow chromium to handle synthetic mouse events for touch
|
||||
|
||||
With WCO, allow chromium to handle synthetic mouse events generated for touch
|
||||
actions in the non-client caption area.
|
||||
|
||||
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
|
||||
index f6b37bdec2343d45447b419aeadbe2aa19493c3c..bdbf7153f27376bd68459f9cb480bff7485c9e98 100644
|
||||
--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
|
||||
+++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
|
||||
@@ -1169,6 +1169,10 @@ void DesktopWindowTreeHostWin::HandleWindowScaleFactorChanged(
|
||||
}
|
||||
}
|
||||
|
||||
+bool DesktopWindowTreeHostWin::HandleMouseEventForCaption(UINT message) const {
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
DesktopNativeCursorManager*
|
||||
DesktopWindowTreeHostWin::GetSingletonDesktopNativeCursorManager() {
|
||||
return new DesktopNativeCursorManagerWin();
|
||||
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h
|
||||
index 0aae49ec83b88057434af5bbfb54b10e53469918..058e5dc978e76a71fa02dc9e275592f3c39befea 100644
|
||||
--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h
|
||||
+++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h
|
||||
@@ -263,6 +263,7 @@ class VIEWS_EXPORT DesktopWindowTreeHostWin
|
||||
void HandleWindowSizeChanging() override;
|
||||
void HandleWindowSizeUnchanged() override;
|
||||
void HandleWindowScaleFactorChanged(float window_scale_factor) override;
|
||||
+ bool HandleMouseEventForCaption(UINT message) const override;
|
||||
|
||||
Widget* GetWidget();
|
||||
const Widget* GetWidget() const;
|
||||
diff --git a/ui/views/win/hwnd_message_handler.cc b/ui/views/win/hwnd_message_handler.cc
|
||||
index 7c7952755317a8069becfff58ca5ec89e2266ce4..6496933a9c84c337b6ba25276badf7728eeabdfb 100644
|
||||
--- a/ui/views/win/hwnd_message_handler.cc
|
||||
+++ b/ui/views/win/hwnd_message_handler.cc
|
||||
@@ -3129,15 +3129,19 @@ LRESULT HWNDMessageHandler::HandleMouseEventInternal(UINT message,
|
||||
SetMsgHandled(FALSE);
|
||||
// We must let Windows handle the caption buttons if it's drawing them, or
|
||||
// they won't work.
|
||||
+ bool simulate_mouse_event_for_caption = false;
|
||||
if (delegate_->GetFrameMode() == FrameMode::SYSTEM_DRAWN &&
|
||||
(hittest == HTCLOSE || hittest == HTMINBUTTON ||
|
||||
hittest == HTMAXBUTTON)) {
|
||||
- SetMsgHandled(FALSE);
|
||||
+ simulate_mouse_event_for_caption =
|
||||
+ delegate_->HandleMouseEventForCaption(message);
|
||||
+ if (!simulate_mouse_event_for_caption)
|
||||
+ SetMsgHandled(FALSE);
|
||||
}
|
||||
// Let resize events fall through. Ignore everything else, as we're either
|
||||
// letting Windows handle it above or we've already handled the equivalent
|
||||
// touch message.
|
||||
- if (!IsHitTestOnResizeHandle(hittest))
|
||||
+ if (!IsHitTestOnResizeHandle(hittest) && !simulate_mouse_event_for_caption)
|
||||
return 0;
|
||||
}
|
||||
|
||||
diff --git a/ui/views/win/hwnd_message_handler_delegate.h b/ui/views/win/hwnd_message_handler_delegate.h
|
||||
index 5dbb192d0840ca0ded61397c399b774a8cb05cce..098a9c3140e9e140fdc8f0dc9cf4e8ec84451221 100644
|
||||
--- a/ui/views/win/hwnd_message_handler_delegate.h
|
||||
+++ b/ui/views/win/hwnd_message_handler_delegate.h
|
||||
@@ -258,6 +258,10 @@ class VIEWS_EXPORT HWNDMessageHandlerDelegate {
|
||||
// Called when the window scale factor has changed.
|
||||
virtual void HandleWindowScaleFactorChanged(float window_scale_factor) = 0;
|
||||
|
||||
+ // Called when synthetic mouse event is generated for touch event on
|
||||
+ // caption buttons.
|
||||
+ virtual bool HandleMouseEventForCaption(UINT message) const = 0;
|
||||
+
|
||||
protected:
|
||||
virtual ~HWNDMessageHandlerDelegate() = default;
|
||||
};
|
||||
@@ -246,10 +246,10 @@ index c6bd5c19f8a7ceec17c9e32af5296a9617f3a619..02199b439fba7fdc617b7f7980d958b7
|
||||
void AddNewContents(content::WebContents* source,
|
||||
std::unique_ptr<content::WebContents> new_contents,
|
||||
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
|
||||
index 889da8724da515ab7e6b412fbaff434eb53289dc..7dba296aaa55b9aa6026ccdf288171f701601f46 100644
|
||||
index eae322cb4bcc66556c36f1df2c31537039d4a4b1..fb1bb27a5471912c0f40f2b989762d52058e19fa 100644
|
||||
--- a/content/browser/web_contents/web_contents_impl.cc
|
||||
+++ b/content/browser/web_contents/web_contents_impl.cc
|
||||
@@ -3880,8 +3880,7 @@ FrameTree* WebContentsImpl::CreateNewWindow(
|
||||
@@ -3898,8 +3898,7 @@ FrameTree* WebContentsImpl::CreateNewWindow(
|
||||
|
||||
if (delegate_ && delegate_->IsWebContentsCreationOverridden(
|
||||
source_site_instance, params.window_container_type,
|
||||
|
||||
156
patches/chromium/create_browser_v8_snapshot_file_name_fuse.patch
Normal file
156
patches/chromium/create_browser_v8_snapshot_file_name_fuse.patch
Normal file
@@ -0,0 +1,156 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Ryan Manuel <ryanm@cypress.io>
|
||||
Date: Thu, 4 Aug 2022 22:37:01 -0500
|
||||
Subject: Create browser v8 snapshot file name fuse
|
||||
|
||||
By default, chromium sets up one v8 snapshot to be used in all v8 contexts. This patch allows consumers
|
||||
to have a dedicated browser process v8 snapshot defined by the file `browser_v8_context_snapshot.bin`.
|
||||
|
||||
diff --git a/content/app/content_main_runner_impl.cc b/content/app/content_main_runner_impl.cc
|
||||
index 328f8b800c36544f7906536416ac61dc87cc45d3..2f973efcf3e38edcc74060929339fc21bdf0aa3b 100644
|
||||
--- a/content/app/content_main_runner_impl.cc
|
||||
+++ b/content/app/content_main_runner_impl.cc
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "base/process/memory.h"
|
||||
#include "base/process/process.h"
|
||||
#include "base/process/process_handle.h"
|
||||
+#include "base/strings/string_piece.h"
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/task/thread_pool/thread_pool_instance.h"
|
||||
@@ -232,8 +233,13 @@ std::string GetSnapshotDataDescriptor(const base::CommandLine& command_line) {
|
||||
|
||||
#endif
|
||||
|
||||
-void LoadV8SnapshotFile(const base::CommandLine& command_line) {
|
||||
+void LoadV8SnapshotFile(const raw_ptr<ContentMainDelegate> delegate, const base::CommandLine& command_line) {
|
||||
const gin::V8SnapshotFileType snapshot_type = GetSnapshotType(command_line);
|
||||
+ base::StringPiece browser_v8_snapshot_file_name = delegate->GetBrowserV8SnapshotFilename();
|
||||
+ if (!browser_v8_snapshot_file_name.empty()) {
|
||||
+ gin::V8Initializer::LoadV8SnapshotFromFileName(browser_v8_snapshot_file_name, snapshot_type);
|
||||
+ return;
|
||||
+ }
|
||||
#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_MAC)
|
||||
base::FileDescriptorStore& file_descriptor_store =
|
||||
base::FileDescriptorStore::GetInstance();
|
||||
@@ -262,11 +268,12 @@ bool ShouldLoadV8Snapshot(const base::CommandLine& command_line,
|
||||
|
||||
#endif // V8_USE_EXTERNAL_STARTUP_DATA
|
||||
|
||||
-void LoadV8SnapshotIfNeeded(const base::CommandLine& command_line,
|
||||
+void LoadV8SnapshotIfNeeded(const raw_ptr<ContentMainDelegate> delegate,
|
||||
+ const base::CommandLine& command_line,
|
||||
const std::string& process_type) {
|
||||
#if defined(V8_USE_EXTERNAL_STARTUP_DATA)
|
||||
if (ShouldLoadV8Snapshot(command_line, process_type))
|
||||
- LoadV8SnapshotFile(command_line);
|
||||
+ LoadV8SnapshotFile(delegate, command_line);
|
||||
#endif // V8_USE_EXTERNAL_STARTUP_DATA
|
||||
}
|
||||
|
||||
@@ -917,7 +924,7 @@ int ContentMainRunnerImpl::Initialize(ContentMainParams params) {
|
||||
return TerminateForFatalInitializationError();
|
||||
#endif // BUILDFLAG(IS_ANDROID) && (ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_FILE)
|
||||
|
||||
- LoadV8SnapshotIfNeeded(command_line, process_type);
|
||||
+ LoadV8SnapshotIfNeeded(delegate_, command_line, process_type);
|
||||
|
||||
blink::TrialTokenValidator::SetOriginTrialPolicyGetter(
|
||||
base::BindRepeating([]() -> blink::OriginTrialPolicy* {
|
||||
diff --git a/content/public/app/content_main_delegate.cc b/content/public/app/content_main_delegate.cc
|
||||
index ce6b8b454d0cc57ec4de81c7a19b5e0f0087a162..c421d3b5bc02b702e89c714d3d521207cbca156b 100644
|
||||
--- a/content/public/app/content_main_delegate.cc
|
||||
+++ b/content/public/app/content_main_delegate.cc
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "content/public/app/content_main_delegate.h"
|
||||
|
||||
#include "base/check.h"
|
||||
+#include "base/strings/string_piece.h"
|
||||
#include "build/build_config.h"
|
||||
#include "content/public/browser/content_browser_client.h"
|
||||
#include "content/public/common/content_client.h"
|
||||
@@ -55,6 +56,10 @@ ContentMainDelegate::CreateVariationsIdsProvider() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
+base::StringPiece ContentMainDelegate::GetBrowserV8SnapshotFilename() {
|
||||
+ return base::StringPiece();
|
||||
+}
|
||||
+
|
||||
ContentClient* ContentMainDelegate::CreateContentClient() {
|
||||
return new ContentClient();
|
||||
}
|
||||
diff --git a/content/public/app/content_main_delegate.h b/content/public/app/content_main_delegate.h
|
||||
index f81430b564a3cf44c2168e18c4c53c6629353d75..34a5531cd33b439114a796adc71af7251b6b1f81 100644
|
||||
--- a/content/public/app/content_main_delegate.h
|
||||
+++ b/content/public/app/content_main_delegate.h
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
+#include "base/strings/string_piece.h"
|
||||
#include "build/build_config.h"
|
||||
#include "content/common/content_export.h"
|
||||
#include "content/public/common/main_function_params.h"
|
||||
@@ -149,6 +150,8 @@ class CONTENT_EXPORT ContentMainDelegate {
|
||||
virtual bool ShouldHandleConsoleControlEvents();
|
||||
#endif
|
||||
|
||||
+ virtual base::StringPiece GetBrowserV8SnapshotFilename();
|
||||
+
|
||||
protected:
|
||||
friend class ContentClientCreator;
|
||||
friend class ContentClientInitializer;
|
||||
diff --git a/gin/v8_initializer.cc b/gin/v8_initializer.cc
|
||||
index 34a65998cbaa22241fd7c6cc60d8ab01982ca3ce..68c12e9bb1f334d6fec050018da8bc0a6db4a850 100644
|
||||
--- a/gin/v8_initializer.cc
|
||||
+++ b/gin/v8_initializer.cc
|
||||
@@ -512,8 +512,7 @@ void V8Initializer::GetV8ExternalSnapshotData(const char** snapshot_data_out,
|
||||
|
||||
#if defined(V8_USE_EXTERNAL_STARTUP_DATA)
|
||||
|
||||
-// static
|
||||
-void V8Initializer::LoadV8Snapshot(V8SnapshotFileType snapshot_file_type) {
|
||||
+void V8Initializer::LoadV8SnapshotFromFileName(base::StringPiece file_name, V8SnapshotFileType snapshot_file_type) {
|
||||
if (g_mapped_snapshot) {
|
||||
// TODO(crbug.com/802962): Confirm not loading different type of snapshot
|
||||
// files in a process.
|
||||
@@ -522,10 +521,17 @@ void V8Initializer::LoadV8Snapshot(V8SnapshotFileType snapshot_file_type) {
|
||||
|
||||
base::MemoryMappedFile::Region file_region;
|
||||
base::File file =
|
||||
- OpenV8File(GetSnapshotFileName(snapshot_file_type), &file_region);
|
||||
+ OpenV8File(file_name.data(), &file_region);
|
||||
LoadV8SnapshotFromFile(std::move(file), &file_region, snapshot_file_type);
|
||||
}
|
||||
|
||||
+// static
|
||||
+void V8Initializer::LoadV8Snapshot(V8SnapshotFileType snapshot_file_type) {
|
||||
+ const char* file_name = GetSnapshotFileName(snapshot_file_type);
|
||||
+
|
||||
+ LoadV8SnapshotFromFileName(file_name, snapshot_file_type);
|
||||
+}
|
||||
+
|
||||
// static
|
||||
void V8Initializer::LoadV8SnapshotFromFile(
|
||||
base::File snapshot_file,
|
||||
diff --git a/gin/v8_initializer.h b/gin/v8_initializer.h
|
||||
index 13a120c7fe8e69a44793473f3124c33d572a07a3..acb294780873c1d84546eb2b9acc00f86838361d 100644
|
||||
--- a/gin/v8_initializer.h
|
||||
+++ b/gin/v8_initializer.h
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include "base/files/file.h"
|
||||
#include "base/files/memory_mapped_file.h"
|
||||
+#include "base/strings/string_piece.h"
|
||||
#include "build/build_config.h"
|
||||
#include "gin/array_buffer.h"
|
||||
#include "gin/gin_export.h"
|
||||
@@ -42,6 +43,7 @@ class GIN_EXPORT V8Initializer {
|
||||
int* snapshot_size_out);
|
||||
|
||||
#if defined(V8_USE_EXTERNAL_STARTUP_DATA)
|
||||
+ static void LoadV8SnapshotFromFileName(base::StringPiece file_name, V8SnapshotFileType snapshot_file_type);
|
||||
// Load V8 snapshot from default resources, if they are available.
|
||||
static void LoadV8Snapshot(
|
||||
V8SnapshotFileType snapshot_file_type = V8SnapshotFileType::kDefault);
|
||||
@@ -20,14 +20,15 @@ to deal with color spaces. That is being tracked at
|
||||
https://crbug.com/634542 and https://crbug.com/711107.
|
||||
|
||||
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
|
||||
index 5ab61f6045aea2bf35ed25bd05270f044cbd8dd6..85875fe07d9eaf60406f60e6ffcd10dd06a265a6 100644
|
||||
index aca208728d0dae78e57bf4b7f0af46ed5ad73e68..2afef2fb0d3890bdada7d5785a4a48494d580cab 100644
|
||||
--- a/cc/trees/layer_tree_host_impl.cc
|
||||
+++ b/cc/trees/layer_tree_host_impl.cc
|
||||
@@ -1852,6 +1852,9 @@ void LayerTreeHostImpl::SetIsLikelyToRequireADraw(
|
||||
@@ -1852,6 +1852,10 @@ void LayerTreeHostImpl::SetIsLikelyToRequireADraw(
|
||||
TargetColorParams LayerTreeHostImpl::GetTargetColorParams(
|
||||
gfx::ContentColorUsage content_color_usage) const {
|
||||
TargetColorParams params;
|
||||
+ if (!settings_.enable_color_correct_rendering) {
|
||||
+ params.color_space = gfx::ColorSpace();
|
||||
+ return params;
|
||||
+ }
|
||||
|
||||
@@ -112,7 +113,7 @@ index 73a50b19f8bf75119b6af7698cdf7d569c504e77..9fdc3d5235a95cfc9ef3b94ba9c19630
|
||||
sandbox::policy::switches::kDisableSeccompFilterSandbox,
|
||||
sandbox::policy::switches::kNoSandbox,
|
||||
diff --git a/third_party/blink/renderer/platform/graphics/canvas_color_params.cc b/third_party/blink/renderer/platform/graphics/canvas_color_params.cc
|
||||
index 75d7af9a79d4e7f2cd39e45496ab5fff66407638..b4ddafdd126edd16172f00448bbbd56eaf509b1f 100644
|
||||
index 75d7af9a79d4e7f2cd39e45496ab5fff66407638..35b0bb908245330fbdc5205caa3299bf6fd8f7b4 100644
|
||||
--- a/third_party/blink/renderer/platform/graphics/canvas_color_params.cc
|
||||
+++ b/third_party/blink/renderer/platform/graphics/canvas_color_params.cc
|
||||
@@ -4,6 +4,7 @@
|
||||
@@ -131,7 +132,18 @@ index 75d7af9a79d4e7f2cd39e45496ab5fff66407638..b4ddafdd126edd16172f00448bbbd56e
|
||||
|
||||
namespace blink {
|
||||
|
||||
@@ -118,6 +120,11 @@ uint8_t CanvasColorParams::BytesPerPixel() const {
|
||||
@@ -19,6 +21,10 @@ namespace blink {
|
||||
// Level 4 specification.
|
||||
gfx::ColorSpace PredefinedColorSpaceToGfxColorSpace(
|
||||
PredefinedColorSpace color_space) {
|
||||
+ auto* cmd_line = base::CommandLine::ForCurrentProcess();
|
||||
+ if (cmd_line->HasSwitch(switches::kDisableColorCorrectRendering)) {
|
||||
+ return gfx::ColorSpace();
|
||||
+ }
|
||||
switch (color_space) {
|
||||
case PredefinedColorSpace::kSRGB:
|
||||
return gfx::ColorSpace::CreateSRGB();
|
||||
@@ -118,6 +124,11 @@ uint8_t CanvasColorParams::BytesPerPixel() const {
|
||||
}
|
||||
|
||||
gfx::ColorSpace CanvasColorParams::GetStorageGfxColorSpace() const {
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Hassan Talat <hatalat@microsoft.com>
|
||||
Date: Mon, 13 Jun 2022 21:27:53 +0000
|
||||
Subject: dpwa: Enable Window Controls Overlay by default
|
||||
|
||||
This reverts commit d61c4042374672712176e43e33f39a1e66da4faa.
|
||||
I2S: https://groups.google.com/a/chromium.org/g/blink-dev/c/guI1QCPJTAA
|
||||
|
||||
Bug: 937121
|
||||
Change-Id: I3dfebec2356c7a12fd7eab32f12ef8d9e4bf6ee6
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3430266
|
||||
Commit-Queue: Alex Russell <slightlyoff@chromium.org>
|
||||
Reviewed-by: Alex Russell <slightlyoff@chromium.org>
|
||||
Reviewed-by: Avi Drissman <avi@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/main@{#1013665}
|
||||
|
||||
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc
|
||||
index ee8c06004a0b38883d60b2bd3e6d1ac5cdf93277..3169ed9adc24961050500ad6fb62cec6b522eac1 100644
|
||||
--- a/content/public/common/content_features.cc
|
||||
+++ b/content/public/common/content_features.cc
|
||||
@@ -1025,7 +1025,7 @@ const base::Feature kV8VmFuture{"V8VmFuture",
|
||||
|
||||
// Enable window controls overlays for desktop PWAs
|
||||
const base::Feature kWebAppWindowControlsOverlay{
|
||||
- "WebAppWindowControlsOverlay", base::FEATURE_DISABLED_BY_DEFAULT};
|
||||
+ "WebAppWindowControlsOverlay", base::FEATURE_ENABLED_BY_DEFAULT};
|
||||
|
||||
// Enable WebAssembly baseline compilation (Liftoff).
|
||||
const base::Feature kWebAssemblyBaseline{"WebAssemblyBaseline",
|
||||
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5
|
||||
index 3efb1d07380a117f0a6fe0c07890d39d94e5f6ec..f99b90db892d6190c8f7146d2892ca6f6b26ea2b 100644
|
||||
--- a/third_party/blink/renderer/platform/runtime_enabled_features.json5
|
||||
+++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
|
||||
@@ -2575,7 +2575,7 @@
|
||||
name: "WebAppWindowControlsOverlay",
|
||||
origin_trial_feature_name: "WebAppWindowControlsOverlay",
|
||||
origin_trial_os: ["win", "mac", "linux", "chromeos"],
|
||||
- status: "experimental",
|
||||
+ status: "stable",
|
||||
},
|
||||
{
|
||||
name: "WebAssemblyCSP",
|
||||
diff --git a/third_party/blink/web_tests/platform/generic/virtual/stable/fast/dom/Window/property-access-on-cached-properties-after-frame-navigated-expected.txt b/third_party/blink/web_tests/platform/generic/virtual/stable/fast/dom/Window/property-access-on-cached-properties-after-frame-navigated-expected.txt
|
||||
index a2bac6e1f0fc6404a8fabbab87cd78da3e50570c..d6e4d3d5846ec3de2056af5a89a74f168a0e216d 100644
|
||||
--- a/third_party/blink/web_tests/platform/generic/virtual/stable/fast/dom/Window/property-access-on-cached-properties-after-frame-navigated-expected.txt
|
||||
+++ b/third_party/blink/web_tests/platform/generic/virtual/stable/fast/dom/Window/property-access-on-cached-properties-after-frame-navigated-expected.txt
|
||||
@@ -77,6 +77,8 @@ PASS window.cached_navigator_virtualKeyboard.boundingRect.x is 0
|
||||
PASS window.cached_navigator_virtualKeyboard.boundingRect.y is 0
|
||||
PASS window.cached_navigator_virtualKeyboard.ongeometrychange is null
|
||||
PASS window.cached_navigator_virtualKeyboard.overlaysContent is false
|
||||
+PASS window.cached_navigator_windowControlsOverlay.ongeometrychange is null
|
||||
+PASS window.cached_navigator_windowControlsOverlay.visible is false
|
||||
PASS window.cached_navigator_xr.ondevicechange is null
|
||||
PASS window.cached_performance.onresourcetimingbufferfull is null
|
||||
PASS window.cached_performance_navigation.redirectCount is 0
|
||||
diff --git a/third_party/blink/web_tests/platform/generic/virtual/stable/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-and-gced-expected.txt b/third_party/blink/web_tests/platform/generic/virtual/stable/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-and-gced-expected.txt
|
||||
index 9b413dea03d864d6cef496279187b39cf81ba4b0..5cfdedb36e5f9bd0dbfae11d5ba5cc1172823071 100644
|
||||
--- a/third_party/blink/web_tests/platform/generic/virtual/stable/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-and-gced-expected.txt
|
||||
+++ b/third_party/blink/web_tests/platform/generic/virtual/stable/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-and-gced-expected.txt
|
||||
@@ -77,6 +77,8 @@ PASS window.cached_navigator_virtualKeyboard.boundingRect.x is 0
|
||||
PASS window.cached_navigator_virtualKeyboard.boundingRect.y is 0
|
||||
PASS window.cached_navigator_virtualKeyboard.ongeometrychange is null
|
||||
PASS window.cached_navigator_virtualKeyboard.overlaysContent is false
|
||||
+PASS window.cached_navigator_windowControlsOverlay.ongeometrychange is null
|
||||
+PASS window.cached_navigator_windowControlsOverlay.visible is false
|
||||
PASS window.cached_navigator_xr.ondevicechange is null
|
||||
PASS window.cached_performance.onresourcetimingbufferfull is null
|
||||
PASS window.cached_performance_navigation.redirectCount is 0
|
||||
diff --git a/third_party/blink/web_tests/platform/generic/virtual/stable/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-expected.txt b/third_party/blink/web_tests/platform/generic/virtual/stable/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-expected.txt
|
||||
index 6f480ccfc7031fbdab98b50511a667aed5840af1..37bba469a00c719128762f861313e383d1ad4b86 100644
|
||||
--- a/third_party/blink/web_tests/platform/generic/virtual/stable/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-expected.txt
|
||||
+++ b/third_party/blink/web_tests/platform/generic/virtual/stable/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-expected.txt
|
||||
@@ -77,6 +77,8 @@ PASS window.cached_navigator_virtualKeyboard.boundingRect.x is 0
|
||||
PASS window.cached_navigator_virtualKeyboard.boundingRect.y is 0
|
||||
PASS window.cached_navigator_virtualKeyboard.ongeometrychange is null
|
||||
PASS window.cached_navigator_virtualKeyboard.overlaysContent is false
|
||||
+PASS window.cached_navigator_windowControlsOverlay.ongeometrychange is null
|
||||
+PASS window.cached_navigator_windowControlsOverlay.visible is false
|
||||
PASS window.cached_navigator_xr.ondevicechange is null
|
||||
PASS window.cached_performance.onresourcetimingbufferfull is null
|
||||
PASS window.cached_performance_navigation.redirectCount is 0
|
||||
diff --git a/third_party/blink/web_tests/platform/generic/virtual/stable/fast/dom/Window/property-access-on-cached-window-after-frame-navigated-expected.txt b/third_party/blink/web_tests/platform/generic/virtual/stable/fast/dom/Window/property-access-on-cached-window-after-frame-navigated-expected.txt
|
||||
index ef72385e2cc50ae9519f2d0cf496e8cc771cf5aa..36efa30d35e4b8e5e7752bfde58f50cdef865e89 100644
|
||||
--- a/third_party/blink/web_tests/platform/generic/virtual/stable/fast/dom/Window/property-access-on-cached-window-after-frame-navigated-expected.txt
|
||||
+++ b/third_party/blink/web_tests/platform/generic/virtual/stable/fast/dom/Window/property-access-on-cached-window-after-frame-navigated-expected.txt
|
||||
@@ -87,6 +87,8 @@ PASS oldChildWindow.navigator.virtualKeyboard.boundingRect.y is newChildWindow.n
|
||||
PASS oldChildWindow.navigator.virtualKeyboard.ongeometrychange is newChildWindow.navigator.virtualKeyboard.ongeometrychange
|
||||
PASS oldChildWindow.navigator.virtualKeyboard.overlaysContent is newChildWindow.navigator.virtualKeyboard.overlaysContent
|
||||
PASS oldChildWindow.navigator.webdriver is newChildWindow.navigator.webdriver
|
||||
+PASS oldChildWindow.navigator.windowControlsOverlay.ongeometrychange is newChildWindow.navigator.windowControlsOverlay.ongeometrychange
|
||||
+PASS oldChildWindow.navigator.windowControlsOverlay.visible is newChildWindow.navigator.windowControlsOverlay.visible
|
||||
PASS oldChildWindow.navigator.xr.ondevicechange is newChildWindow.navigator.xr.ondevicechange
|
||||
PASS oldChildWindow.onabort is newChildWindow.onabort
|
||||
PASS oldChildWindow.onafterprint is newChildWindow.onafterprint
|
||||
diff --git a/third_party/blink/web_tests/platform/generic/virtual/stable/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/platform/generic/virtual/stable/webexposed/global-interface-listing-expected.txt
|
||||
index 8dd54bc97aaeb0d563d7d839ff945881a5c7a422..ec02c2f0024fb6479aa469b4aeb66521b4f741f7 100644
|
||||
--- a/third_party/blink/web_tests/platform/generic/virtual/stable/webexposed/global-interface-listing-expected.txt
|
||||
+++ b/third_party/blink/web_tests/platform/generic/virtual/stable/webexposed/global-interface-listing-expected.txt
|
||||
@@ -4976,6 +4976,7 @@ interface Navigator
|
||||
getter webdriver
|
||||
getter webkitPersistentStorage
|
||||
getter webkitTemporaryStorage
|
||||
+ getter windowControlsOverlay
|
||||
getter xr
|
||||
method clearAppBadge
|
||||
method constructor
|
||||
@@ -9676,6 +9677,18 @@ interface Window : EventTarget
|
||||
attribute PERSISTENT
|
||||
attribute TEMPORARY
|
||||
method constructor
|
||||
+interface WindowControlsOverlay : EventTarget
|
||||
+ attribute @@toStringTag
|
||||
+ getter ongeometrychange
|
||||
+ getter visible
|
||||
+ method constructor
|
||||
+ method getTitlebarAreaRect
|
||||
+ setter ongeometrychange
|
||||
+interface WindowControlsOverlayGeometryChangeEvent : Event
|
||||
+ attribute @@toStringTag
|
||||
+ getter titlebarAreaRect
|
||||
+ getter visible
|
||||
+ method constructor
|
||||
interface Worker : EventTarget
|
||||
attribute @@toStringTag
|
||||
getter onerror
|
||||
@@ -33,10 +33,10 @@ index 14c71cc69388da46f62d9835e2a06fef0870da02..9481ea08401ae29ae9c1d960491b05b3
|
||||
|
||||
} // namespace net
|
||||
diff --git a/services/network/network_context.cc b/services/network/network_context.cc
|
||||
index b8560d71365759680fd5e49d311b19df41d6fb3b..1c0451cd2f2f7e1aeb182fb4f803cb960b63ef63 100644
|
||||
index c90733c3f463a2b9a3f142a739061fa65d6905b8..372c00c77c4320847313bdba49ade7ae8ed3f699 100644
|
||||
--- a/services/network/network_context.cc
|
||||
+++ b/services/network/network_context.cc
|
||||
@@ -1412,6 +1412,13 @@ void NetworkContext::SetNetworkConditions(
|
||||
@@ -1414,6 +1414,13 @@ void NetworkContext::SetNetworkConditions(
|
||||
std::move(network_conditions));
|
||||
}
|
||||
|
||||
|
||||
27
patches/chromium/feat_add_set_can_resize_mutator.patch
Normal file
27
patches/chromium/feat_add_set_can_resize_mutator.patch
Normal file
@@ -0,0 +1,27 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Raymond Zhao <7199958+rzhao271@users.noreply.github.com>
|
||||
Date: Tue, 2 Aug 2022 09:30:36 -0700
|
||||
Subject: feat: Add set_can_resize mutator
|
||||
|
||||
Adds a set_can_resize mutator to WidgetDelegate that
|
||||
doesn't emit the OnSizeConstraintsChanged event.
|
||||
This way, we can call set_can_resize from Electron before
|
||||
the widget is initialized to set the value earlier,
|
||||
and in turn, avoid showing a frame at startup
|
||||
for frameless applications.
|
||||
|
||||
diff --git a/ui/views/widget/widget_delegate.h b/ui/views/widget/widget_delegate.h
|
||||
index 8176aa0ac84b82a342713e6d36c4cc9d34b2f34f..c586f9e410fdff944f9af749bb31b20d248f8c58 100644
|
||||
--- a/ui/views/widget/widget_delegate.h
|
||||
+++ b/ui/views/widget/widget_delegate.h
|
||||
@@ -331,6 +331,10 @@ class VIEWS_EXPORT WidgetDelegate {
|
||||
// be cycled through with keyboard focus.
|
||||
virtual void GetAccessiblePanes(std::vector<View*>* panes) {}
|
||||
|
||||
+ // A setter for the can_resize parameter that doesn't
|
||||
+ // emit any events.
|
||||
+ void set_can_resize(bool can_resize) { params_.can_resize = can_resize; }
|
||||
+
|
||||
// Setters for data parameters of the WidgetDelegate. If you use these
|
||||
// setters, there is no need to override the corresponding virtual getters.
|
||||
void SetAccessibleRole(ax::mojom::Role role);
|
||||
@@ -6,10 +6,10 @@ Subject: fix: allow guest webcontents to enter fullscreen
|
||||
This can be upstreamed, a guest webcontents can't technically become the focused webContents. This DCHECK should allow all guest webContents to request fullscreen entrance.
|
||||
|
||||
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
|
||||
index 050e59567dfb72833d96a9331329b8235d0a4a07..3f740e42f2ca869c4f19632a5cfee6142702f02a 100644
|
||||
index c59a5dafe25831e55a36958f3d3d0765af720ca4..8982a2a4d2be23e56472b17e9d59e289e8255336 100644
|
||||
--- a/content/browser/web_contents/web_contents_impl.cc
|
||||
+++ b/content/browser/web_contents/web_contents_impl.cc
|
||||
@@ -3417,7 +3417,7 @@ void WebContentsImpl::EnterFullscreenMode(
|
||||
@@ -3429,7 +3429,7 @@ void WebContentsImpl::EnterFullscreenMode(
|
||||
OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::EnterFullscreenMode");
|
||||
DCHECK(CanEnterFullscreenMode(requesting_frame, options));
|
||||
DCHECK(requesting_frame->IsActive());
|
||||
|
||||
@@ -8,10 +8,10 @@ we invoke it in order to expose contents.decrementCapturerCount([stayHidden, sta
|
||||
to users. We should try to upstream this.
|
||||
|
||||
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h
|
||||
index 4c278081eaec0cdb5dac5e9fc3453de5ce04d918..888b8950f4849a5005f45ee4c4be3a481166540c 100644
|
||||
index 3d9e766965b52e7b4e66ac00434a982a0fedea77..6431e171811693bb5cdcbd83a6d50073451b8675 100644
|
||||
--- a/content/browser/web_contents/web_contents_impl.h
|
||||
+++ b/content/browser/web_contents/web_contents_impl.h
|
||||
@@ -1824,7 +1824,7 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
|
||||
@@ -1828,7 +1828,7 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
|
||||
// IncrementCapturerCount() is destructed.
|
||||
void DecrementCapturerCount(bool stay_hidden,
|
||||
bool stay_awake,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user