Compare commits

...

58 Commits

Author SHA1 Message Date
Pedro Pontes
f89e3e37de chore: cherry-pick 38de42d2bbc3 from chromium (#37667)
* chore: cherry-pick 38de42d2bbc3 from chromium

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: electron-patch-conflict-fixer[bot] <83340002+electron-patch-conflict-fixer[bot]@users.noreply.github.com>
2023-03-23 14:35:16 -04:00
Pedro Pontes
550b0d5a43 chore: cherry-pick 546e00df97ac from v8 (#37671)
* chore: cherry-pick 546e00df97ac from v8

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: electron-patch-conflict-fixer[bot] <83340002+electron-patch-conflict-fixer[bot]@users.noreply.github.com>
2023-03-23 12:34:26 -04:00
Pedro Pontes
f2719edd1d chore: cherry-pick 8731bd8a30f6 from chromium (#37657)
* chore: cherry-pick 8731bd8a30f6 from chromium

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: electron-patch-conflict-fixer[bot] <83340002+electron-patch-conflict-fixer[bot]@users.noreply.github.com>
2023-03-23 10:53:20 -04:00
Pedro Pontes
cedf0014f6 chore: cherry-pick f6ddbf42b1ea from v8 (#37663)
* chore: cherry-pick f6ddbf42b1ea from v8

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-03-22 20:14:38 -04:00
Pedro Pontes
2d1ba5626b chore: cherry-pick 55e2b6daba9d from angle (#37656)
* chore: [22-x-y] cherry-pick 55e2b6daba9d from angle

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-03-22 20:11:38 -04:00
Pedro Pontes
c8fea8abcf chore: cherry-pick 26bfa5807606 from chromium (#37648)
* chore: [22-x-y] cherry-pick 26bfa5807606 from chromium

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-03-22 19:56:13 -04:00
trop[bot]
bb88e69ccc fix: invoke app.dock.{hide|show} instead of duplicating logic (#37623)
fix: invoke app.dock.{hide|show} instead of duplicating logic

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-03-20 20:47:23 -04:00
trop[bot]
14707ad2b5 fix: properly bubble up cookie creation failure message (#37595)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-03-16 15:22:40 +01:00
trop[bot]
24ce94856c fix: don't set delegate for QLPreviewPanel (#37576)
fix: don't set delegate for QLPreviewPanel

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Jeremy Spiegel <jeremy.spiegel@frontapp.com>
2023-03-16 13:48:29 +01:00
trop[bot]
a831d69dfd docs: clarify open-url not preventable (#37574)
docs: clarify open-url not preventable

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-03-14 20:20:18 -04:00
Pedro Pontes
432eba9406 chore: cherry-pick 999cc7185e93 and 0f0b3a54c53c from chromium (#37477)
* chore: [22-x-y] cherry-pick 999cc7185e93 and 0f0b3a54c53c from chromium

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: electron-patch-conflict-fixer[bot] <83340002+electron-patch-conflict-fixer[bot]@users.noreply.github.com>
2023-03-08 22:02:48 -05:00
Pedro Pontes
e4800bab86 chore: cherry-pick e79b89b47dac from chromium (#37479)
* chore: [22-x-y] cherry-pick e79b89b47dac from chromium

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: electron-patch-conflict-fixer[bot] <83340002+electron-patch-conflict-fixer[bot]@users.noreply.github.com>
2023-03-07 21:35:47 +01:00
trop[bot]
d44fd39272 fix: don't double-log unhandled rejections (#37502)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-03-07 21:35:29 +01:00
Pedro Pontes
8352346fff chore: cherry-pick 06851790480e from chromium (#37483)
* chore: cherry-pick 06851790480e from chromium

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: electron-patch-conflict-fixer[bot] <83340002+electron-patch-conflict-fixer[bot]@users.noreply.github.com>
2023-03-06 16:47:16 +01:00
Pedro Pontes
76f5059db4 chore: cherry-pick 218b56e51638 from webrtc (#37485) 2023-03-06 11:44:03 +01:00
Pedro Pontes
0b52938852 chore: cherry-pick aeec1ba5893d from chromium (#37481)
* chore: [22-x-y] cherry-pick aeec1ba5893d from chromium

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-03-06 11:04:10 +01:00
trop[bot]
5d3eea5934 chore: improve contents.takeHeapSnapshot error messages (#37459)
* chore: improve contents.takeHeapSnapshot error messages

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>

* fix wstring conversion issue

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-03-02 12:49:02 +01:00
trop[bot]
0384c57eb5 fix: min/max width/height enforcement when aspectRatio is set (#37458)
fix: min/max width/height with aspect ratio

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-03-02 12:22:45 +01:00
trop[bot]
7e02e1d6da fix: Notification with reply obscuring first action on macOS (#37447)
fix: Notification with reply obscuring first action

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-03-01 12:24:26 +01:00
trop[bot]
87ec774248 fix: restoring X11 window should not remove previous maximize state (#37360)
* fix: restoring X11 window should not remove previous maximize state

Co-authored-by: Cheng Zhao <zcbenz@gmail.com>

* chore: update patches

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-02-23 18:49:07 +09:00
Keeley Hammond
1df44118af chore: cherry-pick e0efbd45ea74 from webrtc (#37298) 2023-02-20 12:31:27 +01:00
trop[bot]
9db65bac75 test: fix "crash cases" tests not failing properly (#37324)
* test: fix "crash cases" tests not failing properly

Co-authored-by: Alexey Kuzmin <alex.s.kuzmin@gmail.com>

* fixup! test: fix "crash cases" tests not failing properly

Co-authored-by: Alexey Kuzmin <alex.s.kuzmin@gmail.com>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Alexey Kuzmin <alex.s.kuzmin@gmail.com>
2023-02-19 01:26:35 -08:00
trop[bot]
5f115c8967 docs: only macOS 10.13+ is supported now (#37289)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Milan Burda <miburda@microsoft.com>
2023-02-16 15:56:32 -08:00
Keeley Hammond
03a1deb25c build: use node 18.12 in AppVeyor (22-x-y) (#37284)
* build: use node18.12 appveyor image

* build: use e-108.0.5359.215-node18
2023-02-15 17:50:10 -08:00
trop[bot]
54436d2048 feat: include all standard paper sizes for webContents.print() (#37263)
feat: include standard paper sizes for webContents.print()

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-02-15 19:59:13 +01:00
trop[bot]
da55d6bfda fix: cookies filter secure invalid (#37247)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Black-Hole <158blackhole@gmail.com>
2023-02-15 12:37:55 +01:00
trop[bot]
a7bd733462 fix: BrowserView crash when 'beforeunload' prevented (#37266)
fix: crash when beforeunload prevented

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-02-15 11:55:52 +01:00
trop[bot]
5692fd89d6 refactor: simplify Node.js event loop with SpinEventLoop (#37257)
refactor: simplify Node.js event loop with SpinEventLoop

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-02-15 11:55:30 +01:00
trop[bot]
72984eb31b docs: add win.isFocusable() return type (#37262)
docs: fix `win.isFocusable()` return type

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Andrew Ferreira <andrew.shien2@gmail.com>
2023-02-15 11:52:09 +01:00
trop[bot]
d6bcc07688 build: set make_latest correctly on published releases (#37241)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Samuel Attard <marshallofsound@electronjs.org>
2023-02-13 17:09:37 +01:00
trop[bot]
299756c5b1 chore: update https://cs.chromium.org/ links to https://source.chromium.org/ (#37237)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Milan Burda <miburda@microsoft.com>
2023-02-13 16:34:32 +09:00
John Kleinschmidt
2a4aed7f7a ci: update appveyor image (22-x-y) (#37227)
ci update appveyor image

(cherry picked from commit 454dc6aa318cadeb45a07cb311eccdd5a3a3670e)
2023-02-11 13:37:08 -05:00
trop[bot]
b0c7515e6a docs: add missing clipboard-sanitized-write permission value to setPermissionRequestHandler() (#37207)
docs: add missing clipboard-sanitized-write permission value to setPermissionRequestHandler() (#37173)

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2023-02-09 14:31:07 +01:00
Keeley Hammond
1ae86b3bec chore: cherry-pick e17eee4894be from v8 (#37192)
* chore: [22-x-y] cherry-pick e17eee4894be from v8

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-02-09 12:28:53 +01:00
trop[bot]
62e9ffab9b fix: expose native bindings by process type (#37175)
* fix: expose native bindings by process type

Co-authored-by: Milan Burda <milan.burda@gmail.com>

* fix test

* fix test

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2023-02-08 14:34:58 +01:00
trop[bot]
fc2261f159 fix: enable basic a11y when voice control is active (#37146)
* fix: enable basic a11y when voice control is active

c.f. https://chromium-review.googlesource.com/c/chromium/src/+/2680102

Co-authored-by: Samuel Attard <marshallofsound@electronjs.org>

* Update shell/browser/mac/electron_application.mm

Co-authored-by: Robo <hop2deep@gmail.com>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Samuel Attard <marshallofsound@electronjs.org>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
Co-authored-by: Robo <hop2deep@gmail.com>
2023-02-07 16:01:49 -05:00
trop[bot]
dcc99ecb19 docs: use relative links within docs (#37160)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2023-02-07 11:34:03 -05:00
trop[bot]
0e508d9c98 fix: nodeIntegrationInWorker fails to boot in AudioWorklets (#37102)
fix: nodeIntegrationInWorker in AudioWorklets

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Jeremy Rose <jeremya@chromium.org>
2023-02-07 10:03:36 +01:00
David Sanders
dfa48d673f build: fixup release_dependency_versions action (#37111)
* build: update release deps workflow

* build: fixup release_dependency_versions action

---------

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-02-06 08:56:38 -08:00
trop[bot]
120fd04f7f docs: use automatic link syntax for symbol server link (#37119)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2023-02-02 14:31:59 +01:00
trop[bot]
ab5a5b616f docs: remove invalid appcache value from storages in clearStorageData() (#37107)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2023-02-02 20:54:02 +09:00
trop[bot]
1106ca998b feat: enable whole-program optimization native modules by default (#37047)
* feat: enable whole-program optimization

Enable whole-program optimization in electron native modules by default.

Co-authored-by: Kyrylo Hrechykhin <khrechykhin@microsoft.com>

* pass --with-ltcg to configure.py instead of setting variable

Co-authored-by: Kyrylo Hrechykhin <khrechykhin@microsoft.com>

* enable ltcg only on windows

Co-authored-by: Kyrylo Hrechykhin <khrechykhin@microsoft.com>

* chore: update patches

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Kyrylo Hrechykhin <khrechykhin@microsoft.com>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2023-02-02 20:53:26 +09:00
trop[bot]
fe3baa83d6 ci: ensure correct ninja is used (#37071)
* ci: ensure correct ninja is used

Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>

* chore: remove no longer needed patch

* ci: fixup ninja for release

(cherry picked from commit 78b83864cd)

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2023-01-31 12:36:58 -05:00
trop[bot]
21082ae2fb docs: updated deep link docs (#37032) 2023-01-30 10:58:31 +01:00
electron-roller[bot]
5ed0f95d8f chore: bump chromium to 108.0.5359.215 (22-x-y) (#37019)
* chore: bump chromium in DEPS to 108.0.5359.215

* chore: update patches

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-01-26 16:18:05 -05:00
Cheng Zhao
4f5432e986 fix: fallback to GtkStatusIcon when app indicator is not supported (#37034)
* refactor: make StatusIconType an enum class (#36554)

Co-authored-by: Milan Burda <miburda@microsoft.com>

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Milan Burda <miburda@microsoft.com>

* fix: fallback to GtkStatusIcon when app indicator is not supported (#36815)

* chore: get ready for multi backend tray

* fix: fallback to GtkStatusIcon when app indicator is not supported

* chore: use smart pointers

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Milan Burda <miburda@microsoft.com>
2023-01-26 13:39:26 +01:00
trop[bot]
ef164e7e8d feat: Add BrowserWindow option to hide window in Mission Control (macOS) (#36390) 2023-01-26 11:25:03 +01:00
trop[bot]
786350c22e chore: remove crashpad related sandbox policy (#37027)
Co-authored-by: deepak1556 <hop2deep@gmail.com>

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: deepak1556 <hop2deep@gmail.com>
2023-01-26 17:27:31 +09:00
Keeley Hammond
19b85bb74e chore: cherry-pick 57c54ae221d6 from chromium (#37022)
* chore: [22-x-y] cherry-pick 57c54ae221d6 from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-01-26 15:44:36 +09:00
trop[bot]
95772e1feb fix: treat maxWidth/Height<=0 as unlimited (#36512)
Co-authored-by: Jeremy Rose <jeremya@chromium.org>

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Jeremy Rose <jeremya@chromium.org>
2023-01-25 13:06:15 -08:00
David Sanders
a73332fd9f test: support running tests against Electron releases (#36968)
Co-authored-by: Charles Kerr <charles@charleskerr.com>

Co-authored-by: Charles Kerr <charles@charleskerr.com>
2023-01-24 11:58:16 -05:00
trop[bot]
153abeb351 test: add a <datalist> spec for time type (#36997)
spec: add a datalist spec for time type

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-01-24 09:35:00 +01:00
Robo
e5690f1353 chore: cherry-pick 5e04f643 from chromium (#36991) 2023-01-23 13:32:13 +01:00
trop[bot]
71e1d8eea1 fix: make plugin helper executable unconditional (#36978)
Co-authored-by: deepak1556 <hop2deep@gmail.com>

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: deepak1556 <hop2deep@gmail.com>
2023-01-21 21:40:38 +09:00
trop[bot]
b6eef90604 docs: update clipboard fiddles (#36961)
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2023-01-19 18:08:15 -05:00
trop[bot]
57f2eecb28 docs: Change factuality and word choice in app.runningUnderARM64Translation (#36964)
Change factuality and word choice.

Added "or WOW" to the phrase, "when they are running the x64 version under Rosetta", to reflect the use of a supported platform, Windows, as a possible scenario.
Changed the wording of that same sentence to make it appear clearer. "incorrectly" to "mistakenly" and moved this word to before the verb instead of the end of the sentence.

Co-authored-by: GGIEnrike <52293637+GGIEnrike@users.noreply.github.com>

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: GGIEnrike <52293637+GGIEnrike@users.noreply.github.com>
2023-01-19 18:02:51 -05:00
trop[bot]
72bdd5cd4c feat: add label property to Display objects (#36932)
Co-authored-by: Milan Burda <milan.burda@gmail.com>

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2023-01-19 15:59:08 +09:00
trop[bot]
37267d1beb fix: webview background color on reload (#36940)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-01-18 16:29:15 -05:00
114 changed files with 3735 additions and 501 deletions

View File

@@ -484,7 +484,9 @@ step-fix-sync: &step-fix-sync
run:
name: Fix Sync
command: |
SEDOPTION="-i"
if [ "`uname`" == "Darwin" ]; then
SEDOPTION="-i ''"
# Fix Clang Install (wrong binary)
rm -rf src/third_party/llvm-build
python3 src/tools/clang/scripts/update.py
@@ -494,13 +496,16 @@ step-fix-sync: &step-fix-sync
# Remove extra output from calling gclient getdep which always calls update_depot_tools
sed -i '' "s/Updating depot_tools... //g" esbuild_ensure_file
cipd ensure --root src/third_party/devtools-frontend/src/third_party/esbuild -ensure-file esbuild_ensure_file
# Fix ninja (wrong binary)
echo 'infra/3pp/tools/ninja/${platform}' `gclient getdep --deps-file=src/DEPS -r 'src/third_party/ninja:infra/3pp/tools/ninja/${platform}'` > ninja_ensure_file
sed -i '' "s/Updating depot_tools... //g" ninja_ensure_file
cipd ensure --root src/third_party/ninja -ensure-file ninja_ensure_file
fi
# Make sure we are using the right ninja
echo 'infra/3pp/tools/ninja/${platform}' `gclient getdep --deps-file=src/DEPS -r 'src/third_party/ninja:infra/3pp/tools/ninja/${platform}'` > ninja_ensure_file
sed $SEDOPTION "s/Updating depot_tools... //g" ninja_ensure_file
cipd ensure --root src/third_party/ninja -ensure-file ninja_ensure_file
# Explicitly add ninja to the path
echo 'export PATH="$PATH:'"$PWD"'/src/third_party/ninja"' >> $BASH_ENV
cd src/third_party/angle
rm .git/objects/info/alternates
git remote set-url origin https://chromium.googlesource.com/angle/angle.git

View File

@@ -8,24 +8,26 @@ env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
jobs:
check_tag:
trigger_chromedriver:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Check Tag
- uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # tag: v3
- name: Trigger New chromedriver Release
run: |
if [[ ${{ github.event.release.tag_name }} =~ ^v[0-9]+\.0\.0$ ]]; then
echo ::set-output name=should_release::true
fi
trigger:
runs-on: ubuntu-latest
needs: check_tag
if: needs.check_tag.outputs.should_release == 'true'
steps:
- uses: actions/checkout@v3
- name: Trigger New chromedriver Release
run: |
if [[ ${{ github.event.release.tag_name }} =~ ^v\d+\.\d+\.\d+$ ]]; then
gh api /repos/:owner/chromedriver/actions/workflows/release.yml/dispatches --input - <<< '{"ref":"main","inputs":{"version":"${{ github.event.release.tag_name }}"}}'
else
echo "Not releasing for version ${{ github.event.release.tag_name }}"
fi
trigger_mksnapshot:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # tag: v3
- name: Trigger New mksnapshot Release
run: |
gh api /repos/:owner/mksnapshot/actions/workflows/release.yml/dispatches --input - <<< '{"ref":"main","inputs":{"version":"${{ github.event.release.tag_name }}"}}'
if [[ ${{ github.event.release.tag_name }} =~ ^v\d+\.\d+\.\d+$ ]]; then
gh api /repos/:owner/mksnapshot/actions/workflows/release.yml/dispatches --input - <<< '{"ref":"main","inputs":{"version":"${{ github.event.release.tag_name }}"}}'
else
echo "Not releasing for version ${{ github.event.release.tag_name }}"
fi

View File

@@ -631,8 +631,6 @@ source_set("electron_lib") {
sources += [
"shell/browser/certificate_manager_model.cc",
"shell/browser/certificate_manager_model.h",
"shell/browser/ui/gtk/menu_util.cc",
"shell/browser/ui/gtk/menu_util.h",
"shell/browser/ui/gtk_util.cc",
"shell/browser/ui/gtk_util.h",
]

2
DEPS
View File

@@ -2,7 +2,7 @@ gclient_gn_args_from = 'src'
vars = {
'chromium_version':
'108.0.5359.179',
'108.0.5359.215',
'node_version':
'v16.17.1',
'nan_version':

View File

@@ -6,7 +6,7 @@
version: 1.0.{build}
build_cloud: electronhq-16-core
image: e-111.0.5518.0
image: e-111.0.5560.0-node18
environment:
GIT_CACHE_PATH: C:\Users\appveyor\libcc_cache
ELECTRON_OUT_DIR: Default
@@ -16,17 +16,61 @@ environment:
GOMA_FALLBACK_ON_AUTH_FAILURE: true
DEPOT_TOOLS_WIN_TOOLCHAIN: 0
PYTHONIOENCODING: UTF-8
# The following lines are needed when baking from a completely new image (eg MicrosoftWindowsServer:WindowsServer:2019-Datacenter:latest via image: base-windows-server2019)
# init:
# - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
# - appveyor version
# - ps: $ErrorActionPreference = 'Stop'
# - ps: 'Write-Host "OS Build: $((Get-CimInstance Win32_OperatingSystem).BuildNumber)"'
# clone_folder: '%USERPROFILE%\image-bake-scripts'
# clone_script:
# - ps: Invoke-WebRequest "https://github.com/appveyor/build-images/archive/1f90d94e74c8243c909a09b994e527584dfcb838.zip" -OutFile "$env:temp\scripts.zip"
# - ps: Expand-Archive -Path "$env:temp\scripts.zip" -DestinationPath "$env:temp\scripts" -Force
# - ps: Copy-Item -Path "$env:temp\scripts\build-images-1f90d94e74c8243c909a09b994e527584dfcb838\scripts\Windows\*" -Destination $env:APPVEYOR_BUILD_FOLDER -Recurse
build_script:
- ps: Resize-Partition -DriveLetter C -Size (256GB) # ensure initial partition size
- ps: Get-Partition -DriveLetter C
# The following lines are needed when baking from a completely new image (eg MicrosoftWindowsServer:WindowsServer:2019-Datacenter:latest via image: base-windows-server2019)
# - ps: .\init_server.ps1
# - ps: .\extend_system_volume.ps1
# # Restart VM
# - ps: Start-Sleep -s 5; Restart-Computer
# - ps: Start-Sleep -s 5
# - appveyor version
# - ps: .\install_path_utils.ps1
# - ps: .\install_powershell_core.ps1
# - ps: .\install_powershell_get.ps1
# - ps: .\install_7zip.ps1
# - ps: .\install_chocolatey.ps1
# - ps: .\install_webpi.ps1
# - ps: .\install_nuget.ps1
# - ps: .\install_pstools.ps1
# - ps: .\install_git.ps1
# - ps: .\install_git_lfs.ps1
# # Restart VM
# - ps: Start-Sleep -s 5; Restart-Computer
# - ps: Start-Sleep -s 5
# END LINES FOR COMPLETELY NEW IMAGE
- git config --global core.longpaths true
- cd ..
- mkdir src
- ps: git clone --depth=1 https://chromium.googlesource.com/chromium/tools/depot_tools.git
- ps: $env:PATH="$pwd\depot_tools;$env:PATH"
- ps: >-
if (-not (Test-Path -Path C:\projects\src)) {
New-Item -Path C:\projects\src -ItemType Directory
}
- cd C:\projects\
- git clone -q --branch=%APPVEYOR_REPO_BRANCH% https://github.com/electron/electron.git C:\projects\src\electron
- git clone --depth=1 https://chromium.googlesource.com/chromium/tools/depot_tools.git
- ps: $env:PATH="$pwd\depot_tools;$env:PATH"
- update_depot_tools.bat
- ps: Move-Item $env:APPVEYOR_BUILD_FOLDER -Destination src\electron
- src\electron\script\setup-win-for-dev.bat
# Uncomment the following line if windows deps change
# - src\electron\script\setup-win-for-dev.bat
- >-
gclient config
--name "src\electron"
@@ -40,13 +84,25 @@ build_script:
- ps: cd ..\..
- gclient sync --with_branch_heads --with_tags --nohooks
- ps: regsvr32 /s "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\DIA SDK\bin\amd64\msdia140.dll"
# The following lines are needed when baking from a completely new image (eg MicrosoftWindowsServer:WindowsServer:2019-Datacenter:latest via image: base-windows-server2019)
# # Restart VM
# - ps: Start-Sleep -s 5; Restart-Computer
# - ps: Start-Sleep -s 5
# - cd %USERPROFILE%\image-bake-scripts
# - appveyor version
# - ps: .\optimize_dotnet_runtime.ps1
# - ps: .\disable_windows_background_services.ps1
# - ps: .\enforce_windows_firewall.ps1
# - ps: .\cleanup_windows.ps1
# END LINES FOR COMPLETELY NEW IMAGE
on_image_bake:
- ps: >-
echo "Baking image: $env:APPVEYOR_BAKE_IMAGE at dir $PWD"
- ps: Remove-Item -Recurse -Force $pwd\depot_tools
- ps: Remove-Item -Recurse -Force $pwd\src\electron
# Uncomment these lines to enable RDP
#on_finish:
# - ps: >-
# $env:APPVEYOR_RDP_PASSWORD = "electron"
# $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
- ps: Remove-Item -Recurse -Force C:\projects\depot_tools
- ps: Remove-Item -Recurse -Force C:\projects\src\electron
# Uncomment these lines and set APPVEYOR_RDP_PASSWORD in project settings to enable RDP after bake is done
# # on_finish:
# - ps: >-
# $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))

View File

@@ -29,7 +29,7 @@
version: 1.0.{build}
build_cloud: electronhq-16-core
image: e-108.0.5359.179
image: e-108.0.5359.215
environment:
GIT_CACHE_PATH: C:\Users\appveyor\libcc_cache
ELECTRON_OUT_DIR: Default
@@ -51,6 +51,8 @@ environment:
clone_folder: C:\projects\src\electron
skip_branch_with_pr: true
# the first failed job cancels other jobs and fails entire build
matrix:
fast_finish: true
@@ -80,7 +82,7 @@ for:
if (Test-Path -Path "$pwd\build-tools") {
Remove-Item -Recurse -Force $pwd\build-tools
}
- ps: git clone --depth=1 https://chromium.googlesource.com/chromium/tools/depot_tools.git
- git clone --depth=1 https://chromium.googlesource.com/chromium/tools/depot_tools.git
- ps: $env:PATH="$pwd\depot_tools;$env:PATH"
- ps: >-
if (Test-Path -Path "$pwd\src\electron") {
@@ -130,6 +132,7 @@ for:
}
- if "%RUN_GCLIENT_SYNC%"=="true" ( gclient sync --with_branch_heads --with_tags ) else ( gclient runhooks )
- cd src
- ps: $env:PATH="$pwd\third_party\ninja;$env:PATH"
- set BUILD_CONFIG_PATH=//electron/build/args/%GN_CONFIG%.gn
- gn gen out/Default "--args=import(\"%BUILD_CONFIG_PATH%\") import(\"%GN_GOMA_FILE%\") %GN_EXTRA_ARGS% "
- gn check out/Default //electron:electron_lib

View File

@@ -29,7 +29,7 @@
version: 1.0.{build}
build_cloud: electronhq-16-core
image: e-108.0.5359.179
image: e-108.0.5359.215-node18
environment:
GIT_CACHE_PATH: C:\Users\appveyor\libcc_cache
ELECTRON_OUT_DIR: Default
@@ -49,6 +49,8 @@ environment:
clone_folder: C:\projects\src\electron
skip_branch_with_pr: true
# the first failed job cancels other jobs and fails entire build
matrix:
fast_finish: true
@@ -78,7 +80,7 @@ for:
if (Test-Path -Path "$pwd\build-tools") {
Remove-Item -Recurse -Force $pwd\build-tools
}
- ps: git clone --depth=1 https://chromium.googlesource.com/chromium/tools/depot_tools.git
- git clone --depth=1 https://chromium.googlesource.com/chromium/tools/depot_tools.git
- ps: $env:PATH="$pwd\depot_tools;$env:PATH"
- ps: >-
if (Test-Path -Path "$pwd\src\electron") {
@@ -128,6 +130,7 @@ for:
}
- if "%RUN_GCLIENT_SYNC%"=="true" ( gclient sync --with_branch_heads --with_tags ) else ( gclient runhooks )
- cd src
- ps: $env:PATH="$pwd\third_party\ninja;$env:PATH"
- set BUILD_CONFIG_PATH=//electron/build/args/%GN_CONFIG%.gn
- gn gen out/Default "--args=import(\"%BUILD_CONFIG_PATH%\") import(\"%GN_GOMA_FILE%\") %GN_EXTRA_ARGS% "
- gn check out/Default //electron:electron_lib

View File

@@ -128,8 +128,6 @@ Emitted when the user wants to open a URL with the application. Your application
`Info.plist` file must define the URL scheme within the `CFBundleURLTypes` key, and
set `NSPrincipalClass` to `AtomApplication`.
You should call `event.preventDefault()` if you want to handle this event.
As with the `open-file` event, be sure to register a listener for the `open-url`
event early in your application startup to detect if the the application being
is being opened to handle a URL. If you register the listener in response to a
@@ -1562,5 +1560,4 @@ an ARM64 translator (like the macOS
or Windows [WOW](https://en.wikipedia.org/wiki/Windows_on_Windows)).
You can use this property to prompt users to download the arm64 version of
your application when they are running the x64 version under Rosetta
incorrectly.
your application when they are mistakenly running the x64 version under Rosetta or WOW.

View File

@@ -192,6 +192,7 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
macOS. Default is `false`.
* `skipTaskbar` boolean (optional) _macOS_ _Windows_ - Whether to show the window in taskbar.
Default is `false`.
* `hiddenInMissionControl` boolean (optional) _macOS_ - Whether window should be hidden when the user toggles into mission control.
* `kiosk` boolean (optional) - Whether the window is in kiosk mode. Default is `false`.
* `title` string (optional) - Default window title. Default is `"Electron"`. If the HTML tag `<title>` is defined in the HTML file loaded by `loadURL()`, this property will be ignored.
* `icon` ([NativeImage](native-image.md) | string) (optional) - The window icon. On Windows it is
@@ -268,7 +269,7 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
zoom to the width of the screen. This will also affect the behavior when
calling `maximize()` directly. Default is `false`.
* `tabbingIdentifier` string (optional) _macOS_ - Tab group name, allows
opening the window as a native tab on macOS 10.12+. Windows with the same
opening the window as a native tab. Windows with the same
tabbing identifier will be grouped together. This also adds a native new
tab button to your window's tab bar and allows your `app` and window to
receive the `new-window-for-tab` event.
@@ -1255,6 +1256,16 @@ Returns `boolean` - Whether the window can be manually closed by user.
On Linux always returns `true`.
#### `win.setHiddenInMissionControl(hidden)` _macOS_
* `hidden` boolean
Sets whether the window will be hidden when the user toggles into mission control.
#### `win.isHiddenInMissionControl()` _macOS_
Returns `boolean` - Whether the window will be hidden when the user toggles into mission control.
#### `win.setAlwaysOnTop(flag[, level][, relativeLevel])`
* `flag` boolean
@@ -1753,7 +1764,7 @@ On macOS it does not remove the focus from the window.
#### `win.isFocusable()` _macOS_ _Windows_
Returns whether the window can be focused.
Returns `boolean` - Whether the window can be focused.
#### `win.setParentWindow(parent)`
@@ -1836,7 +1847,7 @@ frameless window.
Sets the touchBar layout for the current window. Specifying `null` or
`undefined` clears the touch bar. This method only has an effect if the
machine has a touch bar and is running on macOS 10.12.1+.
machine has a touch bar.
**Note:** The TouchBar API is currently experimental and may change or be
removed in future Electron releases.
@@ -1887,7 +1898,7 @@ removed in future Electron releases.
On a Window with Window Controls Overlay already enabled, this method updates
the style of the title bar overlay.
[runtime-enabled-features]: https://cs.chromium.org/chromium/src/third_party/blink/renderer/platform/runtime_enabled_features.json5?l=70
[runtime-enabled-features]: https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/platform/runtime_enabled_features.json5
[page-visibility-api]: https://developer.mozilla.org/en-US/docs/Web/API/Page_Visibility_API
[quick-look]: https://en.wikipedia.org/wiki/Quick_Look
[vibrancy-docs]: https://developer.apple.com/documentation/appkit/nsvisualeffectview?preferredLanguage=objc

View File

@@ -2,7 +2,7 @@
> Perform copy and paste operations on the system clipboard.
Process: [Main](../glossary.md#main-process), [Renderer](../glossary.md#renderer-process)
Process: [Main](../glossary.md#main-process), [Renderer](../glossary.md#renderer-process) (non-sandboxed only)
On Linux, there is also a `selection` clipboard. To manipulate it
you need to pass `selection` to each method:

View File

@@ -51,7 +51,7 @@ See [`Menu`](menu.md) for examples.
the placement of their containing group after the containing group of the item
with the specified label.
**Note:** `acceleratorWorksWhenHidden` is specified as being macOS-only because accelerators always work when items are hidden on Windows and Linux. The option is exposed to users to give them the option to turn it off, as this is possible in native macOS development. This property is only usable on macOS High Sierra 10.13 or newer.
**Note:** `acceleratorWorksWhenHidden` is specified as being macOS-only because accelerators always work when items are hidden on Windows and Linux. The option is exposed to users to give them the option to turn it off, as this is possible in native macOS development.
### Roles

View File

@@ -449,7 +449,7 @@ Clears the sessions HTTP cache.
* `origin` string (optional) - Should follow `window.location.origin`s representation
`scheme://host:port`.
* `storages` string[] (optional) - The types of storages to clear, can contain:
`appcache`, `cookies`, `filesystem`, `indexdb`, `localstorage`,
`cookies`, `filesystem`, `indexdb`, `localstorage`,
`shadercache`, `websql`, `serviceworkers`, `cachestorage`. If not
specified, clear all storage types.
* `quotas` string[] (optional) - The types of quotas to clear, can contain:
@@ -672,6 +672,7 @@ win.webContents.session.setCertificateVerifyProc((request, callback) => {
* `webContents` [WebContents](web-contents.md) - WebContents requesting the permission. Please note that if the request comes from a subframe you should use `requestingUrl` to check the request origin.
* `permission` string - The type of requested permission.
* `clipboard-read` - Request access to read from the clipboard.
* `clipboard-sanitized-write` - Request access to write to the clipboard.
* `media` - Request access to media devices such as camera, microphone and speakers.
* `display-capture` - Request access to capture the screen.
* `mediaKeySystem` - Request access to DRM protected content.

View File

@@ -1,6 +1,7 @@
# Display Object
* `id` number - Unique identifier associated with the display.
* `label` string - User-friendly label, determined by the platform.
* `rotation` number - Can be 0, 90, 180, 270, represents screen rotation in
clock-wise degrees.
* `scaleFactor` number - Output device's pixel scale factor.

View File

@@ -394,8 +394,6 @@ system default and override the value of `getEffectiveAppearance`.
Returns `boolean` - whether or not this device has the ability to use Touch ID.
**NOTE:** This API will return `false` on macOS systems older than Sierra 10.12.2.
### `systemPreferences.promptTouchID(reason)` _macOS_
* `reason` string - The reason you are asking for Touch ID authentication
@@ -414,8 +412,6 @@ systemPreferences.promptTouchID('To get consent for a Security-Gated Thing').the
This API itself will not protect your user data; rather, it is a mechanism to allow you to do so. Native apps will need to set [Access Control Constants](https://developer.apple.com/documentation/security/secaccesscontrolcreateflags?language=objc) like [`kSecAccessControlUserPresence`](https://developer.apple.com/documentation/security/secaccesscontrolcreateflags/ksecaccesscontroluserpresence?language=objc) on their keychain entry so that reading it would auto-prompt for Touch ID biometric consent. This could be done with [`node-keytar`](https://github.com/atom/node-keytar), such that one would store an encryption key with `node-keytar` and only fetch it if `promptTouchID()` resolves.
**NOTE:** This API will return a rejected Promise on macOS systems older than Sierra 10.12.2.
### `systemPreferences.isTrustedAccessibilityClient(prompt)` _macOS_
* `prompt` boolean - whether or not the user will be informed via prompt if the current process is untrusted.
@@ -428,7 +424,7 @@ Returns `boolean` - `true` if the current process is a trusted accessibility cli
Returns `string` - Can be `not-determined`, `granted`, `denied`, `restricted` or `unknown`.
This user consent was not required on macOS 10.13 High Sierra or lower so this method will always return `granted`.
This user consent was not required on macOS 10.13 High Sierra so this method will always return `granted`.
macOS 10.14 Mojave or higher requires consent for `microphone` and `camera` access.
macOS 10.15 Catalina or higher requires consent for `screen` access.
@@ -443,7 +439,7 @@ Returns `Promise<boolean>` - A promise that resolves with `true` if consent was
**Important:** In order to properly leverage this API, you [must set](https://developer.apple.com/documentation/avfoundation/cameras_and_media_capture/requesting_authorization_for_media_capture_on_macos?language=objc) the `NSMicrophoneUsageDescription` and `NSCameraUsageDescription` strings in your app's `Info.plist` file. The values for these keys will be used to populate the permission dialogs so that the user will be properly informed as to the purpose of the permission request. See [Electron Application Distribution](../tutorial/application-distribution.md#rebranding-with-downloaded-binaries) for more information about how to set these in the context of Electron.
This user consent was not required until macOS 10.14 Mojave, so this method will always return `true` if your system is running 10.13 High Sierra or lower.
This user consent was not required until macOS 10.14 Mojave, so this method will always return `true` if your system is running 10.13 High Sierra.
### `systemPreferences.getAnimationSettings()`

View File

@@ -29,8 +29,9 @@ __Platform Considerations__
__Linux__
* Tray icon requires support of [StatusNotifierItem](https://www.freedesktop.org/wiki/Specifications/StatusNotifierItem/)
in user's desktop environment.
* Tray icon uses [StatusNotifierItem](https://www.freedesktop.org/wiki/Specifications/StatusNotifierItem/)
by default, when it is not available in user's desktop environment the
`GtkStatusIcon` will be used instead.
* The `click` event is emitted when the tray icon receives activation from
user, however the StatusNotifierItem spec does not specify which action would
cause an activation, for some environments it is left mouse click, but for
@@ -234,7 +235,7 @@ Sets the hover text for this tray icon.
* `title` string
* `options` Object (optional)
* `fontType` string (optional) - The font family variant to display, can be `monospaced` or `monospacedDigit`. `monospaced` is available in macOS 10.15+ and `monospacedDigit` is available in macOS 10.11+. When left blank, the title uses the default system font.
* `fontType` string (optional) - The font family variant to display, can be `monospaced` or `monospacedDigit`. `monospaced` is available in macOS 10.15+ When left blank, the title uses the default system font.
Sets the title displayed next to the tray icon in the status bar (Support ANSI colors).

View File

@@ -1416,8 +1416,8 @@ Returns `Promise<PrinterInfo[]>` - Resolves with a [`PrinterInfo[]`](structures/
* `vertical` number (optional) - The vertical dpi.
* `header` string (optional) - string to be printed as page header.
* `footer` string (optional) - string to be printed as page footer.
* `pageSize` string | Size (optional) - Specify page size of the printed document. Can be `A3`,
`A4`, `A5`, `Legal`, `Letter`, `Tabloid` or an Object containing `height` and `width`.
* `pageSize` string | Size (optional) - Specify page size of the printed document. Can be `A0`, `A1`, `A2`, `A3`,
`A4`, `A5`, `A6`, `Legal`, `Letter`, `Tabloid` or an Object containing `height` and `width`.
* `callback` Function (optional)
* `success` boolean - Indicates success of the print call.
* `failureReason` string - Error description called back if the print fails.

View File

@@ -993,7 +993,7 @@ Emitted when DevTools is closed.
Emitted when DevTools is focused / opened.
[runtime-enabled-features]: https://cs.chromium.org/chromium/src/third_party/blink/renderer/platform/runtime_enabled_features.json5?l=70
[runtime-enabled-features]: https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/platform/runtime_enabled_features.json5
[chrome-webview]: https://developer.chrome.com/docs/extensions/reference/webviewTag/
### Event: 'context-menu'

View File

@@ -146,6 +146,13 @@ webContents.printToPDF({
## Planned Breaking API Changes (20.0)
### Removed: macOS 10.11 / 10.12 support
macOS 10.11 (El Capitan) and macOS 10.12 (Sierra) are no longer supported by [Chromium](https://chromium-review.googlesource.com/c/chromium/src/+/3646050).
Older versions of Electron will continue to run on these operating systems, but macOS 10.13 (High Sierra)
or later will be required to run Electron v20.0.0 and higher.
### Default Changed: renderers without `nodeIntegration: true` are sandboxed by default
Previously, renderers that specified a preload script defaulted to being

View File

@@ -18,8 +18,8 @@ See also [V8 Development](v8-development.md)
### Code Resources
- [Code Search](https://cs.chromium.org/) - Indexed and searchable source code for Chromium and associated projects.
- [Source Code](https://cs.chromium.org/chromium/src/) - The source code for Chromium itself.
- [Code Search](https://source.chromium.org/chromium) - Indexed and searchable source code for Chromium and associated projects.
- [Source Code](https://source.chromium.org/chromium/chromium/src) - The source code for Chromium itself.
- [Chromium Review](https://chromium-review.googlesource.com) - The searchable code host which facilitates code reviews for Chromium and related projects.
### Informational Resources

View File

@@ -144,7 +144,7 @@ NODE_LINKED_MODULE_CONTEXT_AWARE(electron_browser_{api_name},Initialize)
In your [`shell/common/node_bindings.cc`](https://github.com/electron/electron/blob/main/shell/common/node_bindings.cc) file, add your node binding name to Electron's built-in modules.
```cpp title='shell/common/node_bindings.cc'
#define ELECTRON_BUILTIN_MODULES(V) \
#define ELECTRON_BROWSER_MODULES(V) \
V(electron_browser_{api_name})
```

View File

@@ -15,7 +15,7 @@ calls, and other compiler optimizations. The only workaround is to build an
unoptimized local build.
The official symbol server URL for Electron is
https://symbols.electronjs.org.
<https://symbols.electronjs.org>.
You cannot visit this URL directly, you must add it to the symbol path of your
debugging tool. In the examples below, a local cache directory is used to avoid
repeatedly fetching the PDB from the server. Replace `c:\code\symbols` with an

View File

@@ -2,12 +2,13 @@
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
</head>
<body>
<div>
<div>
<h1>Clipboard copy</h1>
<i>Supports: Win, macOS, Linux <span>|</span> Process: Both</i>
<i>Supports: Win, macOS, Linux <span>|</span> Process: Main, Renderer (non-sandboxed only)</i>
<div>
<div>
<button id="copy-to">Copy</button>
@@ -17,8 +18,6 @@
</div>
</div>
</div>
<script src="./renderer.js"></script>
</body>
<script>
require('./renderer.js')
</script>
</html>

View File

@@ -1,4 +1,5 @@
const { app, BrowserWindow } = require('electron')
const { app, BrowserWindow, ipcMain, clipboard } = require('electron')
const path = require('path')
let mainWindow = null
@@ -8,7 +9,7 @@ function createWindow () {
height: 400,
title: 'Clipboard copy',
webPreferences: {
nodeIntegration: true
preload: path.join(__dirname, 'preload.js')
}
}
@@ -20,6 +21,18 @@ function createWindow () {
})
}
ipcMain.handle('clipboard:writeText', (event, text) => {
clipboard.writeText(text)
})
app.whenReady().then(() => {
createWindow()
app.on('activate', function () {
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})
})
app.on('window-all-closed', function () {
if (process.platform !== 'darwin') app.quit()
})

View File

@@ -0,0 +1,5 @@
const { contextBridge, ipcRenderer } = require('electron')
contextBridge.exposeInMainWorld('clipboard', {
writeText: (text) => ipcRenderer.invoke('clipboard:writeText', text)
})

View File

@@ -1,5 +1,3 @@
const { clipboard } = require('electron')
const copyBtn = document.getElementById('copy-to')
const copyInput = document.getElementById('copy-to-input')

View File

@@ -2,12 +2,13 @@
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
</head>
<body>
<div>
<div>
<h1>Clipboard paste</h1>
<i>Supports: Win, macOS, Linux <span>|</span> Process: Both</i>
<i>Supports: Win, macOS, Linux <span>|</span> Process: Main, Renderer (non-sandboxed only)</i>
<div>
<div>
<button id="paste-to">Paste</button>
@@ -17,8 +18,6 @@
</div>
</div>
</div>
<script src="./renderer.js"></script>
</body>
<script>
require('./renderer.js')
</script>
</html>

View File

@@ -1,4 +1,5 @@
const { app, BrowserWindow } = require('electron')
const { app, BrowserWindow, ipcMain, clipboard } = require('electron')
const path = require('path')
let mainWindow = null
@@ -8,7 +9,7 @@ function createWindow () {
height: 400,
title: 'Clipboard paste',
webPreferences: {
nodeIntegration: true
preload: path.join(__dirname, 'preload.js')
}
}
@@ -20,6 +21,22 @@ function createWindow () {
})
}
ipcMain.handle('clipboard:readText', () => {
return clipboard.readText()
})
ipcMain.handle('clipboard:writeText', (event, text) => {
clipboard.writeText(text)
})
app.whenReady().then(() => {
createWindow()
app.on('activate', function () {
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})
})
app.on('window-all-closed', function () {
if (process.platform !== 'darwin') app.quit()
})

View File

@@ -0,0 +1,6 @@
const { contextBridge, ipcRenderer } = require('electron')
contextBridge.exposeInMainWorld('clipboard', {
readText: () => ipcRenderer.invoke('clipboard:readText'),
writeText: (text) => ipcRenderer.invoke('clipboard:writeText', text)
})

View File

@@ -1,9 +1,7 @@
const { clipboard } = require('electron')
const pasteBtn = document.getElementById('paste-to')
pasteBtn.addEventListener('click', () => {
clipboard.writeText('What a demo!')
const message = `Clipboard contents: ${clipboard.readText()}`
pasteBtn.addEventListener('click', async () => {
await clipboard.writeText('What a demo!')
const message = `Clipboard contents: ${await clipboard.readText()}`
document.getElementById('paste-from').innerHTML = message
})

View File

@@ -23,6 +23,8 @@ if (!gotTheLock) {
if (mainWindow.isMinimized()) mainWindow.restore()
mainWindow.focus()
}
dialog.showErrorBox('Welcome Back', `You arrived from: ${commandLine.pop().slice(0,-1)}`)
})
// Create mainWindow, load the rest of the app, etc...

View File

@@ -33,4 +33,4 @@ template and submit a new issue.
[(publish)]: https://www.electronforge.io/cli#publish
[GitHub issue tracker]: https://github.com/electron/forge/issues
[discord]: https://discord.gg/APGC3k5yaH
[tutorial]: https://www.electronjs.org/docs/latest/tutorial/tutorial-prerequisites
[tutorial]: ./tutorial-1-prerequisites.md

View File

@@ -12,7 +12,7 @@ hide_title: true
<!-- ✍ Update this section if you want to provide more details -->
This guide will take you through the process of setting your Electron app as the default
handler for a specific [protocol](https://www.electronjs.org/docs/api/protocol).
handler for a specific [protocol](../api/protocol.md).
By the end of this tutorial, we will have set our app to intercept and handle
any clicked URLs that start with a specific protocol. In this guide, the protocol
@@ -61,7 +61,7 @@ const createWindow = () => {
In this next step, we will create our `BrowserWindow` and tell our application how to handle an event in which an external protocol is clicked.
This code will be different in Windows compared to MacOS and Linux. This is due to Windows requiring additional code in order to open the contents of the protocol link within the same Electron instance. Read more about this [here](https://www.electronjs.org/docs/api/app#apprequestsingleinstancelock).
This code will be different in Windows compared to MacOS and Linux. This is due to Windows requiring additional code in order to open the contents of the protocol link within the same Electron instance. Read more about this [here](../api/app.md#apprequestsingleinstancelockadditionaldata).
#### Windows code:
@@ -77,17 +77,15 @@ if (!gotTheLock) {
if (mainWindow.isMinimized()) mainWindow.restore()
mainWindow.focus()
}
// the commandLine is array of strings in which last element is deep link url
// the url str ends with /
dialog.showErrorBox('Welcome Back', `You arrived from: ${commandLine.pop().slice(0, -1)}`)
})
// Create mainWindow, load the rest of the app, etc...
app.whenReady().then(() => {
createWindow()
})
// Handle the protocol. In this case, we choose to show an Error Box.
app.on('open-url', (event, url) => {
dialog.showErrorBox('Welcome Back', `You arrived from: ${url}`)
})
}
```

View File

@@ -13,7 +13,7 @@ hide_title: true
<!-- ✍ Update this section if you want to provide more details -->
This guide will take you through the process of creating a
[Tray](https://www.electronjs.org/docs/api/tray) icon with
[Tray](../api/tray.md) icon with
its own context menu to the system's notification area.
On MacOS and Ubuntu, the Tray will be located on the top
@@ -31,11 +31,11 @@ const { app, Tray, Menu, nativeImage } = require('electron')
```
Next we will create our Tray. To do this, we will use a
[`NativeImage`](https://www.electronjs.org/docs/api/native-image) icon,
[`NativeImage`](../api/native-image.md) icon,
which can be created through any one of these
[methods](https://www.electronjs.org/docs/api/native-image#methods).
[methods](../api/native-image.md#methods).
Note that we wrap our Tray creation code within an
[`app.whenReady`](https://www.electronjs.org/docs/api/app#appwhenready)
[`app.whenReady`](../api/app.md#appwhenready)
as we will need to wait for our electron app to finish initializing.
```js title='main.js'
@@ -64,7 +64,7 @@ tray.setContextMenu(contextMenu)
The code above will create 4 separate radio-type items in the context menu.
To read more about constructing native menus, click
[here](https://www.electronjs.org/docs/api/menu#menubuildfromtemplatetemplate).
[here](../api/menu.md#menubuildfromtemplatetemplate).
Finally, let's give our tray a tooltip and a title.

View File

@@ -35,9 +35,15 @@ filenames = {
"shell/browser/relauncher_linux.cc",
"shell/browser/ui/electron_desktop_window_tree_host_linux.cc",
"shell/browser/ui/file_dialog_gtk.cc",
"shell/browser/ui/gtk/menu_gtk.cc",
"shell/browser/ui/gtk/menu_gtk.h",
"shell/browser/ui/gtk/menu_util.cc",
"shell/browser/ui/gtk/menu_util.h",
"shell/browser/ui/message_box_gtk.cc",
"shell/browser/ui/tray_icon_gtk.cc",
"shell/browser/ui/tray_icon_gtk.h",
"shell/browser/ui/status_icon_gtk.cc",
"shell/browser/ui/status_icon_gtk.h",
"shell/browser/ui/tray_icon_linux.cc",
"shell/browser/ui/tray_icon_linux.h",
"shell/browser/ui/views/client_frame_view_linux.cc",
"shell/browser/ui/views/client_frame_view_linux.h",
"shell/common/application_info_linux.cc",

View File

@@ -28,11 +28,47 @@ type PostData = LoadURLOptions['postData']
// Stock page sizes
const PDFPageSizes: Record<string, ElectronInternal.MediaSize> = {
A5: {
custom_display_name: 'A5',
height_microns: 210000,
name: 'ISO_A5',
width_microns: 148000
Letter: {
custom_display_name: 'Letter',
height_microns: 279400,
name: 'NA_LETTER',
width_microns: 215900
},
Legal: {
custom_display_name: 'Legal',
height_microns: 355600,
name: 'NA_LEGAL',
width_microns: 215900
},
Tabloid: {
height_microns: 431800,
name: 'NA_LEDGER',
width_microns: 279400,
custom_display_name: 'Tabloid'
},
A0: {
custom_display_name: 'A0',
height_microns: 1189000,
name: 'ISO_A0',
width_microns: 841000
},
A1: {
custom_display_name: 'A1',
height_microns: 841000,
name: 'ISO_A1',
width_microns: 594000
},
A2: {
custom_display_name: 'A2',
height_microns: 594000,
name: 'ISO_A2',
width_microns: 420000
},
A3: {
custom_display_name: 'A3',
height_microns: 420000,
name: 'ISO_A3',
width_microns: 297000
},
A4: {
custom_display_name: 'A4',
@@ -41,29 +77,17 @@ const PDFPageSizes: Record<string, ElectronInternal.MediaSize> = {
is_default: 'true',
width_microns: 210000
},
A3: {
custom_display_name: 'A3',
height_microns: 420000,
name: 'ISO_A3',
width_microns: 297000
A5: {
custom_display_name: 'A5',
height_microns: 210000,
name: 'ISO_A5',
width_microns: 148000
},
Legal: {
custom_display_name: 'Legal',
height_microns: 355600,
name: 'NA_LEGAL',
width_microns: 215900
},
Letter: {
custom_display_name: 'Letter',
height_microns: 279400,
name: 'NA_LETTER',
width_microns: 215900
},
Tabloid: {
height_microns: 431800,
name: 'NA_LEDGER',
width_microns: 279400,
custom_display_name: 'Tabloid'
A6: {
custom_display_name: 'A6',
height_microns: 148000,
name: 'ISO_A6',
width_microns: 105000
}
} as const;

View File

@@ -21,8 +21,9 @@ global.module = new Module('electron/js2c/worker_init');
global.require = makeRequireFunction(global.module);
// Set the __filename to the path of html file if it is file: protocol.
if (self.location.protocol === 'file:') {
const pathname = process.platform === 'win32' && self.location.pathname[0] === '/' ? self.location.pathname.substr(1) : self.location.pathname;
// NB. 'self' isn't defined in an AudioWorklet.
if (typeof self !== 'undefined' && self.location.protocol === 'file:') {
const pathname = process.platform === 'win32' && self?.location.pathname[0] === '/' ? self?.location.pathname.substr(1) : self?.location.pathname;
global.__filename = path.normalize(decodeURIComponent(pathname));
global.__dirname = path.dirname(global.__filename);

View File

@@ -6,9 +6,10 @@
"devDependencies": {
"@azure/storage-blob": "^12.9.0",
"@electron/docs-parser": "^1.0.0",
"@electron/fiddle-core": "^1.0.4",
"@electron/github-app-auth": "^1.5.0",
"@electron/typescript-definitions": "^8.10.0",
"@octokit/rest": "^18.0.3",
"@octokit/rest": "^19.0.7",
"@primer/octicons": "^10.0.0",
"@types/basic-auth": "^1.1.3",
"@types/busboy": "^0.2.3",

View File

@@ -1 +1,2 @@
fix_rename_webswapcgllayer_to_webswapcgllayerchromium.patch
cherry-pick-55e2b6daba9d.patch

View File

@@ -0,0 +1,136 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shahbaz Youssefi <syoussefi@chromium.org>
Date: Thu, 16 Feb 2023 23:16:46 -0500
Subject: Vulkan: Don't close render pass if rebind to same fbo
M108 merge issues:
src/libANGLE/renderer/vulkan/ContextVk.cpp:
- hasActiveRenderPass named hasStartedRenderPass in 108
- getLastRenderPassQueueSerial named getLastRenderPassSerial in 108
In the Vulkan backend, the render pass can occasionally (and
transiently) be in a state of "open but inactive". This is when the
render pass is closed, but has the potential for future modifications
(for example to add a resolve attachment). Under many circumstances, it
is expected that an open render pass cannot be in such a state.
This assumption can be broken in this scenario:
- Open render pass, draw, etc
- Change framebuffer binding
- Change framebuffer binding back to original
- Masked Clear
When ContextVk is synced before clear, it sees that the framebuffer
binding is changed (though it hasn't really), and it closes the render
passes and sets the render pass dirty bit. If a draw were to follow, a
new render pass would have started (unnecessarily). However, in the
case of a masked clear, UtilsVk notices that the render pass is started,
assumes it must be active, and continues recording to it. While the
operation itself succeeds, the assumption that the render pass is active
is false (and fails assertion).
This change makes sure that framebuffer binding change is no-oped if the
framebuffer is the same one that has opened the current render pass. If
any application does unnecessary binding changes and back, it will be
optimized by this change as well.
Bug: chromium:1411210
Change-Id: I37a3a9f2eaa1a81a1b3393840b9458ec71a87377
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4261215
Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
(cherry picked from commit 05e62f39412e8c6bfc98582f5e7a49041991c97b)
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4303738
Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
diff --git a/src/libANGLE/renderer/vulkan/ContextVk.cpp b/src/libANGLE/renderer/vulkan/ContextVk.cpp
index f08877444f66ac2d61953c9c56d4c71d253d53c6..31e1882c8923b81bf5fd74fbe40d8233c7551ec9 100644
--- a/src/libANGLE/renderer/vulkan/ContextVk.cpp
+++ b/src/libANGLE/renderer/vulkan/ContextVk.cpp
@@ -5022,6 +5022,15 @@ angle::Result ContextVk::syncState(const gl::Context *context,
// as some optimizations in non-draw commands require the render pass to remain
// open, such as invalidate or blit. Note that we always start a new command buffer
// because we currently can only support one open RenderPass at a time.
+ //
+ // The render pass is not closed if binding is changed to the same framebuffer as
+ // before.
+ if (hasStartedRenderPass() &&
+ hasStartedRenderPassWithSerial(drawFramebufferVk->getLastRenderPassSerial()))
+ {
+ break;
+ }
+
onRenderPassFinished(RenderPassClosureReason::FramebufferBindingChange);
if (getFeatures().preferSubmitAtFBOBoundary.enabled)
{
diff --git a/src/tests/gl_tests/ClearTest.cpp b/src/tests/gl_tests/ClearTest.cpp
index 1a6b425da6be1e1c2526a8f5e5d84ea8049ee7ab..41e3ea7efe26d1aa0e0dd0e8e9d5bcd7b6472017 100644
--- a/src/tests/gl_tests/ClearTest.cpp
+++ b/src/tests/gl_tests/ClearTest.cpp
@@ -2864,6 +2864,26 @@ TEST_P(ClearTest, DISABLED_ClearReachesWindow)
angle::Sleep(2000);
}
+// Tests that masked clear after a no-op framebuffer binding change with an open render pass works.
+TEST_P(ClearTest, DrawThenChangeFBOBindingAndBackThenMaskedClear)
+{
+ ANGLE_GL_PROGRAM(blueProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
+
+ // Draw blue.
+ drawQuad(blueProgram, essl1_shaders::PositionAttrib(), 0.5f);
+
+ // Change framebuffer and back
+ glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+
+ // Masked clear
+ glColorMask(1, 0, 0, 1);
+ glClearColor(1.0f, 0.5f, 0.5f, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::magenta);
+}
+
// Test that clearing slices of a 3D texture and reading them back works.
TEST_P(ClearTestES3, ClearAndReadPixels3DTexture)
{
diff --git a/src/tests/gl_tests/VulkanPerformanceCounterTest.cpp b/src/tests/gl_tests/VulkanPerformanceCounterTest.cpp
index 7268d08da90e27022f7139aa98b5972e1dfe62f1..6a91ecc2b4329696f573db3451dac35a0a795c8c 100644
--- a/src/tests/gl_tests/VulkanPerformanceCounterTest.cpp
+++ b/src/tests/gl_tests/VulkanPerformanceCounterTest.cpp
@@ -5,7 +5,7 @@
//
// VulkanPerformanceCounterTest:
// Validates specific GL call patterns with ANGLE performance counters.
-// For example we can verify a certain call set doesn't break the RenderPass.
+// For example we can verify a certain call set doesn't break the render pass.
#include "test_utils/ANGLETest.h"
#include "test_utils/angle_test_instantiate.h"
@@ -6991,6 +6991,26 @@ TEST_P(VulkanPerformanceCounterTest, EndXfbAfterRenderPassClosed)
EXPECT_EQ(getPerfCounters().renderPasses, expectedRenderPassCount);
}
+// Verify that changing framebuffer and back doesn't break the render pass.
+TEST_P(VulkanPerformanceCounterTest, FBOChangeAndBackDoesNotBreakRenderPass)
+{
+ uint64_t expectedRenderPassCount = getPerfCounters().renderPasses + 1;
+
+ ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());
+ drawQuad(drawRed, essl1_shaders::PositionAttrib(), 0);
+
+ GLFramebuffer fbo;
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+
+ drawQuad(drawRed, essl1_shaders::PositionAttrib(), 0);
+
+ // Verify render pass count.
+ EXPECT_EQ(getPerfCounters().renderPasses, expectedRenderPassCount);
+
+ EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
+}
+
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(VulkanPerformanceCounterTest);
ANGLE_INSTANTIATE_TEST(VulkanPerformanceCounterTest, ES3_VULKAN(), ES3_VULKAN_SWIFTSHADER());

View File

@@ -126,3 +126,13 @@ cherry-pick-2611772cf0a0.patch
cherry-pick-3235c1d1955b.patch
expose_v8initializer_codegenerationcheckcallbackinmainthread.patch
cherry-pick-43637378b14e.patch
axselectedtextmarkerrange_should_not_be_backwards.patch
fix_x11_window_restore_minimized_maximized_window.patch
m108-lts_simplify_webmediaplayermscompositor_destruction.patch
m108-lts_further_simplify_webmediaplayermscompositor_lifetime.patch
cherry-pick-e79b89b47dac.patch
cherry-pick-06851790480e.patch
cherry-pick-aeec1ba5893d.patch
cherry-pick-38de42d2bbc3.patch
cherry-pick-8731bd8a30f6.patch
cherry-pick-26bfa5807606.patch

View File

@@ -0,0 +1,57 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Valerie Young <spectranaut@igalia.com>
Date: Mon, 14 Nov 2022 19:53:31 +0000
Subject: AXSelectedTextMarkerRange should not be backwards
AXSelectedTextMarkerRange was changed to backwards in this commit:
https://chromium-review.googlesource.com/c/chromium/src/+/2330812
In response to this bug:
https://bugs.chromium.org/p/chromium/issues/detail?id=1110480
After switching the range back to forward, the bug above is not
repeatable.
Fixed: 1172956
Change-Id: I8f32e807e91514e3d74393b1ec54960ffdfacdcb
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3994770
Reviewed-by: Aaron Leventhal <aleventhal@chromium.org>
Commit-Queue: Valerie Young <spectranaut@igalia.com>
Cr-Commit-Position: refs/heads/main@{#1071150}
diff --git a/content/browser/accessibility/ax_tree_formatter_mac_browsertest.mm b/content/browser/accessibility/ax_tree_formatter_mac_browsertest.mm
index 46426469b3728f470c102812c454fd838b3f006f..250180222304766ca2b25d1dcd5df248f3087833 100644
--- a/content/browser/accessibility/ax_tree_formatter_mac_browsertest.mm
+++ b/content/browser/accessibility/ax_tree_formatter_mac_browsertest.mm
@@ -206,7 +206,7 @@ AccessibilityNotificationWaiter waiter(shell()->web_contents(),
</script>)~~",
{":3;AXSelectedTextMarkerRange=*"}, R"~~(AXWebArea
++AXGroup
-++++AXStaticText AXSelectedTextMarkerRange={anchor: {:2, -1, down}, focus: {:3, 0, down}}
+++++AXStaticText AXSelectedTextMarkerRange={anchor: {:3, 0, down}, focus: {:2, -1, down}}
)~~");
}
diff --git a/content/browser/accessibility/browser_accessibility_cocoa.mm b/content/browser/accessibility/browser_accessibility_cocoa.mm
index 55cce7ff53b355cea2787abca6140f122f6a0369..202923773d7adb2fad5c15be4558bfd548ec6c7d 100644
--- a/content/browser/accessibility/browser_accessibility_cocoa.mm
+++ b/content/browser/accessibility/browser_accessibility_cocoa.mm
@@ -1347,9 +1347,7 @@ - (id)selectedTextMarkerRange {
if (ax_range.IsNull())
return nil;
- // Voiceover expects this range to be backwards in order to read the selected
- // words correctly.
- return AXRangeToAXTextMarkerRange(ax_range.AsBackwardRange());
+ return AXRangeToAXTextMarkerRange(std::move(ax_range));
}
- (NSString*)sortDirection {
diff --git a/content/test/data/accessibility/mac/selection/selectall-textarea-expected.txt b/content/test/data/accessibility/mac/selection/selectall-textarea-expected.txt
index f2638c5d03b16266e781bb74cfc08c65f7c0a60d..34036471ad01d0fcfc7bd9b7213f1b4edcded719 100644
--- a/content/test/data/accessibility/mac/selection/selectall-textarea-expected.txt
+++ b/content/test/data/accessibility/mac/selection/selectall-textarea-expected.txt
@@ -1,4 +1,4 @@
textarea_range={anchor: {:3, 0, down}, focus: {:3, 19, down}}
textarea.AXSelectedTextMarkerRange={anchor: {:3, 0, down}, focus: {:3, 19, down}}
AXSelectedTextChanged on AXTextArea AXValue='The quick brown fox' AXTextSelectionDirection=AXTextSelectionDirectionUnknown AXTextSelectionGranularity=AXTextSelectionGranularityUnknown AXTextStateChangeType=AXTextStateChangeTypeSelectionMove
-textarea.AXSelectedTextMarkerRange={anchor: {:3, 19, down}, focus: {:3, 0, down}}
+textarea.AXSelectedTextMarkerRange={anchor: {:3, 0, down}, focus: {:3, 19, down}}

View File

@@ -0,0 +1,91 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: "Tommy C. Li" <tommycli@chromium.org>
Date: Tue, 21 Feb 2023 18:55:00 +0000
Subject: Exclude Policy and Play API engines from Sync merging
There's a security bug in which the call to ResetTemplateURLGUID can
cause a policy-created engine to be deleted. This means that after
the call, either the current `conflicting_turl` pointer, or future
iterations in the loop may point to an already-freed TemplateURL,
causing the use-after free bug.
This CL addresses that by forbidding Policy-created and Play API
engines from being merged into Synced engines.
Although Play API engines aren't directly affected, they seem to also
not be something that should be merged to Synced engines.
(cherry picked from commit 315632458eb795ef9d9dce3fd1062f9e6f2c2077)
Bug: 1414224
Change-Id: Ide43d71e9844e04a7ffe2e7ad2a522b6ca1535a3
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4250623
Reviewed-by: Matthew Denton <mpdenton@chromium.org>
Reviewed-by: Mikel Astiz <mastiz@chromium.org>
Commit-Queue: Tommy Li <tommycli@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1106249}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4274984
Reviewed-by: Tommy Li <tommycli@chromium.org>
Commit-Queue: Krishna Govind <govind@chromium.org>
Cr-Commit-Position: refs/branch-heads/5481@{#1238}
Cr-Branched-From: 130f3e4d850f4bc7387cfb8d08aa993d288a67a9-refs/heads/main@{#1084008}
diff --git a/chrome/browser/search_engines/template_url_service_sync_unittest.cc b/chrome/browser/search_engines/template_url_service_sync_unittest.cc
index 2de150bbca0bf9032e207754203e60f2ee1f115f..b552f1d844e44b34eadaca850408754488b9d27b 100644
--- a/chrome/browser/search_engines/template_url_service_sync_unittest.cc
+++ b/chrome/browser/search_engines/template_url_service_sync_unittest.cc
@@ -732,6 +732,34 @@ TEST_F(TemplateURLServiceSyncTest, MergeAddFromNewerSyncData) {
processor()->change_for_guid("localguid3").change_type());
}
+TEST_F(TemplateURLServiceSyncTest, MergeIgnoresPolicyAndPlayAPIEngines) {
+ // Add a policy-created engine.
+ model()->Add(CreateTestTemplateURL(u"key1", "http://key1.com", "localguid1",
+ base::Time::FromTimeT(100),
+ /*safe_for_autoreplace=*/false,
+ /*created_by_policy=*/true));
+
+ {
+ auto play_api_engine = CreateTestTemplateURL(
+ u"key2", "http://key2.com", "localguid2", base::Time::FromTimeT(100));
+ TemplateURLData data(play_api_engine->data());
+ data.created_from_play_api = true;
+ play_api_engine = std::make_unique<TemplateURL>(data);
+ model()->Add(std::move(play_api_engine));
+ }
+
+ ASSERT_EQ(1U, model()->GetAllSyncData(syncer::SEARCH_ENGINES).size());
+ MergeAndExpectNotify(CreateInitialSyncData(), 1);
+
+ // The policy engine should be ignored when it comes to conflict resolution.
+ EXPECT_TRUE(model()->GetTemplateURLForGUID("guid1"));
+ EXPECT_TRUE(model()->GetTemplateURLForGUID("localguid1"));
+
+ // The Play API engine should be ignored when it comes to conflict resolution.
+ EXPECT_TRUE(model()->GetTemplateURLForGUID("guid2"));
+ EXPECT_TRUE(model()->GetTemplateURLForGUID("localguid2"));
+}
+
TEST_F(TemplateURLServiceSyncTest, ProcessChangesEmptyModel) {
// We initially have no data.
MergeAndExpectNotify({}, 0);
diff --git a/components/search_engines/template_url_service.cc b/components/search_engines/template_url_service.cc
index 61e7fabfed76c251ee2e3186ab60c56da54be551..824383536eed1560aa50b6892603e3a1aa601c53 100644
--- a/components/search_engines/template_url_service.cc
+++ b/components/search_engines/template_url_service.cc
@@ -2175,7 +2175,14 @@ void TemplateURLService::MergeInSyncTemplateURL(
keyword_to_turl_and_length_.equal_range(sync_turl->keyword());
for (auto it = match_range.first; it != match_range.second; ++it) {
TemplateURL* local_turl = it->second.first;
- if (local_turl->type() == TemplateURL::NORMAL) {
+ // The conflict resolution code below sometimes resets the TemplateURL's
+ // GUID, which can trigger deleting any Policy-created engines. Avoid this
+ // use-after-free bug by excluding any Policy-created engines. Also exclude
+ // Play API created engines, as those also seem local-only and should not
+ // be merged into Synced engines. crbug.com/1414224.
+ if (local_turl->type() == TemplateURL::NORMAL &&
+ !local_turl->created_by_policy() &&
+ !local_turl->created_from_play_api()) {
local_duplicates.push_back(local_turl);
}
}

View File

@@ -0,0 +1,61 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: "Steinar H. Gunderson" <sesse@chromium.org>
Date: Tue, 14 Mar 2023 15:53:57 +0000
Subject: In Typed CSSOM, reject adding to something that is not a list.
M108 merge issues:
third_party/blink/renderer/core/css/cssom/style_property_map.cc:
The check before the added IsValueList check isn't present in 108
(cherry picked from commit 7301cf1e40fdd97594ea491676b867cf4e577edc)
Fixed: 1417176
Change-Id: Idef1a81af46d334c181979778c28f19ce6369718
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4293477
Commit-Queue: Steinar H Gunderson <sesse@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1110281}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4306796
Commit-Queue: Zakhar Voit <voit@google.com>
Reviewed-by: Steinar H Gunderson <sesse@chromium.org>
Owners-Override: Achuith Bhandarkar <achuith@chromium.org>
Reviewed-by: Achuith Bhandarkar <achuith@chromium.org>
Cr-Commit-Position: refs/branch-heads/5359@{#1405}
Cr-Branched-From: 27d3765d341b09369006d030f83f582a29eb57ae-refs/heads/main@{#1058933}
diff --git a/third_party/blink/renderer/core/css/cssom/style_property_map.cc b/third_party/blink/renderer/core/css/cssom/style_property_map.cc
index 2c1bcba6022519c3a865ae8e3c2ffcd5bc385cf3..0cde402b49510514599201d2b3104e56ddd7b572 100644
--- a/third_party/blink/renderer/core/css/cssom/style_property_map.cc
+++ b/third_party/blink/renderer/core/css/cssom/style_property_map.cc
@@ -365,6 +365,17 @@ void StylePropertyMap::append(
CSSValueList* current_value = nullptr;
if (const CSSValue* css_value = GetProperty(property_id)) {
+ if (!css_value->IsValueList()) {
+ // The standard doesn't seem to cover this explicitly
+ // (https://github.com/w3c/css-houdini-drafts/issues/823),
+ // but the only really reasonable solution seems to be
+ // to throw a TypeError.
+ //
+ // This covers e.g. system-wide CSS keywords, like inherit.
+ exception_state.ThrowTypeError(
+ "Cannot append to something that is not a list");
+ return;
+ }
current_value = To<CSSValueList>(css_value)->Copy();
} else {
current_value = CssValueListForPropertyID(property_id);
diff --git a/third_party/blink/web_tests/external/wpt/css/css-typed-om/the-stylepropertymap/inline/append.tentative.html b/third_party/blink/web_tests/external/wpt/css/css-typed-om/the-stylepropertymap/inline/append.tentative.html
index ee9a9e4ddbcf78a7517d8d038d66844880719e63..f80875622366939f48a7471513fb6319f75be718 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-typed-om/the-stylepropertymap/inline/append.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-typed-om/the-stylepropertymap/inline/append.tentative.html
@@ -56,4 +56,10 @@ test(t => {
assert_style_value_array_equals(result, [CSS.s(5), CSS.s(10), CSS.s(1), CSS.s(2)]);
}, 'StylePropertyMap.append is case-insensitive');
+// https://crbug.com/1417176
+test(t => {
+ let styleMap = createInlineStyleMap(t, 'transition-duration: inherit');
+ assert_throws_js(TypeError, () => styleMap.append('transition-duration', '1s'));
+}, 'StylePropertyMap.append rejects appending to CSS-wide keywords');
+
</script>

View File

@@ -0,0 +1,37 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Will Harris <wfh@chromium.org>
Date: Thu, 2 Mar 2023 10:23:28 +0000
Subject: Fix potential out of bounds write in base::SampleVectorBase
BUG=1417185
(cherry picked from commit 552939b035e724e022fedb90fd80cd008e441fcf)
Change-Id: I70719d0f9afb81dda373f88ab3a1c177397659ec
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4265437
Commit-Queue: Will Harris <wfh@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1106984}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4289351
Commit-Queue: Zakhar Voit <voit@google.com>
Reviewed-by: Victor-Gabriel Savu <vsavu@google.com>
Owners-Override: Victor-Gabriel Savu <vsavu@google.com>
Cr-Commit-Position: refs/branch-heads/5359@{#1397}
Cr-Branched-From: 27d3765d341b09369006d030f83f582a29eb57ae-refs/heads/main@{#1058933}
diff --git a/base/metrics/sample_vector.cc b/base/metrics/sample_vector.cc
index cec7687eeeb3daea85f5bec24765bb5aed5f1c6a..a6995578515a292631dca6044e5ee23c14803e5a 100644
--- a/base/metrics/sample_vector.cc
+++ b/base/metrics/sample_vector.cc
@@ -274,6 +274,12 @@ void SampleVectorBase::MoveSingleSampleToCounts() {
if (sample.count == 0)
return;
+ // Stop here if the sample bucket would be out of range for the AtomicCount
+ // array.
+ if (sample.bucket >= counts_size()) {
+ return;
+ }
+
// Move the value into storage. Sum and redundant-count already account
// for this entry so no need to call IncreaseSumAndCount().
subtle::NoBarrier_AtomicIncrement(&counts()[sample.bucket], sample.count);

View File

@@ -0,0 +1,595 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Alex Moshchuk <alexmos@chromium.org>
Date: Fri, 3 Mar 2023 22:17:24 +0000
Subject: Use optional SafeRef to save RenderFrameHost in NavigationRequest
This prevents use-after-free if NavigationRequests somehow still
points to an already-deleted RFH, which is currently possible (see bug).
Also converts usages of `render_frame_host_` to use the
GetRenderFrameHost() function to ensure that they are all called after
the final RenderFrameHost is picked for the navigation.
(cherry picked from commit 7b75ae34df6d15acf4e5a45f12c9dca4ce7f2586)
Bug: 1416916
Change-Id: I45569e7bb1f160158dc3139fc9e49d7d6bb56738
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4278923
Reviewed-by: Hiroki Nakagawa <nhiroki@chromium.org>
Commit-Queue: Rakina Zata Amni <rakina@chromium.org>
Reviewed-by: Alex Moshchuk <alexmos@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1112656}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4308070
Reviewed-by: Charlie Reis <creis@chromium.org>
Commit-Queue: Alex Moshchuk <alexmos@chromium.org>
Cr-Commit-Position: refs/branch-heads/5481@{#1322}
Cr-Branched-From: 130f3e4d850f4bc7387cfb8d08aa993d288a67a9-refs/heads/main@{#1084008}
diff --git a/content/browser/renderer_host/navigation_request.cc b/content/browser/renderer_host/navigation_request.cc
index 1496adf92d0e0c7868869263eba5c7786bed6bd8..f6f25544bd36fceb60ada013178cc8fb67e7b10a 100644
--- a/content/browser/renderer_host/navigation_request.cc
+++ b/content/browser/renderer_host/navigation_request.cc
@@ -1450,7 +1450,7 @@ NavigationRequest::CreateForSynchronousRendererCommit(
subresource_web_bundle_navigation_info->token(),
subresource_web_bundle_navigation_info->render_process_id()));
}
- navigation_request->render_frame_host_ = render_frame_host;
+ navigation_request->render_frame_host_ = render_frame_host->GetSafeRef();
navigation_request->coep_reporter_ = std::move(coep_reporter);
navigation_request->isolation_info_for_subresources_ =
isolation_info_for_subresources;
@@ -1964,7 +1964,7 @@ NavigationRequest::GetCommitDeferringConditionForTesting() {
void NavigationRequest::BeginNavigation() {
EnterChildTraceEvent("BeginNavigation", this);
DCHECK(!loader_);
- DCHECK(!render_frame_host_);
+ DCHECK(!HasRenderFrameHost());
ScopedCrashKeys crash_keys(*this);
if (begin_navigation_callback_for_testing_) {
@@ -2342,7 +2342,7 @@ void NavigationRequest::BeginNavigationImpl() {
// expect us to use the current RenderFrameHost for this NavigationRequest,
// and https://crbug.com/1125106.
if (IsSameDocument()) {
- render_frame_host_ = frame_tree_node_->current_frame_host();
+ render_frame_host_ = frame_tree_node_->current_frame_host()->GetSafeRef();
} else {
// [spec]: https://html.spec.whatwg.org/C/#process-a-navigate-response
// 4. if [...] the result of checking a navigation response's adherence to
@@ -2368,11 +2368,12 @@ void NavigationRequest::BeginNavigationImpl() {
origin, net::NetworkAnonymizationKey(site, site));
// Select an appropriate RenderFrameHost.
- render_frame_host_ =
- frame_tree_node_->render_manager()->GetFrameHostForNavigation(this);
+ render_frame_host_ = frame_tree_node_->render_manager()
+ ->GetFrameHostForNavigation(this)
+ ->GetSafeRef();
CHECK(Navigator::CheckWebUIRendererDoesNotDisplayNormalURL(
- render_frame_host_, GetUrlInfo(),
+ &*render_frame_host_.value(), GetUrlInfo(),
/*is_renderer_initiated_check=*/false));
}
@@ -2601,8 +2602,8 @@ void NavigationRequest::ResetForCrossDocumentRestart() {
// Reset the previously selected RenderFrameHost. This is expected to be null
// at the beginning of a new navigation. See https://crbug.com/936962.
- DCHECK(render_frame_host_);
- render_frame_host_ = nullptr;
+ DCHECK(HasRenderFrameHost());
+ render_frame_host_ = absl::nullopt;
// Convert the navigation type to the appropriate cross-document one.
common_params_->navigation_type =
@@ -2660,7 +2661,7 @@ mojom::NavigationClient* NavigationRequest::GetCommitNavigationClient() {
// Instantiate a new NavigationClient interface.
commit_navigation_client_ =
- render_frame_host_->GetNavigationClientFromInterfaceProvider();
+ GetRenderFrameHost()->GetNavigationClientFromInterfaceProvider();
HandleInterfaceDisconnection(
&commit_navigation_client_,
base::BindOnce(
@@ -2731,7 +2732,7 @@ void NavigationRequest::CreateCoepReporter(
common_params_->url,
policies.cross_origin_embedder_policy.reporting_endpoint,
policies.cross_origin_embedder_policy.report_only_reporting_endpoint,
- render_frame_host_->GetFrameToken().value(),
+ GetRenderFrameHost()->GetFrameToken().value(),
isolation_info_for_subresources_.network_anonymization_key());
}
@@ -3133,7 +3134,7 @@ void NavigationRequest::DetermineOriginAgentClusterEndResult() {
? url::Origin::Create(common_params_->base_url_for_data_url)
: url::Origin::Create(common_params_->url);
const IsolationContext& isolation_context =
- render_frame_host_->GetSiteInstance()->GetIsolationContext();
+ GetRenderFrameHost()->GetSiteInstance()->GetIsolationContext();
bool is_requested = IsOriginAgentClusterOptInRequested();
bool expects_origin_agent_cluster = is_requested || IsIsolationImplied();
@@ -3241,7 +3242,7 @@ void NavigationRequest::ProcessOriginAgentClusterEndResult() {
origin_agent_cluster_end_result_ ==
OriginAgentClusterEndResult::kExplicitlyRequestedButNotOriginKeyed) {
GetContentClient()->browser()->LogWebFeatureForCurrentPage(
- render_frame_host_,
+ GetRenderFrameHost(),
blink::mojom::WebFeature::kOriginAgentClusterHeader);
}
@@ -3251,7 +3252,7 @@ void NavigationRequest::ProcessOriginAgentClusterEndResult() {
OriginAgentClusterEndResult::kRequestedButNotOriginKeyed ||
origin_agent_cluster_end_result_ ==
OriginAgentClusterEndResult::kExplicitlyRequestedButNotOriginKeyed) {
- render_frame_host_->AddMessageToConsole(
+ GetRenderFrameHost()->AddMessageToConsole(
blink::mojom::ConsoleMessageLevel::kWarning,
base::StringPrintf(
"The page requested an origin-keyed agent cluster using the "
@@ -3266,7 +3267,7 @@ void NavigationRequest::ProcessOriginAgentClusterEndResult() {
OriginAgentClusterEndResult::kNotRequestedButOriginKeyed ||
origin_agent_cluster_end_result_ ==
OriginAgentClusterEndResult::kExplicitlyNotRequestedButOriginKeyed) {
- render_frame_host_->AddMessageToConsole(
+ GetRenderFrameHost()->AddMessageToConsole(
blink::mojom::ConsoleMessageLevel::kWarning,
base::StringPrintf(
"The page did not request an origin-keyed agent cluster, but was "
@@ -3281,7 +3282,7 @@ void NavigationRequest::PopulateDocumentTokenForCrossDocumentNavigation() {
DCHECK(!IsSameDocument());
DCHECK_GE(state_, READY_TO_COMMIT);
const auto* token_to_reuse =
- render_frame_host_->GetDocumentTokenForCrossDocumentNavigationReuse(
+ GetRenderFrameHost()->GetDocumentTokenForCrossDocumentNavigationReuse(
/* passkey */ {});
document_token_.emplace(token_to_reuse ? *token_to_reuse
: blink::DocumentToken());
@@ -3805,45 +3806,47 @@ void NavigationRequest::OnResponseStarted(
BackForwardCacheImpl::Entry* entry =
controller->GetBackForwardCache().GetEntry(nav_entry_id_);
CHECK(entry);
- render_frame_host_ = entry->render_frame_host();
- CHECK(render_frame_host_);
+ CHECK(entry->render_frame_host());
+ render_frame_host_ = entry->render_frame_host()->GetSafeRef();
} else if (IsPrerenderedPageActivation()) {
// Prerendering requires changing pages starting at the root node.
DCHECK(IsInMainFrame());
- render_frame_host_ =
- GetPrerenderHostRegistry().GetRenderFrameHostForReservedHost(
- prerender_frame_tree_node_id_.value());
- // TODO(https://crbug.com/1181712): Handle the cases when the prerender is
- // cancelled and RFH is destroyed while NavigationRequest is alive.
+ render_frame_host_ = GetPrerenderHostRegistry()
+ .GetRenderFrameHostForReservedHost(
+ prerender_frame_tree_node_id_.value())
+ ->GetSafeRef();
} else if (response_should_be_rendered_) {
- render_frame_host_ =
- frame_tree_node_->render_manager()->GetFrameHostForNavigation(this);
+ render_frame_host_ = frame_tree_node_->render_manager()
+ ->GetFrameHostForNavigation(this)
+ ->GetSafeRef();
// Update the associated RenderFrameHost type, which could have changed
// due to redirects during navigation.
set_associated_rfh_type(
- render_frame_host_ ==
+ GetRenderFrameHost() ==
frame_tree_node_->render_manager()->current_frame_host()
? AssociatedRenderFrameHostType::CURRENT
: AssociatedRenderFrameHostType::SPECULATIVE);
if (!Navigator::CheckWebUIRendererDoesNotDisplayNormalURL(
- render_frame_host_, GetUrlInfo(),
+ GetRenderFrameHost(), GetUrlInfo(),
/* is_renderer_initiated_check */ false)) {
CHECK(false);
}
} else {
- render_frame_host_ = nullptr;
+ render_frame_host_ = absl::nullopt;
}
- if (!render_frame_host_)
+ if (!HasRenderFrameHost()) {
DCHECK(!response_should_be_rendered_);
+ }
- if (render_frame_host_)
+ if (HasRenderFrameHost()) {
DetermineOriginAgentClusterEndResult();
+ }
- if (!commit_params_->is_browser_initiated && render_frame_host_ &&
- render_frame_host_->GetProcess() !=
+ if (!commit_params_->is_browser_initiated && HasRenderFrameHost() &&
+ GetRenderFrameHost()->GetProcess() !=
frame_tree_node_->current_frame_host()->GetProcess()) {
// Allow the embedder to cancel the cross-process commit if needed.
if (!frame_tree_node_->navigator()
@@ -3864,12 +3867,12 @@ void NavigationRequest::OnResponseStarted(
subresource_loader_params_ = std::move(subresource_loader_params);
- if (render_frame_host_) {
+ if (HasRenderFrameHost()) {
// Set the site URL now if it hasn't been set already. If the site requires
// a dedicated process, this will lock the process to that site, which will
// prevent other sites from incorrectly reusing this process. See
// https://crbug.com/738634.
- SiteInstanceImpl* instance = render_frame_host_->GetSiteInstance();
+ SiteInstanceImpl* instance = GetRenderFrameHost()->GetSiteInstance();
if (!instance->HasSite() &&
SiteInstanceImpl::ShouldAssignSiteForURL(common_params_->url)) {
instance->ConvertToDefaultOrSetSite(GetUrlInfo());
@@ -3891,7 +3894,7 @@ void NavigationRequest::OnResponseStarted(
// navigation, and in the meantime another navigation reads the incorrect
// IsUnused() value from the same process when making a process reuse
// decision.
- render_frame_host_->GetProcess()->SetIsUsed();
+ GetRenderFrameHost()->GetProcess()->SetIsUsed();
// Now that we know the IsolationContext for the assigned SiteInstance, we
// opt the origin into OAC here if needed. Note that this doesn't need to
@@ -4005,7 +4008,7 @@ void NavigationRequest::OnResponseStarted(
return;
}
- if (render_frame_host_ &&
+ if (HasRenderFrameHost() &&
!CheckPermissionsPoliciesForFencedFrames(GetOriginToCommit())) {
OnRequestFailedInternal(
network::URLLoaderCompletionStatus(net::ERR_ABORTED),
@@ -4035,7 +4038,7 @@ NavigationRequest::CreateNavigationEarlyHintsManagerParams(
const network::mojom::EarlyHints& early_hints) {
// Early Hints preloads should happen only before the final response is
// received, and limited only in the main frame for now.
- CHECK(!render_frame_host_);
+ CHECK(!HasRenderFrameHost());
CHECK(loader_);
CHECK_LT(state_, WILL_PROCESS_RESPONSE);
CHECK(!IsSameDocument());
@@ -4178,12 +4181,12 @@ void NavigationRequest::OnRequestFailedInternal(
// Sanity check that we haven't changed the RenderFrameHost picked for the
// error page in OnRequestFailedInternal when running the WillFailRequest
// checks.
- CHECK(!render_frame_host_ || render_frame_host_ == render_frame_host);
- render_frame_host_ = render_frame_host;
+ CHECK(!HasRenderFrameHost() || GetRenderFrameHost() == render_frame_host);
+ render_frame_host_ = render_frame_host->GetSafeRef();
// Update the associated RenderFrameHost type.
set_associated_rfh_type(
- render_frame_host_ ==
+ GetRenderFrameHost() ==
frame_tree_node_->render_manager()->current_frame_host()
? AssociatedRenderFrameHostType::CURRENT
: AssociatedRenderFrameHostType::SPECULATIVE);
@@ -4191,17 +4194,17 @@ void NavigationRequest::OnRequestFailedInternal(
// Set the site URL now if it hasn't been set already. It's possible to get
// here if we navigate to an error out of an initial "blank" SiteInstance.
// Also mark the process as used, since it will be hosting an error page.
- SiteInstanceImpl* instance = render_frame_host_->GetSiteInstance();
+ SiteInstanceImpl* instance = GetRenderFrameHost()->GetSiteInstance();
if (!instance->HasSite())
instance->ConvertToDefaultOrSetSite(GetUrlInfo());
- render_frame_host_->GetProcess()->SetIsUsed();
+ GetRenderFrameHost()->GetProcess()->SetIsUsed();
// The check for WebUI should be performed only if error page isolation is
// enabled for this failed navigation. It is possible for subframe error page
// to be committed in a WebUI process as shown in https://crbug.com/944086.
if (frame_tree_node_->IsErrorPageIsolationEnabled()) {
if (!Navigator::CheckWebUIRendererDoesNotDisplayNormalURL(
- render_frame_host_, GetUrlInfo(),
+ GetRenderFrameHost(), GetUrlInfo(),
/* is_renderer_initiated_check */ false)) {
CHECK(false);
}
@@ -4520,7 +4523,7 @@ void NavigationRequest::OnStartChecksComplete(
->CreateURLLoaderNetworkObserverForNavigationRequest(*this),
NetworkServiceDevToolsObserver::MakeSelfOwned(frame_tree_node_),
std::move(cached_response_head), std::move(interceptor));
- DCHECK(!render_frame_host_);
+ DCHECK(!HasRenderFrameHost());
base::UmaHistogramTimes(
base::StrCat({"Navigation.WillStartRequestToLoaderStart.",
@@ -4792,7 +4795,10 @@ void NavigationRequest::OnWillProcessResponseChecksComplete(
!response_should_be_rendered_) {
// Reset the RenderFrameHost that had been computed for the commit of the
// navigation.
- render_frame_host_ = nullptr;
+ // TODO(https://crbug.com/1416916): Reconsider if we really need to unset
+ // the `render_frame_host_` here, as the NavigationRequest might stay alive
+ // for a bit longer to commit an error page.
+ render_frame_host_ = absl::nullopt;
// TODO(clamy): distinguish between CANCEL and CANCEL_AND_IGNORE.
if (!response_should_be_rendered_) {
@@ -4821,7 +4827,10 @@ void NavigationRequest::OnWillProcessResponseChecksComplete(
DCHECK_EQ(net::ERR_BLOCKED_BY_RESPONSE, result.net_error_code());
// Reset the RenderFrameHost that had been computed for the commit of the
// navigation.
- render_frame_host_ = nullptr;
+ // TODO(https://crbug.com/1416916): Reconsider if we really need to unset
+ // the `render_frame_host_` here, as the NavigationRequest might stay alive
+ // for a bit longer to commit an error page.
+ render_frame_host_ = absl::nullopt;
OnRequestFailedInternal(
network::URLLoaderCompletionStatus(result.net_error_code()),
true /* skip_throttles */, result.error_page_content(),
@@ -4894,7 +4903,7 @@ void NavigationRequest::CommitErrorPage(
commit_params_->origin_to_commit =
url::Origin::Create(common_params_->url).DeriveNewOpaqueOrigin();
if (request_navigation_client_.is_bound()) {
- if (render_frame_host_ == frame_tree_node()->current_frame_host()) {
+ if (GetRenderFrameHost() == frame_tree_node()->current_frame_host()) {
// Reuse the request NavigationClient for commit.
commit_navigation_client_ = std::move(request_navigation_client_);
} else {
@@ -4909,7 +4918,7 @@ void NavigationRequest::CommitErrorPage(
PopulateDocumentTokenForCrossDocumentNavigation();
// Use a separate cache shard, and no cookies, for error pages.
isolation_info_for_subresources_ = net::IsolationInfo::CreateTransient();
- render_frame_host_->FailedNavigation(
+ GetRenderFrameHost()->FailedNavigation(
this, *common_params_, *commit_params_, has_stale_copy_in_cache_,
net_error_, extended_error_code_, error_page_content, *document_token_);
@@ -4976,7 +4985,7 @@ void NavigationRequest::CommitNavigation() {
// TODO(crbug.com/979296): Consider changing this code to copy an origin
// instead of creating one from a URL which lacks opacity information.
isolation_info_for_subresources_ =
- render_frame_host_->ComputeIsolationInfoForSubresourcesForPendingCommit(
+ GetRenderFrameHost()->ComputeIsolationInfoForSubresourcesForPendingCommit(
origin, is_anonymous(), ComputeFencedFrameNonce());
DCHECK(!isolation_info_for_subresources_.IsEmpty());
@@ -4984,9 +4993,9 @@ void NavigationRequest::CommitNavigation() {
// moment. We will be able to use it once the browser can compute the origin
// to commit.
absl::optional<base::UnguessableToken> nonce =
- render_frame_host_->ComputeNonce(is_anonymous(),
+ GetRenderFrameHost()->ComputeNonce(is_anonymous(),
ComputeFencedFrameNonce());
- commit_params_->storage_key = render_frame_host_->CalculateStorageKey(
+ commit_params_->storage_key = GetRenderFrameHost()->CalculateStorageKey(
GetOriginToCommit(), base::OptionalToPtr(nonce));
if (IsServedFromBackForwardCache() || IsPrerenderedPageActivation()) {
@@ -5007,13 +5016,13 @@ void NavigationRequest::CommitNavigation() {
if (!weak_self)
return;
- DCHECK(render_frame_host_ ==
+ DCHECK(GetRenderFrameHost() ==
frame_tree_node_->render_manager()->current_frame_host() ||
- render_frame_host_ ==
+ GetRenderFrameHost() ==
frame_tree_node_->render_manager()->speculative_frame_host());
if (request_navigation_client_.is_bound()) {
- if (render_frame_host_ == frame_tree_node()->current_frame_host()) {
+ if (GetRenderFrameHost() == frame_tree_node()->current_frame_host()) {
// Reuse the request NavigationClient for commit.
commit_navigation_client_ = std::move(request_navigation_client_);
} else {
@@ -5023,9 +5032,9 @@ void NavigationRequest::CommitNavigation() {
}
}
- CreateCoepReporter(render_frame_host_->GetProcess()->GetStoragePartition());
+ CreateCoepReporter(GetRenderFrameHost()->GetProcess()->GetStoragePartition());
coop_status_.UpdateReporterStoragePartition(
- render_frame_host_->GetProcess()->GetStoragePartition());
+ GetRenderFrameHost()->GetProcess()->GetStoragePartition());
BrowserContext* browser_context =
frame_tree_node_->navigator().controller().GetBrowserContext();
@@ -5070,7 +5079,7 @@ void NavigationRequest::CommitNavigation() {
// Notify the service worker navigation handle that navigation commit is
// about to go.
service_worker_handle_->OnBeginNavigationCommit(
- render_frame_host_->GetGlobalId(),
+ GetRenderFrameHost()->GetGlobalId(),
policy_container_builder_->FinalPolicies(), std::move(reporter_remote),
&service_worker_container_info, commit_params_->document_ukm_source_id);
}
@@ -5141,7 +5150,7 @@ void NavigationRequest::CommitNavigation() {
std::move(subresource_loader_params_->prefetched_signed_exchanges);
}
- render_frame_host_->CommitNavigation(
+ GetRenderFrameHost()->CommitNavigation(
this, std::move(common_params), std::move(commit_params),
std::move(response_head), std::move(response_body_),
std::move(url_loader_client_endpoints_),
@@ -5154,7 +5163,7 @@ void NavigationRequest::CommitNavigation() {
// BrowserContext. This is mostly needed to make sure the spare is warmed-up
// if it wasn't done in RenderProcessHostImpl::GetProcessHostForSiteInstance.
RenderProcessHostImpl::NotifySpareManagerAboutRecentlyUsedBrowserContext(
- render_frame_host_->GetSiteInstance()->GetBrowserContext());
+ GetRenderFrameHost()->GetSiteInstance()->GetBrowserContext());
SendDeferredConsoleMessages();
}
@@ -5831,14 +5840,14 @@ void NavigationRequest::OnRendererRequestedNavigationCancellation() {
// The cancellation happens before READY_TO_COMMIT.
frame_tree_node_->navigator().CancelNavigation(
frame_tree_node_, NavigationDiscardReason::kCancelled);
- } else if (render_frame_host_ ==
+ } else if (GetRenderFrameHost() ==
frame_tree_node_->render_manager()->current_frame_host() ||
- !render_frame_host_->IsRenderFrameLive()) {
+ !GetRenderFrameHost()->IsRenderFrameLive()) {
// If the NavigationRequest has already reached READY_TO_COMMIT,
// `render_frame_host_` owns `this`. Cache any needed state in stack
// variables to avoid a use-after-free.
FrameTreeNode* frame_tree_node = frame_tree_node_;
- render_frame_host_->NavigationRequestCancelled(this);
+ GetRenderFrameHost()->NavigationRequestCancelled(this);
// Ensure that the speculative RFH, if any, is also cleaned up. In theory,
// `ResetNavigationRequest()` should handle this; however, it early-returns
// if there is no navigation request associated with the FrameTreeNode.
@@ -6267,7 +6276,7 @@ void NavigationRequest::DidCommitNavigation(
// Navigations in non-primary frame trees or portals don't appear in history.
if ((should_update_history_ && IsSameDocument() && !HasUserGesture() &&
params.url == previous_main_frame_url) ||
- !render_frame_host_->GetPage().IsPrimary() ||
+ !GetRenderFrameHost()->GetPage().IsPrimary() ||
frame_tree_node()->frame_tree()->IsPortal()) {
should_update_history_ = false;
}
@@ -6322,7 +6331,7 @@ void NavigationRequest::DidCommitNavigation(
ui::PageTransition transition =
ui::PageTransitionFromInt(common_params_->transition);
absl::optional<bool> is_background =
- render_frame_host_->GetProcess()->IsProcessBackgrounded();
+ GetRenderFrameHost()->GetProcess()->IsProcessBackgrounded();
RecordStartToCommitMetrics(
common_params_->navigation_start, transition, ready_to_commit_time_,
@@ -6483,7 +6492,7 @@ void NavigationRequest::ReadyToCommitNavigation(bool is_error) {
// disconnection from the renderer NavigationClient; but browser-initiated
// navigations do not, so we must look explicitly. We should not proceed and
// claim "ReadyToCommitNavigation" to the delegate if the renderer is gone.
- if (!render_frame_host_->IsRenderFrameLive()) {
+ if (!GetRenderFrameHost()->IsRenderFrameLive()) {
OnRendererRequestedNavigationCancellation();
// DO NOT ADD CODE AFTER THIS, as the NavigationHandle has been deleted
// by the previous call.
@@ -6496,20 +6505,20 @@ void NavigationRequest::ReadyToCommitNavigation(bool is_error) {
// where the FrameTreeNode has no NavigationRequest, yet the
// RenderFrameHostImpl is not marked as loading yet, causing
// FrameTreeNode::IsLoading() to incorrectly return false.
- frame_tree_node_->TransferNavigationRequestOwnership(render_frame_host_);
+ frame_tree_node_->TransferNavigationRequestOwnership(GetRenderFrameHost());
// When a speculative RenderFrameHost reaches ReadyToCommitNavigation, the
// browser process has asked the renderer to commit the navigation and is
// waiting for confirmation of the commit. Update the LifecycleStateImpl to
// kPendingCommit as RenderFrameHost isn't considered speculative anymore and
// was chosen to commit as this navigation's final RenderFrameHost.
- if (render_frame_host_->lifecycle_state() ==
+ if (GetRenderFrameHost()->lifecycle_state() ==
RenderFrameHostImpl::LifecycleStateImpl::kSpeculative) {
// Only cross-RenderFrameHost navigations create speculative
// RenderFrameHosts whereas SameDocument, BackForwardCache and
// PrerenderedActivation navigations don't.
DCHECK(!IsSameDocument() && !IsPageActivation());
- render_frame_host_->SetLifecycleState(
+ GetRenderFrameHost()->SetLifecycleState(
RenderFrameHostImpl::LifecycleStateImpl::kPendingCommit);
}
@@ -6531,11 +6540,11 @@ void NavigationRequest::ReadyToCommitNavigation(bool is_error) {
// Record metrics for the time it takes to get to this state from the
// beginning of the navigation.
if (!IsSameDocument() && !is_error) {
- is_same_process_ = render_frame_host_->GetProcess()->GetID() ==
+ is_same_process_ = GetRenderFrameHost()->GetProcess()->GetID() ==
previous_render_frame_host->GetProcess()->GetID();
RecordReadyToCommitMetrics(
- previous_render_frame_host, render_frame_host_, *common_params_.get(),
+ previous_render_frame_host, GetRenderFrameHost(), *common_params_.get(),
ready_to_commit_time_, origin_agent_cluster_end_result_,
did_receive_early_hints_before_cross_origin_redirect_);
}
@@ -6544,7 +6553,7 @@ void NavigationRequest::ReadyToCommitNavigation(bool is_error) {
same_origin_ = (previous_render_frame_host->GetLastCommittedOrigin() ==
GetOriginToCommit());
- SetExpectedProcess(render_frame_host_->GetProcess());
+ SetExpectedProcess(GetRenderFrameHost()->GetProcess());
commit_params_->is_load_data_with_base_url = IsLoadDataWithBaseURL();
@@ -6568,7 +6577,7 @@ void NavigationRequest::ReadyToCommitNavigation(bool is_error) {
NavigationEntry* entry = GetNavigationEntry();
if (entry && entry->IsViewSourceMode()) {
// Put the renderer in view source mode.
- render_frame_host_->GetAssociatedLocalFrame()->EnableViewSourceMode();
+ GetRenderFrameHost()->GetAssociatedLocalFrame()->EnableViewSourceMode();
}
}
@@ -6892,7 +6901,7 @@ NavigationRequest::MakeDidCommitProvisionalLoadParamsForActivation() {
// Use the DidCommitProvisionalLoadParams last used to commit the frame being
// restored as a starting point.
mojom::DidCommitProvisionalLoadParamsPtr params =
- render_frame_host_->TakeLastCommitParams();
+ GetRenderFrameHost()->TakeLastCommitParams();
// Params must have been set when the RFH being restored from the cache last
// navigated.
@@ -7159,7 +7168,10 @@ RenderFrameHostImpl* NavigationRequest::GetRenderFrameHost() const {
}
static_assert(WILL_FAIL_REQUEST > WILL_PROCESS_RESPONSE,
"WillFailRequest state should come after WillProcessResponse");
- return render_frame_host_;
+ if (HasRenderFrameHost()) {
+ return &*render_frame_host_.value();
+ }
+ return nullptr;
}
const net::HttpRequestHeaders& NavigationRequest::GetRequestHeaders() {
@@ -7619,7 +7631,8 @@ bool NavigationRequest::CoopCoepSanityCheck() {
// TODO(https://crbug.com/1278207) add other embedded cases if needed.
network::mojom::CrossOriginOpenerPolicyValue coop_value =
GetParentFrameOrOuterDocument()
- ? render_frame_host_->GetOutermostMainFrame()
+ ? GetRenderFrameHost()
+ ->GetOutermostMainFrame()
->cross_origin_opener_policy()
.value
: policies.cross_origin_opener_policy.value;
@@ -8182,8 +8195,8 @@ void NavigationRequest::SendDeferredConsoleMessages() {
for (auto& message : console_messages_) {
// TODO(https://crbug.com/721329): We should have a way of sending console
// messaged to devtools without going through the renderer.
- render_frame_host_->AddMessageToConsole(message.level,
- std::move(message.message));
+ GetRenderFrameHost()->AddMessageToConsole(message.level,
+ std::move(message.message));
}
console_messages_.clear();
}
diff --git a/content/browser/renderer_host/navigation_request.h b/content/browser/renderer_host/navigation_request.h
index 8d6debbd09392d954d05c06c5e0b2d7a7be29bd3..6c715d5e85f2dc90dc17f9a237c69ede69c533e6 100644
--- a/content/browser/renderer_host/navigation_request.h
+++ b/content/browser/renderer_host/navigation_request.h
@@ -459,6 +459,8 @@ class CONTENT_EXPORT NavigationRequest
associated_rfh_type_ = type;
}
+ bool HasRenderFrameHost() const { return render_frame_host_.has_value(); }
+
void set_was_discarded() { commit_params_->was_discarded = true; }
void set_net_error(net::Error net_error) { net_error_ = net_error; }
@@ -1632,8 +1634,17 @@ class CONTENT_EXPORT NavigationRequest
// - the synchronous about:blank navigation.
const bool is_synchronous_renderer_commit_;
- // Invariant: At least one of |loader_| or |render_frame_host_| is null.
- raw_ptr<RenderFrameHostImpl> render_frame_host_ = nullptr;
+ // The RenderFrameHost that this navigation intends to commit in. The value
+ // will be set when we know the final RenderFrameHost that the navigation will
+ // commit in (i.e. when we receive the final network response for most
+ // navigations). Note that currently this can be reset to absl::nullopt for
+ // cross-document restarts and some failed navigations.
+ // TODO(https://crbug.com/1416916): Don't reset this on failed navigations,
+ // and ensure the NavigationRequest doesn't outlive the `render_frame_host_`
+ // picked for failed Back/Forward Cache restores.
+ // Invariant: At least one of |loader_| or |render_frame_host_| is
+ // null/absl::nullopt.
+ absl::optional<base::SafeRef<RenderFrameHostImpl>> render_frame_host_;
// Initialized on creation of the NavigationRequest. Sent to the renderer when
// the navigation is ready to commit.

View File

@@ -0,0 +1,89 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Peng Huang <penghuang@chromium.org>
Date: Mon, 13 Feb 2023 22:10:44 +0000
Subject: Fix UAF problem in AngleVulkanImageBacking
Right now, we use vulkan fence helper to release the backing.
It is right, if the last usage of the backing is by skia.
If the last usage is by gl, the fence helper(skia) isn't aware of
the submitted work from ANGLE, skia may call flush finish callback
to release the backing while the backing is still being referenced
by works in ANGLE. Fix the problem by calling glFinish() if the last
usage is GL.
Know issue: the finish callback of skia flush() is not always called
in order. So in edge cases, the UAF problem can still happen.
(cherry picked from commit d5143b14a00807b40eada4dfb0bce610ffc1477a)
Bug: 1309035
Change-Id: I3562043650dd2b27bde3a370bef45b1226cdd48c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4232858
Reviewed-by: Vasiliy Telezhnikov <vasilyt@chromium.org>
Commit-Queue: Peng Huang <penghuang@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1102905}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4245959
Cr-Commit-Position: refs/branch-heads/5481@{#1119}
Cr-Branched-From: 130f3e4d850f4bc7387cfb8d08aa993d288a67a9-refs/heads/main@{#1084008}
diff --git a/gpu/command_buffer/service/shared_image/angle_vulkan_image_backing.cc b/gpu/command_buffer/service/shared_image/angle_vulkan_image_backing.cc
index a2239f19b8d1002bbf511ba53a9eab6b39b84653..c8b53477a7e7dd5685be1b4aef725911e605825b 100644
--- a/gpu/command_buffer/service/shared_image/angle_vulkan_image_backing.cc
+++ b/gpu/command_buffer/service/shared_image/angle_vulkan_image_backing.cc
@@ -161,6 +161,11 @@ AngleVulkanImageBacking::~AngleVulkanImageBacking() {
passthrough_texture_.reset();
egl_image_.reset();
+
+ if (need_gl_finish_before_destroy_ && have_context()) {
+ gl::GLApi* api = gl::g_current_gl_context;
+ api->glFinishFn();
+ }
}
if (vulkan_image_) {
@@ -325,8 +330,9 @@ void AngleVulkanImageBacking::GLTextureImageRepresentationEndAccess(
--gl_reads_in_process_;
// For the last GL read access, release texture from ANGLE.
- if (gl_reads_in_process_ == 0)
+ if (gl_reads_in_process_ == 0) {
ReleaseTextureANGLE();
+ }
return;
}
@@ -356,6 +362,9 @@ void AngleVulkanImageBacking::ReleaseTextureANGLE() {
GLuint texture = passthrough_texture_->service_id();
// Release the texture from ANGLE, so it can be used elsewhere.
api->glReleaseTexturesANGLEFn(1, &texture, &layout_);
+ // Releasing the texture will submit all related works to queue, so to be
+ // safe, glFinish() should be called before releasing the VkImage.
+ need_gl_finish_before_destroy_ = true;
}
void AngleVulkanImageBacking::PrepareBackendTexture() {
@@ -435,6 +444,11 @@ void AngleVulkanImageBacking::EndAccessSkia() {
return;
}
+ // The backing is used by skia, so skia should submit related work to the
+ // queue, and we can use vulkan fence helper to release the VkImage.
+ // glFinish() is not necessary anymore.
+ need_gl_finish_before_destroy_ = false;
+
SyncImageLayoutFromBackendTexture();
if (gl_reads_in_process_ > 0) {
diff --git a/gpu/command_buffer/service/shared_image/angle_vulkan_image_backing.h b/gpu/command_buffer/service/shared_image/angle_vulkan_image_backing.h
index e773aed4b20db46d7a12a10961d88ff643f9c8ec..9306868802d81af87b8a3d6a0e5ea69d57ac6685 100644
--- a/gpu/command_buffer/service/shared_image/angle_vulkan_image_backing.h
+++ b/gpu/command_buffer/service/shared_image/angle_vulkan_image_backing.h
@@ -80,6 +80,7 @@ class AngleVulkanImageBacking : public ClearTrackingSharedImageBacking,
bool is_gl_write_in_process_ = false;
int skia_reads_in_process_ = 0;
int gl_reads_in_process_ = 0;
+ bool need_gl_finish_before_destroy_ = false;
};
} // namespace gpu

View File

@@ -0,0 +1,58 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Vasiliy Telezhnikov <vasilyt@chromium.org>
Date: Fri, 10 Feb 2023 17:36:57 +0000
Subject: CHECK that YUV readback finished synchronously
DoReadbackYUVImagePixelsINTERNAL is implemented using skia asynchronous
readback and to make it synchronous we use sync cpu and gpu. In some
edge cases on linux we saw that doesn't happen if readback triggered
vulkan device lost.
To avoid use after free, CHECK that callback was actually called. In
case of device-lost gpu process will restart anyway, so while this is
not proper fix of the problem, it doesn't result in worse user visible
behaviour.
(cherry picked from commit 081df1e7d3712131bcaa575bda2e37ec7f6aa83d)
Bug: 1399742
Change-Id: Ie2172539bb907b9696ef62c70d398aca3967177c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4143606
Reviewed-by: Peng Huang <penghuang@chromium.org>
Commit-Queue: Vasiliy Telezhnikov <vasilyt@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1093064}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4239960
Cr-Commit-Position: refs/branch-heads/5481@{#1084}
Cr-Branched-From: 130f3e4d850f4bc7387cfb8d08aa993d288a67a9-refs/heads/main@{#1084008}
diff --git a/gpu/command_buffer/service/raster_decoder.cc b/gpu/command_buffer/service/raster_decoder.cc
index d2ac0ac70902d68b95417d2a95da153a7fc38128..ef79b5cbcc83d5ed12a9627ce76692476ace10a0 100644
--- a/gpu/command_buffer/service/raster_decoder.cc
+++ b/gpu/command_buffer/service/raster_decoder.cc
@@ -2485,6 +2485,7 @@ void RasterDecoderImpl::DoReadbackARGBImagePixelsINTERNAL(
namespace {
struct YUVReadbackResult {
std::unique_ptr<const SkImage::AsyncReadResult> async_result;
+ bool finished = false;
};
void OnReadYUVImagePixelsDone(
@@ -2492,6 +2493,7 @@ void OnReadYUVImagePixelsDone(
std::unique_ptr<const SkImage::AsyncReadResult> async_result) {
YUVReadbackResult* context = reinterpret_cast<YUVReadbackResult*>(raw_ctx);
context->async_result = std::move(async_result);
+ context->finished = true;
}
} // namespace
@@ -2689,6 +2691,10 @@ void RasterDecoderImpl::DoReadbackYUVImagePixelsINTERNAL(
// asynchronous by removing this flush and implementing a query that can
// signal back to client process.
gr_context()->flushAndSubmit(true);
+
+ // The call above will sync up gpu and CPU, resulting in callback being run
+ // during flushAndSubmit. To prevent UAF make sure it indeed happened.
+ CHECK(yuv_result.finished);
if (!yuv_result.async_result) {
LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glReadbackYUVImagePixels",
"Failed to read pixels from SkImage");

View File

@@ -0,0 +1,55 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Cheng Zhao <zcbenz@gmail.com>
Date: Wed, 15 Feb 2023 11:30:56 +0900
Subject: fix: restoring a X11 window should not remove its previous maximized
state
On Linux after minimizing a maximized window, it will have both the
"maximized" and "hidden" states, and restoring the window should only remove
the "hidden" state, which makes it back a maximized window.
However in the implementation of `X11Window::Restore`, both "maximized" and
"hidden" states are removed, and a maximized window that was minimized will
be resized to its normal size after calling Restore, while the correct
behavior should be going back to the maximized state.
Backported from:
https://chromium-review.googlesource.com/c/chromium/src/+/4252946
diff --git a/ui/ozone/platform/x11/x11_window.cc b/ui/ozone/platform/x11/x11_window.cc
index 45e0a75a643c2d7a70af37cbf38dcbde52fdd0cf..b229800eafabb0c810430d615cc165ff1e356491 100644
--- a/ui/ozone/platform/x11/x11_window.cc
+++ b/ui/ozone/platform/x11/x11_window.cc
@@ -729,11 +729,16 @@ void X11Window::Minimize() {
}
void X11Window::Restore() {
- should_maximize_after_map_ = false;
- restore_in_flight_ = true;
- SetWMSpecState(false, x11::GetAtom("_NET_WM_STATE_MAXIMIZED_VERT"),
- x11::GetAtom("_NET_WM_STATE_MAXIMIZED_HORZ"));
- SetWMSpecState(false, x11::GetAtom("_NET_WM_STATE_HIDDEN"), x11::Atom::None);
+ if (IsMinimized()) {
+ restore_in_flight_ = true;
+ SetWMSpecState(false, x11::GetAtom("_NET_WM_STATE_HIDDEN"),
+ x11::Atom::None);
+ } else if (IsMaximized()) {
+ restore_in_flight_ = true;
+ should_maximize_after_map_ = false;
+ SetWMSpecState(false, x11::GetAtom("_NET_WM_STATE_MAXIMIZED_VERT"),
+ x11::GetAtom("_NET_WM_STATE_MAXIMIZED_HORZ"));
+ }
}
PlatformWindowState X11Window::GetPlatformWindowState() const {
@@ -1884,6 +1889,10 @@ bool X11Window::IsMinimized() const {
}
bool X11Window::IsMaximized() const {
+ // In X11, if a maximized window is minimized, it will have both the "hidden"
+ // and "maximized" states.
+ if (IsMinimized())
+ return false;
return (HasWMSpecProperty(window_properties_,
x11::GetAtom("_NET_WM_STATE_MAXIMIZED_VERT")) &&
HasWMSpecProperty(window_properties_,

View File

@@ -0,0 +1,381 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Dale Curtis <dalecurtis@chromium.org>
Date: Mon, 20 Feb 2023 13:16:32 +0000
Subject: Further simplify WebMediaPlayerMSCompositor lifetime.
M108 merge issues:
third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc:
- video_task_runner_ is named io_task_runner_ in 108
third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.cc:
- video_task_runner_ is named io_task_runner_ in 108 (conflict in ReplaceCurrentFrameWithACopy)
Due to the raw pointer held by VideoFrameSubmitter, there may be
tasks pending on the compositor task runner after the RefCounted
traits have "destructed" WebMediaPlayerMSCompositor. Through this
raw pointer VFS was invoking OnContextLost which attempts to use
the zero ref count compositor.
The solution here is again similar to VideoFrameCompositor, its
destruction should be explicit instead of a tangle of RefCounted
owners.
(cherry picked from commit 1622bffc6534a0cc4f53d07c43e0cd8f49975d10)
Fixed: 1407701, 1411601
Change-Id: Ic77294d1113d54ab83bc0f5b625a997edf57bf7c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4210508
Commit-Queue: Tony Herre <toprice@chromium.org>
Auto-Submit: Dale Curtis <dalecurtis@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1099726}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4225393
Commit-Queue: Roger Felipe Zanoni da Silva <rzanoni@google.com>
Reviewed-by: Oleh Lamzin <lamzin@google.com>
Owners-Override: Oleh Lamzin <lamzin@google.com>
Cr-Commit-Position: refs/branch-heads/5359@{#1392}
Cr-Branched-From: 27d3765d341b09369006d030f83f582a29eb57ae-refs/heads/main@{#1058933}
diff --git a/third_party/blink/public/web/modules/mediastream/webmediaplayer_ms.h b/third_party/blink/public/web/modules/mediastream/webmediaplayer_ms.h
index f8c640d4f866afafa6fab82d67fe5f866810f828..955f867cc24152fa88dd6c20de006425a20b77c5 100644
--- a/third_party/blink/public/web/modules/mediastream/webmediaplayer_ms.h
+++ b/third_party/blink/public/web/modules/mediastream/webmediaplayer_ms.h
@@ -211,6 +211,8 @@ class BLINK_MODULES_EXPORT WebMediaPlayerMS
static const gfx::Size kUseGpuMemoryBufferVideoFramesMinResolution;
#endif // BUILDFLAG(IS_WIN)
+ void ReplaceCurrentFrameWithACopy();
+
bool IsInPictureInPicture() const;
// Switch to SurfaceLayer, either initially or from VideoLayer.
@@ -313,7 +315,7 @@ class BLINK_MODULES_EXPORT WebMediaPlayerMS
// Used for DCHECKs to ensure methods calls executed in the correct thread.
THREAD_CHECKER(thread_checker_);
- scoped_refptr<WebMediaPlayerMSCompositor> compositor_;
+ std::unique_ptr<WebMediaPlayerMSCompositor> compositor_;
const WebString initial_audio_output_device_id_;
diff --git a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc
index e4eb2b0053384d3e89545928c22bc2e1a12580fa..a85406d39037a8003eaffd1a91c8021ad38e0267 100644
--- a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc
+++ b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc
@@ -399,8 +399,9 @@ WebMediaPlayerMS::~WebMediaPlayerMS() {
SendLogMessage(
String::Format("%s() [delegate_id=%d]", __func__, delegate_id_));
- if (!web_stream_.IsNull())
+ if (!web_stream_.IsNull()) {
web_stream_.RemoveObserver(this);
+ }
// Destruct compositor resources in the proper order.
get_client()->SetCcLayer(nullptr);
@@ -409,14 +410,35 @@ WebMediaPlayerMS::~WebMediaPlayerMS() {
video_layer_->StopUsingProvider();
}
- if (frame_deliverer_)
- io_task_runner_->DeleteSoon(FROM_HERE, frame_deliverer_.release());
+ if (frame_deliverer_) {
+ io_task_runner_->DeleteSoon(FROM_HERE, std::move(frame_deliverer_));
+ }
- if (video_frame_provider_)
+ if (video_frame_provider_) {
video_frame_provider_->Stop();
+ }
- if (audio_renderer_)
+ // This must be destroyed before `compositor_` since it will grab a couple of
+ // final metrics during destruction.
+ watch_time_reporter_.reset();
+
+ if (compositor_) {
+ // `compositor_` receives frames on `io_task_runner_` from
+ // `frame_deliverer_` and operates on the `compositor_task_runner_`, so
+ // must trampoline through both to ensure a safe destruction.
+ PostCrossThreadTask(
+ *io_task_runner_, FROM_HERE,
+ WTF::CrossThreadBindOnce(
+ [](scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+ std::unique_ptr<WebMediaPlayerMSCompositor> compositor) {
+ task_runner->DeleteSoon(FROM_HERE, std::move(compositor));
+ },
+ compositor_task_runner_, std::move(compositor_)));
+ }
+
+ if (audio_renderer_) {
audio_renderer_->Stop();
+ }
media_log_->AddEvent<media::MediaLogEvent::kWebMediaPlayerDestroyed>();
@@ -457,7 +479,7 @@ WebMediaPlayer::LoadTiming WebMediaPlayerMS::Load(
watch_time_reporter_.reset();
- compositor_ = base::MakeRefCounted<WebMediaPlayerMSCompositor>(
+ compositor_ = std::make_unique<WebMediaPlayerMSCompositor>(
compositor_task_runner_, io_task_runner_, web_stream_,
std::move(submitter_), use_surface_layer_, weak_this_);
@@ -480,7 +502,7 @@ WebMediaPlayer::LoadTiming WebMediaPlayerMS::Load(
frame_deliverer_ = std::make_unique<WebMediaPlayerMS::FrameDeliverer>(
weak_this_,
CrossThreadBindRepeating(&WebMediaPlayerMSCompositor::EnqueueFrame,
- compositor_),
+ CrossThreadUnretained(compositor_.get())),
media_task_runner_, worker_task_runner_, gpu_factories_);
video_frame_provider_ = renderer_factory_->GetVideoRenderer(
web_stream_,
@@ -826,7 +848,19 @@ void WebMediaPlayerMS::Pause() {
video_frame_provider_->Pause();
compositor_->StopRendering();
- compositor_->ReplaceCurrentFrameWithACopy();
+
+ // Bounce this call off of video task runner to since there might still be
+ // frames passed on video task runner.
+ PostCrossThreadTask(
+ *io_task_runner_, FROM_HERE,
+ WTF::CrossThreadBindOnce(
+ [](scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+ WTF::CrossThreadOnceClosure copy_cb) {
+ PostCrossThreadTask(*task_runner, FROM_HERE, std::move(copy_cb));
+ },
+ main_render_task_runner_,
+ WTF::CrossThreadBindOnce(
+ &WebMediaPlayerMS::ReplaceCurrentFrameWithACopy, weak_this_)));
if (audio_renderer_)
audio_renderer_->Pause();
@@ -841,6 +875,11 @@ void WebMediaPlayerMS::Pause() {
paused_ = true;
}
+void WebMediaPlayerMS::ReplaceCurrentFrameWithACopy() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ compositor_->ReplaceCurrentFrameWithACopy();
+}
+
void WebMediaPlayerMS::Seek(double seconds) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
}
@@ -1192,7 +1231,8 @@ void WebMediaPlayerMS::ActivateSurfaceLayerForVideo(
PostCrossThreadTask(
*compositor_task_runner_, FROM_HERE,
CrossThreadBindOnce(&WebMediaPlayerMSCompositor::EnableSubmission,
- compositor_, bridge_->GetSurfaceId(), video_transform,
+ CrossThreadUnretained(compositor_.get()),
+ bridge_->GetSurfaceId(), video_transform,
IsInPictureInPicture()));
// If the element is already in Picture-in-Picture mode, it means that it
diff --git a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.cc b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.cc
index acbdf1c64f0efed4c665de270d712bf446eb2106..67f0c200d85073ecd677e467bc1d624b1817dde0 100644
--- a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.cc
+++ b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.cc
@@ -197,18 +197,18 @@ WebMediaPlayerMSCompositor::WebMediaPlayerMSCompositor(
dropped_frame_count_(0),
stopped_(true),
render_started_(!stopped_) {
+ weak_this_ = weak_ptr_factory_.GetWeakPtr();
if (use_surface_layer) {
submitter_ = std::move(submitter);
PostCrossThreadTask(
*video_frame_compositor_task_runner_, FROM_HERE,
CrossThreadBindOnce(&WebMediaPlayerMSCompositor::InitializeSubmitter,
- weak_ptr_factory_.GetWeakPtr()));
+ weak_this_));
update_submission_state_callback_ = base::BindPostTask(
video_frame_compositor_task_runner_,
ConvertToBaseRepeatingCallback(CrossThreadBindRepeating(
- &WebMediaPlayerMSCompositor::SetIsSurfaceVisible,
- weak_ptr_factory_.GetWeakPtr())));
+ &WebMediaPlayerMSCompositor::SetIsSurfaceVisible, weak_this_)));
}
HeapVector<Member<MediaStreamComponent>> video_components;
@@ -236,27 +236,12 @@ WebMediaPlayerMSCompositor::WebMediaPlayerMSCompositor(
}
WebMediaPlayerMSCompositor::~WebMediaPlayerMSCompositor() {
- // Ensured by destructor traits.
DCHECK(video_frame_compositor_task_runner_->BelongsToCurrentThread());
if (video_frame_provider_client_) {
video_frame_provider_client_->StopUsingProvider();
}
}
-// static
-void WebMediaPlayerMSCompositorTraits::Destruct(
- const WebMediaPlayerMSCompositor* compositor) {
- if (!compositor->video_frame_compositor_task_runner_
- ->BelongsToCurrentThread()) {
- PostCrossThreadTask(
- *compositor->video_frame_compositor_task_runner_, FROM_HERE,
- CrossThreadBindOnce(&WebMediaPlayerMSCompositorTraits::Destruct,
- CrossThreadUnretained(compositor)));
- return;
- }
- delete compositor;
-}
-
void WebMediaPlayerMSCompositor::InitializeSubmitter() {
DCHECK(video_frame_compositor_task_runner_->BelongsToCurrentThread());
submitter_->Initialize(this, /*is_media_stream=*/true);
@@ -302,7 +287,7 @@ void WebMediaPlayerMSCompositor::SetForceBeginFrames(bool enable) {
PostCrossThreadTask(
*video_frame_compositor_task_runner_, FROM_HERE,
CrossThreadBindOnce(&WebMediaPlayerMSCompositor::SetForceBeginFrames,
- weak_ptr_factory_.GetWeakPtr(), enable));
+ weak_this_, enable));
return;
}
@@ -604,7 +589,7 @@ void WebMediaPlayerMSCompositor::StartRendering() {
PostCrossThreadTask(
*video_frame_compositor_task_runner_, FROM_HERE,
CrossThreadBindOnce(&WebMediaPlayerMSCompositor::StartRenderingInternal,
- WrapRefCounted(this)));
+ weak_this_));
}
void WebMediaPlayerMSCompositor::StopRendering() {
@@ -612,18 +597,7 @@ void WebMediaPlayerMSCompositor::StopRendering() {
PostCrossThreadTask(
*video_frame_compositor_task_runner_, FROM_HERE,
CrossThreadBindOnce(&WebMediaPlayerMSCompositor::StopRenderingInternal,
- WrapRefCounted(this)));
-}
-
-void WebMediaPlayerMSCompositor::ReplaceCurrentFrameWithACopy() {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- // Bounce this call off of IO thread to since there might still be frames
- // passed on IO thread.
- io_task_runner_->PostTask(
- FROM_HERE,
- media::BindToCurrentLoop(WTF::BindOnce(
- &WebMediaPlayerMSCompositor::ReplaceCurrentFrameWithACopyInternal,
- WrapRefCounted(this))));
+ weak_this_));
}
bool WebMediaPlayerMSCompositor::MapTimestampsToRenderTimeTicks(
@@ -690,7 +664,7 @@ void WebMediaPlayerMSCompositor::RenderWithoutAlgorithm(
*video_frame_compositor_task_runner_, FROM_HERE,
CrossThreadBindOnce(
&WebMediaPlayerMSCompositor::RenderWithoutAlgorithmOnCompositor,
- WrapRefCounted(this), std::move(frame), is_copy));
+ weak_this_, std::move(frame), is_copy));
}
void WebMediaPlayerMSCompositor::RenderWithoutAlgorithmOnCompositor(
@@ -790,9 +764,8 @@ void WebMediaPlayerMSCompositor::SetCurrentFrame(
PostCrossThreadTask(
*video_frame_compositor_task_runner_, FROM_HERE,
CrossThreadBindOnce(&WebMediaPlayerMSCompositor::CheckForFrameChanges,
- WrapRefCounted(this), is_first_frame,
- has_frame_size_changed, std::move(new_transform),
- std::move(new_opacity)));
+ weak_this_, is_first_frame, has_frame_size_changed,
+ std::move(new_transform), std::move(new_opacity)));
}
void WebMediaPlayerMSCompositor::CheckForFrameChanges(
@@ -859,7 +832,7 @@ void WebMediaPlayerMSCompositor::StopRenderingInternal() {
video_frame_provider_client_->StopRendering();
}
-void WebMediaPlayerMSCompositor::ReplaceCurrentFrameWithACopyInternal() {
+void WebMediaPlayerMSCompositor::ReplaceCurrentFrameWithACopy() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
scoped_refptr<media::VideoFrame> current_frame_ref;
{
diff --git a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.h b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.h
index ffeb448be295223f1f997b47eddff37d04bc8f16..197a0f0d02e84378f7f697213aa613e73c9f79f7 100644
--- a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.h
+++ b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.h
@@ -24,7 +24,6 @@
#include "third_party/blink/renderer/modules/mediastream/video_renderer_algorithm_wrapper.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
-#include "third_party/blink/renderer/platform/wtf/thread_safe_ref_counted.h"
namespace base {
class SingleThreadTaskRunner;
@@ -46,7 +45,6 @@ class SurfaceId;
namespace blink {
class MediaStreamDescriptor;
class WebMediaPlayerMS;
-struct WebMediaPlayerMSCompositorTraits;
// This class is designed to handle the work load on compositor thread for
// WebMediaPlayerMS. It will be instantiated on the main thread, but destroyed
@@ -58,9 +56,7 @@ struct WebMediaPlayerMSCompositorTraits;
// Otherwise, WebMediaPlayerMSCompositor will simply store the most recent
// frame, and submit it whenever asked by the compositor.
class MODULES_EXPORT WebMediaPlayerMSCompositor
- : public cc::VideoFrameProvider,
- public WTF::ThreadSafeRefCounted<WebMediaPlayerMSCompositor,
- WebMediaPlayerMSCompositorTraits> {
+ : public cc::VideoFrameProvider {
public:
using OnNewFramePresentedCB = base::OnceClosure;
@@ -76,6 +72,7 @@ class MODULES_EXPORT WebMediaPlayerMSCompositor
std::unique_ptr<WebVideoFrameSubmitter> submitter,
bool use_surface_layer,
const base::WeakPtr<WebMediaPlayerMS>& player);
+ ~WebMediaPlayerMSCompositor() override;
WebMediaPlayerMSCompositor(const WebMediaPlayerMSCompositor&) = delete;
WebMediaPlayerMSCompositor& operator=(const WebMediaPlayerMSCompositor&) =
@@ -143,10 +140,7 @@ class MODULES_EXPORT WebMediaPlayerMSCompositor
Metadata GetMetadata();
private:
- friend class WTF::ThreadSafeRefCounted<WebMediaPlayerMSCompositor,
- WebMediaPlayerMSCompositorTraits>;
friend class WebMediaPlayerMSTest;
- friend struct WebMediaPlayerMSCompositorTraits;
// Struct used to keep information about frames pending in
// |rendering_frame_buffer_|.
@@ -157,8 +151,6 @@ class MODULES_EXPORT WebMediaPlayerMSCompositor
bool is_copy;
};
- ~WebMediaPlayerMSCompositor() override;
-
// Ran on the |video_frame_compositor_task_runner_| to initialize
// |submitter_|
void InitializeSubmitter();
@@ -204,7 +196,6 @@ class MODULES_EXPORT WebMediaPlayerMSCompositor
void StartRenderingInternal();
void StopRenderingInternal();
- void ReplaceCurrentFrameWithACopyInternal();
void SetAlgorithmEnabledForTesting(bool algorithm_enabled);
void RecordFrameDisplayedStats(base::TimeTicks frame_displayed_time);
@@ -314,15 +305,10 @@ class MODULES_EXPORT WebMediaPlayerMSCompositor
// |dropped_frame_count_|, |current_metadata_| and |render_started_|.
base::Lock current_frame_lock_;
+ base::WeakPtr<WebMediaPlayerMSCompositor> weak_this_;
base::WeakPtrFactory<WebMediaPlayerMSCompositor> weak_ptr_factory_{this};
};
-struct WebMediaPlayerMSCompositorTraits {
- // Ensure destruction occurs on main thread so that "Web" and other resources
- // are destroyed on the correct thread.
- static void Destruct(const WebMediaPlayerMSCompositor* player);
-};
-
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASTREAM_WEBMEDIAPLAYER_MS_COMPOSITOR_H_

View File

@@ -0,0 +1,124 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Dale Curtis <dalecurtis@chromium.org>
Date: Mon, 20 Feb 2023 10:08:49 +0000
Subject: Simplify WebMediaPlayerMSCompositor destruction.
The code was only sometimes calling StopUsingProvider() and posted
the submitter destruction unnecessarily.
Destruction now works the same as in VideoFrameCompositor, where the
class itself is responsible for calling StopUsingProvider() during
its own destruction.
(cherry picked from commit cbd238e85903b7d94910bd2c6362ff9abf9908cc)
Fixed: 1407701
Disallow-Recycled-Builds: test-failures
Change-Id: Ia649cb5532519468eea34e12745ed9c990580d82
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4195824
Auto-Submit: Dale Curtis <dalecurtis@chromium.org>
Commit-Queue: Tony Herre <toprice@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1098505}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4225498
Reviewed-by: Oleh Lamzin <lamzin@google.com>
Owners-Override: Oleh Lamzin <lamzin@google.com>
Commit-Queue: Roger Felipe Zanoni da Silva <rzanoni@google.com>
Cr-Commit-Position: refs/branch-heads/5359@{#1391}
Cr-Branched-From: 27d3765d341b09369006d030f83f582a29eb57ae-refs/heads/main@{#1058933}
diff --git a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc
index 01b3e059e339341995deb9c27e248ab272acd1b2..e4eb2b0053384d3e89545928c22bc2e1a12580fa 100644
--- a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc
+++ b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc
@@ -412,9 +412,6 @@ WebMediaPlayerMS::~WebMediaPlayerMS() {
if (frame_deliverer_)
io_task_runner_->DeleteSoon(FROM_HERE, frame_deliverer_.release());
- if (compositor_)
- compositor_->StopUsingProvider();
-
if (video_frame_provider_)
video_frame_provider_->Stop();
diff --git a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.cc b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.cc
index 63957929facc933c23eef3fc200f140b73cb3f50..acbdf1c64f0efed4c665de270d712bf446eb2106 100644
--- a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.cc
+++ b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.cc
@@ -238,13 +238,8 @@ WebMediaPlayerMSCompositor::WebMediaPlayerMSCompositor(
WebMediaPlayerMSCompositor::~WebMediaPlayerMSCompositor() {
// Ensured by destructor traits.
DCHECK(video_frame_compositor_task_runner_->BelongsToCurrentThread());
-
- if (submitter_) {
- video_frame_compositor_task_runner_->DeleteSoon(FROM_HERE,
- std::move(submitter_));
- } else {
- DCHECK(!video_frame_provider_client_)
- << "Must call StopUsingProvider() before dtor!";
+ if (video_frame_provider_client_) {
+ video_frame_provider_client_->StopUsingProvider();
}
}
@@ -264,7 +259,7 @@ void WebMediaPlayerMSCompositorTraits::Destruct(
void WebMediaPlayerMSCompositor::InitializeSubmitter() {
DCHECK(video_frame_compositor_task_runner_->BelongsToCurrentThread());
- submitter_->Initialize(this, /* is_media_stream = */ true);
+ submitter_->Initialize(this, /*is_media_stream=*/true);
}
void WebMediaPlayerMSCompositor::SetIsSurfaceVisible(
@@ -631,15 +626,6 @@ void WebMediaPlayerMSCompositor::ReplaceCurrentFrameWithACopy() {
WrapRefCounted(this))));
}
-void WebMediaPlayerMSCompositor::StopUsingProvider() {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- PostCrossThreadTask(
- *video_frame_compositor_task_runner_, FROM_HERE,
- CrossThreadBindOnce(
- &WebMediaPlayerMSCompositor::StopUsingProviderInternal,
- WrapRefCounted(this)));
-}
-
bool WebMediaPlayerMSCompositor::MapTimestampsToRenderTimeTicks(
const std::vector<base::TimeDelta>& timestamps,
std::vector<base::TimeTicks>* wall_clock_times) {
@@ -873,13 +859,6 @@ void WebMediaPlayerMSCompositor::StopRenderingInternal() {
video_frame_provider_client_->StopRendering();
}
-void WebMediaPlayerMSCompositor::StopUsingProviderInternal() {
- DCHECK(video_frame_compositor_task_runner_->BelongsToCurrentThread());
- if (video_frame_provider_client_)
- video_frame_provider_client_->StopUsingProvider();
- video_frame_provider_client_ = nullptr;
-}
-
void WebMediaPlayerMSCompositor::ReplaceCurrentFrameWithACopyInternal() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
scoped_refptr<media::VideoFrame> current_frame_ref;
diff --git a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.h b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.h
index a82497399be7588298f4c740ef67e18ee429967d..ffeb448be295223f1f997b47eddff37d04bc8f16 100644
--- a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.h
+++ b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.h
@@ -119,10 +119,6 @@ class MODULES_EXPORT WebMediaPlayerMSCompositor
void StopRendering();
void ReplaceCurrentFrameWithACopy();
- // Tell |video_frame_provider_client_| to stop using this instance in
- // preparation for dtor.
- void StopUsingProvider();
-
// Sets a hook to be notified when a new frame is presented, to fulfill a
// prending video.requestAnimationFrame() request.
// Can be called from any thread.
@@ -208,7 +204,6 @@ class MODULES_EXPORT WebMediaPlayerMSCompositor
void StartRenderingInternal();
void StopRenderingInternal();
- void StopUsingProviderInternal();
void ReplaceCurrentFrameWithACopyInternal();
void SetAlgorithmEnabledForTesting(bool algorithm_enabled);

View File

@@ -796,10 +796,10 @@ index 51a5497b809cda82b223138f43507172a9f066ae..71227492fd87e577518f3bf55ded37b0
#if BUILDFLAG(ENABLE_PRINT_PREVIEW)
// Set options for print preset from source PDF document.
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
index 18328bedfdd0dc735126f7541ee7ed3e736d94b0..e5e28db9a970b49ac5624c59cbaeed9aff5e52d8 100644
index a73daeeb4b6397db6fff9a9b552007204a376fb5..61454cd1b6e1c3c1d1ee1b901c499d9c802aec81 100644
--- a/content/browser/BUILD.gn
+++ b/content/browser/BUILD.gn
@@ -2821,8 +2821,9 @@ source_set("browser") {
@@ -2823,8 +2823,9 @@ source_set("browser") {
"//ppapi/shared_impl",
]

View File

@@ -9,3 +9,6 @@ fix_disable_implies_dcheck_for_node_stream_array_buffers.patch
revert_runtime_dhceck_terminating_exception_in_microtasks.patch
chore_disable_is_execution_terminating_dcheck.patch
force_cppheapcreateparams_to_be_noncopyable.patch
cherry-pick-e17eee4894be.patch
cherry-pick-546e00df97ac.patch
cherry-pick-f6ddbf42b1ea.patch

View File

@@ -0,0 +1,75 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Joyee Cheung <joyee@igalia.com>
Date: Tue, 14 Feb 2023 00:58:04 +0100
Subject: Merged: [ic] store slow stubs for objects with access checks in
DefineNamedIC
The CheckIfCanDefine() used to check the attributes of the object
as well as reporting to access check failure callbacks can update
the lookup iterator, resulting in wrong store handlers being
installed. Restart the lookup iterator in this case to make
sure that slow handlers are installed.
Bug: chromium:1415249
(cherry picked from commit da2df213bc70437ef76f47e0ab6995fa45f8014a)
Change-Id: I92d60af7ea798d80b1115e63b7fce8e2e8026ed9
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4290868
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/branch-heads/11.0@{#33}
Cr-Branched-From: 06097c6f0c5af54fd5d6965d37027efb72decd4f-refs/heads/11.0.226@{#1}
Cr-Branched-From: 6bf3344f5d9940de1ab253f1817dcb99c641c9d3-refs/heads/main@{#84857}
diff --git a/src/ic/ic.cc b/src/ic/ic.cc
index ae1dde1a8c587dfc80a0a62e96b7bbfe6ba5eea5..fff21e90bad3451e2d942ec327cb02f394fecc46 100644
--- a/src/ic/ic.cc
+++ b/src/ic/ic.cc
@@ -1818,6 +1818,11 @@ MaybeHandle<Object> StoreIC::Store(Handle<Object> object, Handle<Name> name,
if (!can_define.FromJust()) {
return isolate()->factory()->undefined_value();
}
+ // Restart the lookup iterator updated by CheckIfCanDefine() for
+ // UpdateCaches() to handle access checks.
+ if (use_ic && object->IsAccessCheckNeeded()) {
+ it.Restart();
+ }
}
if (use_ic) {
diff --git a/test/mjsunit/regress/regress-crbug-1415249.js b/test/mjsunit/regress/regress-crbug-1415249.js
new file mode 100644
index 0000000000000000000000000000000000000000..5715e0107a4b6e9dded9ca92c7b766c4cce0af72
--- /dev/null
+++ b/test/mjsunit/regress/regress-crbug-1415249.js
@@ -0,0 +1,30 @@
+// Copyright 2023 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --always-turbofan
+{
+ const realm = Realm.createAllowCrossRealmAccess();
+ const global = Realm.global(realm);
+ function Base() { return global; }
+ let i = 0;
+ class Klass extends Base {
+ field = i++;
+ }
+ let a = new Klass();
+ assertEquals(a.field, 0);
+ a = new Klass();
+ assertEquals(a.field, 1);
+}
+
+{
+ const realm = Realm.create();
+ const global = Realm.global(realm);
+ function Base() { return global; }
+ let i = 0;
+ class Klass extends Base {
+ field = i++;
+ }
+ assertThrows(() => new Klass(), Error, /no access/);
+ assertThrows(() => new Klass(), Error, /no access/);
+}

View File

@@ -0,0 +1,171 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Clemens Backes <clemensb@chromium.org>
Date: Thu, 22 Dec 2022 09:43:42 +0100
Subject: Fix printing of wasm-to-js frames
After https://crrev.com/c/3859787 those frames would be printed like
standard Wasm frames, but in the place of the WasmInstanceObject, they
have a WasmApiFunctionRef object instead.
So special-case the {WasmToJsFrame::instance()} to load the instance
properly. Also special-case the {position()} accessor for imported
functions.
R=victorgomes@chromium.org
Bug: chromium:1402270
Change-Id: I39805805a50e7a73d7d8075c63c46bdf5a373a33
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4116778
Reviewed-by: Nico Hartmann <nicohartmann@chromium.org>
Commit-Queue: Clemens Backes <clemensb@chromium.org>
Reviewed-by: Victor Gomes <victorgomes@chromium.org>
Cr-Commit-Position: refs/heads/main@{#84993}
diff --git a/src/compiler/backend/arm/code-generator-arm.cc b/src/compiler/backend/arm/code-generator-arm.cc
index 4c5accd7a8f352a128499861d5d28a6d9b859f1a..d8a77d70bbd465035ee91dbc57058f83ccf7cf83 100644
--- a/src/compiler/backend/arm/code-generator-arm.cc
+++ b/src/compiler/backend/arm/code-generator-arm.cc
@@ -3699,6 +3699,10 @@ void CodeGenerator::AssembleConstructFrame() {
if (call_descriptor->IsWasmFunctionCall() ||
call_descriptor->IsWasmImportWrapper() ||
call_descriptor->IsWasmCapiFunction()) {
+ // For import wrappers and C-API functions, this stack slot is only used
+ // for printing stack traces in V8. Also, it holds a WasmApiFunctionRef
+ // instead of the instance itself, which is taken care of in the frames
+ // accessors.
__ Push(kWasmInstanceRegister);
}
if (call_descriptor->IsWasmCapiFunction()) {
diff --git a/src/compiler/backend/arm64/code-generator-arm64.cc b/src/compiler/backend/arm64/code-generator-arm64.cc
index 60d19c79307529f13f64a1f5c41295d720f31dde..8ad2c88c12763106d7d279372d7f36933755f1e0 100644
--- a/src/compiler/backend/arm64/code-generator-arm64.cc
+++ b/src/compiler/backend/arm64/code-generator-arm64.cc
@@ -3225,6 +3225,9 @@ void CodeGenerator::AssembleConstructFrame() {
Register scratch = temps.AcquireX();
__ Mov(scratch,
StackFrame::TypeToMarker(info()->GetOutputStackFrameType()));
+ // This stack slot is only used for printing stack traces in V8. Also,
+ // it holds a WasmApiFunctionRef instead of the instance itself, which
+ // is taken care of in the frames accessors.
__ Push(scratch, kWasmInstanceRegister);
int extra_slots =
call_descriptor->kind() == CallDescriptor::kCallWasmImportWrapper
diff --git a/src/compiler/backend/ia32/code-generator-ia32.cc b/src/compiler/backend/ia32/code-generator-ia32.cc
index 5afd119ff506ddd07f719d539ad6e9592f967201..d13310cfcc244ea2c61766a9960dbab29779bf52 100644
--- a/src/compiler/backend/ia32/code-generator-ia32.cc
+++ b/src/compiler/backend/ia32/code-generator-ia32.cc
@@ -4026,6 +4026,10 @@ void CodeGenerator::AssembleConstructFrame() {
if (call_descriptor->IsWasmFunctionCall() ||
call_descriptor->IsWasmImportWrapper() ||
call_descriptor->IsWasmCapiFunction()) {
+ // For import wrappers and C-API functions, this stack slot is only used
+ // for printing stack traces in V8. Also, it holds a WasmApiFunctionRef
+ // instead of the instance itself, which is taken care of in the frames
+ // accessors.
__ push(kWasmInstanceRegister);
}
if (call_descriptor->IsWasmCapiFunction()) {
diff --git a/src/compiler/backend/x64/code-generator-x64.cc b/src/compiler/backend/x64/code-generator-x64.cc
index e3f759f570050c183d133854f83d02d9b442d8f9..0e02c63ace62caf2fcb5642db82d0c07af2cc2ba 100644
--- a/src/compiler/backend/x64/code-generator-x64.cc
+++ b/src/compiler/backend/x64/code-generator-x64.cc
@@ -4841,10 +4841,10 @@ void CodeGenerator::AssembleConstructFrame() {
if (call_descriptor->IsWasmFunctionCall() ||
call_descriptor->IsWasmImportWrapper() ||
call_descriptor->IsWasmCapiFunction()) {
- // We do not use this stack value in import wrappers and capi functions.
- // We push it anyway to satisfy legacy assumptions about these frames'
- // size and order.
- // TODO(manoskouk): Consider fixing this.
+ // For import wrappers and C-API functions, this stack slot is only used
+ // for printing stack traces in V8. Also, it holds a WasmApiFunctionRef
+ // instead of the instance itself, which is taken care of in the frames
+ // accessors.
__ pushq(kWasmInstanceRegister);
}
if (call_descriptor->IsWasmCapiFunction()) {
diff --git a/src/diagnostics/objects-printer.cc b/src/diagnostics/objects-printer.cc
index ce4d15b2c27e145be7e8dd2b98f1519ed11ce2f6..71604afa7a067e14a891057de4011416f45f4f19 100644
--- a/src/diagnostics/objects-printer.cc
+++ b/src/diagnostics/objects-printer.cc
@@ -2137,6 +2137,7 @@ void WasmApiFunctionRef::WasmApiFunctionRefPrint(std::ostream& os) {
os << "\n - isolate_root: " << reinterpret_cast<void*>(isolate_root());
os << "\n - native_context: " << Brief(native_context());
os << "\n - callable: " << Brief(callable());
+ os << "\n - instance: " << Brief(instance());
os << "\n - suspend: " << suspend();
os << "\n";
}
diff --git a/src/execution/frames.cc b/src/execution/frames.cc
index 0ca10a21e190f5113e0a84687ae6fa1d2882d3ee..c18ce06a87f94431c503997913e9c1993e6be804 100644
--- a/src/execution/frames.cc
+++ b/src/execution/frames.cc
@@ -2500,7 +2500,7 @@ void WasmFrame::Print(StringStream* accumulator, PrintMode mode,
return;
}
wasm::WasmCodeRefScope code_ref_scope;
- accumulator->Add("Wasm [");
+ accumulator->Add(is_wasm_to_js() ? "Wasm-to-JS [" : "Wasm [");
accumulator->PrintName(script().name());
Address instruction_start = wasm_code()->instruction_start();
base::Vector<const uint8_t> raw_func_name =
@@ -2631,6 +2631,15 @@ void WasmDebugBreakFrame::Print(StringStream* accumulator, PrintMode mode,
if (mode != OVERVIEW) accumulator->Add("\n");
}
+WasmInstanceObject WasmToJsFrame::wasm_instance() const {
+ // WasmToJsFrames hold the {WasmApiFunctionRef} object in the instance slot.
+ // Load the instance from there.
+ const int offset = WasmFrameConstants::kWasmInstanceOffset;
+ Object func_ref_obj(Memory<Address>(fp() + offset));
+ WasmApiFunctionRef func_ref = WasmApiFunctionRef::cast(func_ref_obj);
+ return WasmInstanceObject::cast(func_ref.instance());
+}
+
void JsToWasmFrame::Iterate(RootVisitor* v) const {
CodeLookupResult lookup_result = GetContainingCode(isolate(), pc());
CHECK(lookup_result.IsFound());
diff --git a/src/execution/frames.h b/src/execution/frames.h
index c72b7acef4b532fec8c55b698711a4897b1494c9..f6cf5360ce94fe62ce9076abb929b42e13c60b6a 100644
--- a/src/execution/frames.h
+++ b/src/execution/frames.h
@@ -1035,7 +1035,7 @@ class WasmFrame : public TypedFrame {
void Iterate(RootVisitor* v) const override;
// Accessors.
- V8_EXPORT_PRIVATE WasmInstanceObject wasm_instance() const;
+ virtual V8_EXPORT_PRIVATE WasmInstanceObject wasm_instance() const;
V8_EXPORT_PRIVATE wasm::NativeModule* native_module() const;
wasm::WasmCode* wasm_code() const;
int function_index() const;
@@ -1101,6 +1101,9 @@ class WasmToJsFrame : public WasmFrame {
public:
Type type() const override { return WASM_TO_JS; }
+ int position() const override { return 0; }
+ WasmInstanceObject wasm_instance() const override;
+
protected:
inline explicit WasmToJsFrame(StackFrameIteratorBase* iterator);
diff --git a/test/mjsunit/regress/asm/regress-1402270.js b/test/mjsunit/regress/asm/regress-1402270.js
new file mode 100644
index 0000000000000000000000000000000000000000..77badd768f6f502ee3bacec73049f25cd8af40b7
--- /dev/null
+++ b/test/mjsunit/regress/asm/regress-1402270.js
@@ -0,0 +1,16 @@
+// Copyright 2022 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+function print_stack(unused_arg) {
+ console.trace();
+}
+function asm(_, imports) {
+ 'use asm';
+ var print_stack = imports.print_stack;
+ function f() {
+ print_stack(1);
+ }
+ return f;
+}
+asm({}, {'print_stack': print_stack})();

View File

@@ -0,0 +1,109 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tobias Tebbi <tebbi@chromium.org>
Date: Wed, 15 Feb 2023 16:35:18 +0100
Subject: check if maps become deprecated during optimization
(cherry picked from commit f82d802a20aa62e42269f977302f26c5c3ed031b)
Bug: chromium:1417585
No-Try: true
No-Presubmit: true
No-Tree-Checks: true
Change-Id: Ie8eb76d2afb3ee4be66cf5d1c4bff8f745dc145b
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4255648
Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#85848}
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4294983
Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
Reviewed-by: Achuith Bhandarkar <achuith@chromium.org>
Commit-Queue: Roger Felipe Zanoni da Silva <rzanoni@google.com>
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/branch-heads/10.8@{#50}
Cr-Branched-From: f1bc03fd6b4c201abd9f0fd9d51fb989150f97b9-refs/heads/10.8.168@{#1}
Cr-Branched-From: 237de893e1c0a0628a57d0f5797483d3add7f005-refs/heads/main@{#83672}
diff --git a/src/codegen/bailout-reason.h b/src/codegen/bailout-reason.h
index cdd9e123185d142dfeac1e422f345a6a5955658f..33a12a67e4464a907124bb2f45a224f43ed7ec3a 100644
--- a/src/codegen/bailout-reason.h
+++ b/src/codegen/bailout-reason.h
@@ -94,19 +94,20 @@ namespace internal {
V(kUnexpectedThreadInWasmSet, "thread_in_wasm flag was already set") \
V(kUnexpectedThreadInWasmUnset, "thread_in_wasm flag was not set")
-#define BAILOUT_MESSAGES_LIST(V) \
- V(kNoReason, "no reason") \
- \
- V(kBailedOutDueToDependencyChange, "Bailed out due to dependency change") \
- V(kCodeGenerationFailed, "Code generation failed") \
- V(kFunctionBeingDebugged, "Function is being debugged") \
- V(kGraphBuildingFailed, "Optimized graph construction failed") \
- V(kFunctionTooBig, "Function is too big to be optimized") \
- V(kTooManyArguments, "Function contains a call with too many arguments") \
- V(kLiveEdit, "LiveEdit") \
- V(kNativeFunctionLiteral, "Native function literal") \
- V(kOptimizationDisabled, "Optimization disabled") \
- V(kHigherTierAvailable, "A higher tier is already available") \
+#define BAILOUT_MESSAGES_LIST(V) \
+ V(kNoReason, "no reason") \
+ \
+ V(kBailedOutDueToDependencyChange, "Bailed out due to dependency change") \
+ V(kConcurrentMapDeprecation, "Maps became deprecated during optimization") \
+ V(kCodeGenerationFailed, "Code generation failed") \
+ V(kFunctionBeingDebugged, "Function is being debugged") \
+ V(kGraphBuildingFailed, "Optimized graph construction failed") \
+ V(kFunctionTooBig, "Function is too big to be optimized") \
+ V(kTooManyArguments, "Function contains a call with too many arguments") \
+ V(kLiveEdit, "LiveEdit") \
+ V(kNativeFunctionLiteral, "Native function literal") \
+ V(kOptimizationDisabled, "Optimization disabled") \
+ V(kHigherTierAvailable, "A higher tier is already available") \
V(kNeverOptimize, "Optimization is always disabled")
#define ERROR_MESSAGES_CONSTANTS(C, T) C,
diff --git a/src/compiler/pipeline.cc b/src/compiler/pipeline.cc
index a142d46a4760d65b09419211afa0972e1f5e6205..7e066adf0a0d04ca332e6b04a253937e51b1d367 100644
--- a/src/compiler/pipeline.cc
+++ b/src/compiler/pipeline.cc
@@ -728,7 +728,10 @@ class PipelineImpl final {
// Step D. Run the code finalization pass.
MaybeHandle<Code> FinalizeCode(bool retire_broker = true);
- // Step E. Install any code dependencies.
+ // Step E. Ensure all embedded maps are non-deprecated.
+ bool CheckNoDeprecatedMaps(Handle<Code> code);
+
+ // Step F. Install any code dependencies.
bool CommitDependencies(Handle<Code> code);
void VerifyGeneratedCodeIsIdempotent();
@@ -1272,6 +1275,9 @@ PipelineCompilationJob::Status PipelineCompilationJob::FinalizeJobImpl(
}
return FAILED;
}
+ if (!pipeline_.CheckNoDeprecatedMaps(code)) {
+ return RetryOptimization(BailoutReason::kConcurrentMapDeprecation);
+ }
if (!pipeline_.CommitDependencies(code)) {
return RetryOptimization(BailoutReason::kBailedOutDueToDependencyChange);
}
@@ -3961,6 +3967,20 @@ MaybeHandle<Code> PipelineImpl::GenerateCode(CallDescriptor* call_descriptor) {
return FinalizeCode();
}
+// We must not embed deprecated maps, as we rely in the compiler on all explicit
+// maps not being deprecated.
+bool PipelineImpl::CheckNoDeprecatedMaps(Handle<Code> code) {
+ int mode_mask = RelocInfo::EmbeddedObjectModeMask();
+ for (RelocIterator it(*code, mode_mask); !it.done(); it.next()) {
+ DCHECK(RelocInfo::IsEmbeddedObjectMode(it.rinfo()->rmode()));
+ HeapObject obj = it.rinfo()->target_object(data_->isolate());
+ if (obj.IsMap() && Map::cast(obj).is_deprecated()) {
+ return false;
+ }
+ }
+ return true;
+}
+
bool PipelineImpl::CommitDependencies(Handle<Code> code) {
return data_->dependencies() == nullptr ||
data_->dependencies()->Commit(code);

View File

@@ -0,0 +1,2 @@
cherry-pick-e0efbd45ea74.patch
cherry-pick-218b56e51638.patch

View File

@@ -0,0 +1,60 @@
From 218b56e516386cd57c7513197528c3124bcd7ef3 Mon Sep 17 00:00:00 2001
From: Alexander Cooper <alcooper@chromium.org>
Date: Wed, 08 Feb 2023 14:16:01 -0800
Subject: [PATCH] Fix Destruction inside WGC Callback
If we are notified of the destruction of the window before a
CaptureFrame call can fail, then we may end up attempting to destroy the
underlying WGC object inside it's own event handler. This can be
problematic, as the class itself may want to run other code. Instead,
we just unsubscribe and signal that any future CaptureFrame calls should
reject.
This also removes setting "is_capture_started_=false" in the item closed
handler, as all that served to do is cause the WgcCapturerWin code to
attempt to restart the capturer, and somewhat muddies up our metrics.
(cherry picked from commit 318cf28945d80a0ac6f09382e507c95e649cc4c1)
Bug: chromium:1413005
No-Try: True
Change-Id: Ibccb7a2e7ce531ba80b4b331b9bc2cda0ff75f4e
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/292762
Auto-Submit: Alexander Cooper <alcooper@chromium.org>
Reviewed-by: Mark Foltz <mfoltz@chromium.org>
Commit-Queue: Mark Foltz <mfoltz@chromium.org>
Commit-Queue: Alexander Cooper <alcooper@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#39275}
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/293246
Bot-Commit: rubber-stamper@appspot.gserviceaccount.com <rubber-stamper@appspot.gserviceaccount.com>
Cr-Commit-Position: refs/branch-heads/5481@{#5}
Cr-Branched-From: 2e1a9a4ae0234d4b1ea7a6fd4188afa1fb20379d-refs/heads/main@{#38901}
---
diff --git a/modules/desktop_capture/win/wgc_capture_session.cc b/modules/desktop_capture/win/wgc_capture_session.cc
index e165291..ea5565c 100644
--- a/modules/desktop_capture/win/wgc_capture_session.cc
+++ b/modules/desktop_capture/win/wgc_capture_session.cc
@@ -397,17 +397,14 @@
RTC_LOG(LS_INFO) << "Capture target has been closed.";
item_closed_ = true;
- is_capture_started_ = false;
RemoveEventHandlers();
- mapped_texture_ = nullptr;
- session_ = nullptr;
- frame_pool_ = nullptr;
- direct3d_device_ = nullptr;
- item_ = nullptr;
- d3d11_device_ = nullptr;
-
+ // Do not attempt to free resources in the OnItemClosed handler, as this
+ // causes a race where we try to delete the item that is calling us. Removing
+ // the event handlers and setting `item_closed_` above is sufficient to ensure
+ // that the resources are no longer used, and the next time the capturer tries
+ // to get a frame, we will report a permanent failure and be destroyed.
return S_OK;
}

View File

@@ -0,0 +1,57 @@
From e0efbd45ea7421fb944c7343254ac5dc22bee541 Mon Sep 17 00:00:00 2001
From: Henrik Boström <hbos@webrtc.org>
Date: Fri, 20 Jan 2023 10:48:31 +0100
Subject: [PATCH] [Merge-110] [Stats] Handle the case of missing certificates.
Certificates being missing is a sign of a bug (e.g. webrtc:14844, to be
fixed separately) which is why we have a DCHECK. But this DCHECK does
not protect against accessing the invalid iterator if it is a release
build. This CL makes that safe.
# Mobile bots not running properly
NOTRY=True
(cherry picked from commit 124d7c3fe5bdc79a355c9df02d07f25331631a68)
Bug: chromium:1408392
Change-Id: I97a82786028e41c58ef8ef15002c3f959bbec7f1
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/291109
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Cr-Original-Commit-Position: refs/heads/main@{#39159}
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/291380
Cr-Commit-Position: refs/branch-heads/5481@{#2}
Cr-Branched-From: 2e1a9a4ae0234d4b1ea7a6fd4188afa1fb20379d-refs/heads/main@{#38901}
---
diff --git a/pc/rtc_stats_collector.cc b/pc/rtc_stats_collector.cc
index d500a7b..1d88566 100644
--- a/pc/rtc_stats_collector.cc
+++ b/pc/rtc_stats_collector.cc
@@ -2192,16 +2192,17 @@
// exist.
const auto& certificate_stats_it =
transport_cert_stats.find(transport_name);
+ std::string local_certificate_id, remote_certificate_id;
RTC_DCHECK(certificate_stats_it != transport_cert_stats.cend());
- std::string local_certificate_id;
- if (certificate_stats_it->second.local) {
- local_certificate_id = RTCCertificateIDFromFingerprint(
- certificate_stats_it->second.local->fingerprint);
- }
- std::string remote_certificate_id;
- if (certificate_stats_it->second.remote) {
- remote_certificate_id = RTCCertificateIDFromFingerprint(
- certificate_stats_it->second.remote->fingerprint);
+ if (certificate_stats_it != transport_cert_stats.cend()) {
+ if (certificate_stats_it->second.local) {
+ local_certificate_id = RTCCertificateIDFromFingerprint(
+ certificate_stats_it->second.local->fingerprint);
+ }
+ if (certificate_stats_it->second.remote) {
+ remote_certificate_id = RTCCertificateIDFromFingerprint(
+ certificate_stats_it->second.remote->fingerprint);
+ }
}
// There is one transport stats for each channel.

View File

@@ -21,6 +21,10 @@ def run_node_configure(target_cpu):
# Work around "No acceptable ASM compiler found" error on some System,
# it breaks nothing since Electron does not use OpenSSL.
args += ['--openssl-no-asm']
# Enable whole-program optimization for electron native modules.
if sys.platform == "win32":
args += ['--with-ltcg']
subprocess.check_call([sys.executable, configure] + args)
def read_node_config_gypi():

View File

@@ -14,8 +14,8 @@ const ROLLER_BRANCH_PATTERN = /^roller\/chromium$/;
const DEFAULT_BUILD_CLOUD_ID = '1598';
const DEFAULT_BUILD_CLOUD = 'electronhq-16-core';
const DEFAULT_BAKE_BASE_IMAGE = 'Windows_Default_Appveyor';
const DEFAULT_BUILD_IMAGE = 'Windows_Default_Appveyor';
const DEFAULT_BAKE_BASE_IMAGE = 'e-111.0.5560.0-node18';
const DEFAULT_BUILD_IMAGE = 'e-111.0.5560.0-node18';
const appveyorBakeJob = 'electron-bake-image';
const appVeyorJobs = {

View File

@@ -13,6 +13,7 @@ const fs = require('fs');
const { execSync } = require('child_process');
const got = require('got');
const path = require('path');
const semver = require('semver');
const temp = require('temp').track();
const { URL } = require('url');
const { BlobServiceClient } = require('@azure/storage-blob');
@@ -317,12 +318,20 @@ function saveShaSumFile (checksums, fileName) {
}
async function publishRelease (release) {
const currentLatest = await octokit.repos.getLatestRelease({
owner: 'electron',
repo: targetRepo
});
const makeLatest = !release.prerelease && semver.gte(release.tag_name, currentLatest.data.tag_name);
return octokit.repos.updateRelease({
owner: 'electron',
repo: targetRepo,
release_id: release.id,
tag_name: release.tag_name,
draft: false
draft: false,
make_latest: makeLatest ? 'true' : 'false'
}).catch(err => {
console.log(`${fail} Error publishing release:`, err);
process.exit(1);

View File

@@ -56,7 +56,8 @@ REM Install Windows SDK
choco install windows-sdk-10-version-2104-all
REM Install nodejs python git and yarn needed dependencies
choco install -y nodejs-lts python2 git yarn
choco install -y --force nodejs --version=18.12.1
choco install -y python2 git yarn
choco install python --version 3.7.9
call C:\ProgramData\chocolatey\bin\RefreshEnv.cmd
SET PATH=C:\Python27\;C:\Python27\Scripts;C:\Python39\;C:\Python39\Scripts;%PATH%

View File

@@ -1,5 +1,6 @@
#!/usr/bin/env node
const { ElectronVersions, Installer } = require('@electron/fiddle-core');
const childProcess = require('child_process');
const crypto = require('crypto');
const fs = require('fs-extra');
@@ -12,7 +13,7 @@ const pass = '✓'.green;
const fail = '✗'.red;
const args = require('minimist')(process.argv, {
string: ['runners', 'target'],
string: ['runners', 'target', 'electronVersion'],
boolean: ['buildNativeTests'],
unknown: arg => unknownFlags.push(arg)
});
@@ -39,6 +40,15 @@ const runners = new Map([
const specHashPath = path.resolve(__dirname, '../spec/.hash');
if (args.electronVersion) {
if (args.runners && args.runners !== 'main') {
console.log(`${fail} only 'main' runner can be used with --electronVersion`);
process.exit(1);
}
args.runners = 'main';
}
let runnersToRun = null;
if (args.runners !== undefined) {
runnersToRun = args.runners.split(',').filter(value => value);
@@ -52,6 +62,14 @@ if (args.runners !== undefined) {
}
async function main () {
if (args.electronVersion) {
const versions = await ElectronVersions.create();
if (!versions.isVersion(args.electronVersion)) {
console.log(`${fail} '${args.electronVersion}' is not a recognized Electron version`);
process.exit(1);
}
}
const [lastSpecHash, lastSpecInstallHash] = loadLastSpecHash();
const [currentSpecHash, currentSpecInstallHash] = await getSpecHash();
const somethingChanged = (currentSpecHash !== lastSpecHash) ||
@@ -122,7 +140,13 @@ async function runElectronTests () {
}
async function runTestUsingElectron (specDir, testName) {
let exe = path.resolve(BASE, utils.getElectronExec());
let exe;
if (args.electronVersion) {
const installer = new Installer();
exe = await installer.install(args.electronVersion);
} else {
exe = path.resolve(BASE, utils.getElectronExec());
}
const runnerArgs = [`electron/${specDir}`, ...unknownArgs.slice(2)];
if (process.platform === 'linux') {
runnerArgs.unshift(path.resolve(__dirname, 'dbus_mock.py'), exe);
@@ -212,14 +236,20 @@ async function installSpecModules (dir) {
// but don't clobber any other CXXFLAGS that were passed into spec-runner.js
const CXXFLAGS = ['-std=c++17', process.env.CXXFLAGS].filter(x => !!x).join(' ');
const nodeDir = path.resolve(BASE, `out/${utils.getOutDir({ shouldLog: true })}/gen/node_headers`);
const env = {
...process.env,
CXXFLAGS,
npm_config_nodedir: nodeDir,
npm_config_msvs_version: '2019',
npm_config_yes: 'true'
};
if (args.electronVersion) {
env.npm_config_target = args.electronVersion;
env.npm_config_disturl = 'https://electronjs.org/headers';
env.npm_config_runtime = 'electron';
env.npm_config_build_from_source = 'true';
} else {
env.npm_config_nodedir = path.resolve(BASE, `out/${utils.getOutDir({ shouldLog: true })}/gen/node_headers`);
}
if (fs.existsSync(path.resolve(dir, 'node_modules'))) {
await fs.remove(path.resolve(dir, 'node_modules'));
}

View File

@@ -15,7 +15,6 @@
#include "base/strings/sys_string_conversions.h"
#include "content/common/mac_helpers.h"
#include "content/public/common/content_paths.h"
#include "ppapi/buildflags/buildflags.h"
#include "shell/browser/mac/electron_application.h"
#include "shell/common/application_info.h"
#include "shell/common/mac/main_application_bundle.h"
@@ -41,11 +40,9 @@ base::FilePath GetHelperAppPath(const base::FilePath& frameworks_path,
} else if (base::EndsWith(path.value(), content::kMacHelperSuffix_gpu,
base::CompareCase::SENSITIVE)) {
helper_name += content::kMacHelperSuffix_gpu;
#if BUILDFLAG(ENABLE_PLUGINS)
} else if (base::EndsWith(path.value(), content::kMacHelperSuffix_plugin,
base::CompareCase::SENSITIVE)) {
helper_name += content::kMacHelperSuffix_plugin;
#endif
}
return frameworks_path.Append(name + " " + helper_name + ".app")

View File

@@ -246,37 +246,9 @@ int NodeMain(int argc, char* argv[]) {
v8::HandleScope scope(isolate);
node::LoadEnvironment(env, node::StartExecutionCallback{});
env->set_trace_sync_io(env->options()->trace_sync_io);
{
v8::SealHandleScope seal(isolate);
bool more;
env->performance_state()->Mark(
node::performance::NODE_PERFORMANCE_MILESTONE_LOOP_START);
do {
uv_run(env->event_loop(), UV_RUN_DEFAULT);
gin_env.platform()->DrainTasks(isolate);
more = uv_loop_alive(env->event_loop());
if (more && !env->is_stopping())
continue;
if (!uv_loop_alive(env->event_loop())) {
EmitBeforeExit(env);
}
// Emit `beforeExit` if the loop became alive either after emitting
// event, or after running some callbacks.
more = uv_loop_alive(env->event_loop());
} while (more && !env->is_stopping());
env->performance_state()->Mark(
node::performance::NODE_PERFORMANCE_MILESTONE_LOOP_EXIT);
}
env->set_trace_sync_io(false);
exit_code = node::EmitExit(env);
// Potential reasons we get Nothing here may include: the env
// is stopping, or the user hooks process.emit('exit').
exit_code = node::SpinEventLoop(env).FromMaybe(1);
node::ResetStdio();

View File

@@ -881,6 +881,16 @@ gfx::Point BaseWindow::GetTrafficLightPosition() const {
}
#endif
#if BUILDFLAG(IS_MAC)
bool BaseWindow::IsHiddenInMissionControl() {
return window_->IsHiddenInMissionControl();
}
void BaseWindow::SetHiddenInMissionControl(bool hidden) {
window_->SetHiddenInMissionControl(hidden);
}
#endif
void BaseWindow::SetTouchBar(
std::vector<gin_helper::PersistentDictionary> items) {
window_->SetTouchBar(std::move(items));
@@ -1256,6 +1266,14 @@ void BaseWindow::BuildPrototype(v8::Isolate* isolate,
.SetMethod("getTrafficLightPosition",
&BaseWindow::GetTrafficLightPosition)
#endif
#if BUILDFLAG(IS_MAC)
.SetMethod("isHiddenInMissionControl",
&BaseWindow::IsHiddenInMissionControl)
.SetMethod("setHiddenInMissionControl",
&BaseWindow::SetHiddenInMissionControl)
#endif
.SetMethod("_setTouchBarItems", &BaseWindow::SetTouchBar)
.SetMethod("_refreshTouchBarItem", &BaseWindow::RefreshTouchBarItem)
.SetMethod("_setEscapeTouchBarItem", &BaseWindow::SetEscapeTouchBarItem)

View File

@@ -198,6 +198,11 @@ class BaseWindow : public gin_helper::TrackableObject<BaseWindow>,
gfx::Point GetTrafficLightPosition() const;
#endif
#if BUILDFLAG(IS_MAC)
bool IsHiddenInMissionControl();
void SetHiddenInMissionControl(bool hidden);
#endif
void SetTouchBar(std::vector<gin_helper::PersistentDictionary> items);
void RefreshTouchBarItem(const std::string& item_id);
void SetEscapeTouchBarItem(gin_helper::PersistentDictionary item);

View File

@@ -127,7 +127,6 @@ BrowserWindow::~BrowserWindow() {
api_web_contents_->RemoveObserver(this);
// Destroy the WebContents.
OnCloseContents();
api_web_contents_->Destroy();
}
}
@@ -155,6 +154,7 @@ void BrowserWindow::WebContentsDestroyed() {
void BrowserWindow::OnCloseContents() {
BaseWindow::ResetBrowserViews();
api_web_contents_->Destroy();
}
void BrowserWindow::OnRendererResponsive(content::RenderProcessHost*) {

View File

@@ -128,10 +128,10 @@ bool MatchesCookie(const base::Value::Dict& filter,
!MatchesDomain(*str, cookie.Domain()))
return false;
absl::optional<bool> secure_filter = filter.FindBool("secure");
if (secure_filter && *secure_filter == cookie.IsSecure())
if (secure_filter && *secure_filter != cookie.IsSecure())
return false;
absl::optional<bool> session_filter = filter.FindBool("session");
if (session_filter && *session_filter != !cookie.IsPersistent())
if (session_filter && *session_filter == cookie.IsPersistent())
return false;
return true;
}
@@ -177,7 +177,7 @@ std::string InclusionStatusToString(net::CookieInclusionStatus status) {
return "Failed to parse cookie";
if (status.HasExclusionReason(
net::CookieInclusionStatus::EXCLUDE_INVALID_DOMAIN))
return "Failed to get cookie domain";
return "Failed to set cookie with an invalid domain attribute";
if (status.HasExclusionReason(
net::CookieInclusionStatus::EXCLUDE_INVALID_PREFIX))
return "Failed because the cookie violated prefix rules.";
@@ -315,19 +315,24 @@ v8::Local<v8::Promise> Cookies::Set(v8::Isolate* isolate,
return handle;
}
net::CookieInclusionStatus status;
auto canonical_cookie = net::CanonicalCookie::CreateSanitizedCookie(
url, name ? *name : "", value ? *value : "", domain ? *domain : "",
path ? *path : "", ParseTimeProperty(details.FindDouble("creationDate")),
ParseTimeProperty(details.FindDouble("expirationDate")),
ParseTimeProperty(details.FindDouble("lastAccessDate")), secure,
http_only, same_site, net::COOKIE_PRIORITY_DEFAULT, same_party,
absl::nullopt);
absl::nullopt, &status);
if (!canonical_cookie || !canonical_cookie->IsCanonical()) {
promise.RejectWithErrorMessage(
InclusionStatusToString(net::CookieInclusionStatus(
net::CookieInclusionStatus::EXCLUDE_FAILURE_TO_STORE)));
promise.RejectWithErrorMessage(InclusionStatusToString(
!status.IsInclude()
? status
: net::CookieInclusionStatus(
net::CookieInclusionStatus::EXCLUDE_FAILURE_TO_STORE)));
return handle;
}
net::CookieOptions options;
if (http_only) {
options.set_include_httponly();

View File

@@ -1221,7 +1221,9 @@ void WebContents::CloseContents(content::WebContents* source) {
for (ExtendedWebContentsObserver& observer : observers_)
observer.OnCloseContents();
Destroy();
// If there are observers, OnCloseContents will call Destroy()
if (observers_.empty())
Destroy();
}
void WebContents::ActivateContents(content::WebContents* source) {
@@ -1520,13 +1522,15 @@ void WebContents::HandleNewRenderFrame(
// Set the background color of RenderWidgetHostView.
auto* web_preferences = WebContentsPreferences::From(web_contents());
if (web_preferences) {
absl::optional<SkColor> maybe_color = web_preferences->GetBackgroundColor();
web_contents()->SetPageBaseBackgroundColor(maybe_color);
auto maybe_color = web_preferences->GetBackgroundColor();
bool guest = IsGuest() || type_ == Type::kBrowserView;
SkColor color =
// If webPreferences has no color stored we need to explicitly set guest
// webContents background color to transparent.
auto bg_color =
maybe_color.value_or(guest ? SK_ColorTRANSPARENT : SK_ColorWHITE);
SetBackgroundColor(rwhv, color);
web_contents()->SetPageBaseBackgroundColor(bg_color);
SetBackgroundColor(rwhv, bg_color);
}
if (!background_throttling_)
@@ -3524,18 +3528,26 @@ v8::Local<v8::Promise> WebContents::TakeHeapSnapshot(
base::File file(file_path,
base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE);
if (!file.IsValid()) {
promise.RejectWithErrorMessage("takeHeapSnapshot failed");
promise.RejectWithErrorMessage(
"Failed to take heap snapshot with invalid file path " +
#if BUILDFLAG(IS_WIN)
base::WideToUTF8(file_path.value()));
#else
file_path.value());
#endif
return handle;
}
auto* frame_host = web_contents()->GetPrimaryMainFrame();
if (!frame_host) {
promise.RejectWithErrorMessage("takeHeapSnapshot failed");
promise.RejectWithErrorMessage(
"Failed to take heap snapshot with invalid webContents main frame");
return handle;
}
if (!frame_host->IsRenderFrameLive()) {
promise.RejectWithErrorMessage("takeHeapSnapshot failed");
promise.RejectWithErrorMessage(
"Failed to take heap snapshot with nonexistent render frame");
return handle;
}
@@ -3555,7 +3567,7 @@ v8::Local<v8::Promise> WebContents::TakeHeapSnapshot(
if (success) {
promise.Resolve();
} else {
promise.RejectWithErrorMessage("takeHeapSnapshot failed");
promise.RejectWithErrorMessage("Failed to take heap snapshot");
}
},
base::Owned(std::move(electron_renderer)), std::move(promise)));

View File

@@ -120,10 +120,6 @@
#include "ui/native_theme/native_theme.h"
#include "v8/include/v8.h"
#if BUILDFLAG(IS_WIN)
#include "sandbox/win/src/sandbox_policy.h"
#endif
#if BUILDFLAG(USE_NSS_CERTS)
#include "net/ssl/client_cert_store_nss.h"
#elif BUILDFLAG(IS_WIN)
@@ -475,15 +471,10 @@ void ElectronBrowserClient::AppendExtraCommandLineSwitches(
content::ChildProcessHost::CHILD_RENDERER);
auto gpu_child_path = content::ChildProcessHost::GetChildPath(
content::ChildProcessHost::CHILD_GPU);
#if BUILDFLAG(ENABLE_PLUGINS)
auto plugin_child_path = content::ChildProcessHost::GetChildPath(
content::ChildProcessHost::CHILD_PLUGIN);
#endif
if (program != renderer_child_path && program != gpu_child_path
#if BUILDFLAG(ENABLE_PLUGINS)
&& program != plugin_child_path
#endif
) {
if (program != renderer_child_path && program != gpu_child_path &&
program != plugin_child_path) {
child_path = content::ChildProcessHost::GetChildPath(
content::ChildProcessHost::CHILD_NORMAL);
CHECK_EQ(program, child_path)
@@ -1464,19 +1455,6 @@ void ElectronBrowserClient::OverrideURLLoaderFactoryParams(
browser_context, origin, is_for_isolated_world, factory_params);
}
#if BUILDFLAG(IS_WIN)
bool ElectronBrowserClient::PreSpawnChild(sandbox::TargetPolicy* policy,
sandbox::mojom::Sandbox sandbox_type,
ChildSpawnFlags flags) {
sandbox::ResultCode result = policy->GetConfig()->AddRule(
sandbox::SubSystem::kFiles, sandbox::Semantics::kFilesAllowAny,
L"\\??\\pipe\\crashpad_*");
if (result != sandbox::SBOX_ALL_OK)
return false;
return true;
}
#endif // BUILDFLAG(IS_WIN)
void ElectronBrowserClient::
RegisterAssociatedInterfaceBindersForRenderFrameHost(
content::RenderFrameHost&

View File

@@ -245,11 +245,6 @@ class ElectronBrowserClient : public content::ContentBrowserClient,
const url::Origin& origin,
bool is_for_isolated_world,
network::mojom::URLLoaderFactoryParams* factory_params) override;
#if BUILDFLAG(IS_WIN)
bool PreSpawnChild(sandbox::TargetPolicy* policy,
sandbox::mojom::Sandbox sandbox_type,
ChildSpawnFlags flags) override;
#endif
void RegisterAssociatedInterfaceBindersForRenderFrameHost(
content::RenderFrameHost& render_frame_host,
blink::AssociatedInterfaceRegistry& associated_registry) override;

View File

@@ -279,7 +279,7 @@ void ElectronBrowserMainParts::PostEarlyInitialization() {
env->set_trace_sync_io(env->options()->trace_sync_io);
// We do not want to crash the main process on unhandled rejections.
env->options()->unhandled_rejections = "warn";
env->options()->unhandled_rejections = "warn-with-error-code";
// Add Electron extended APIs.
electron_bindings_->BindTo(js_env_->isolate(), env->process_object());

View File

@@ -193,6 +193,18 @@ inline void dispatch_sync_main(dispatch_block_t block) {
return [super accessibilitySetValue:value forAttribute:attribute];
}
- (NSAccessibilityRole)accessibilityRole {
// For non-VoiceOver AT, such as Voice Control, Apple recommends turning on
// a11y when an AT accesses the 'accessibilityRole' property. This function
// is accessed frequently so we only change the accessibility state when
// accessibility is disabled.
auto* ax_state = content::BrowserAccessibilityState::GetInstance();
if (!ax_state->GetAccessibilityMode().has_mode(ui::kAXModeBasic.mode())) {
ax_state->AddAccessibilityModeFlags(ui::kAXModeBasic);
}
return [super accessibilityRole];
}
- (void)orderFrontStandardAboutPanel:(id)sender {
electron::Browser::Get()->ShowAboutPanel();
}

View File

@@ -172,7 +172,11 @@ void NativeWindow::InitFromOptions(const gin_helper::Dictionary& options) {
int max_width = max_size.width() > 0 ? max_size.width() : INT_MAX;
int max_height = max_size.height() > 0 ? max_size.height() : INT_MAX;
bool have_max_width = options.Get(options::kMaxWidth, &max_width);
if (have_max_width && max_width <= 0)
max_width = INT_MAX;
bool have_max_height = options.Get(options::kMaxHeight, &max_height);
if (have_max_height && max_height <= 0)
max_height = INT_MAX;
// By default the window has a default maximum size that prevents it
// from being resized larger than the screen, so we should only set this

View File

@@ -219,6 +219,12 @@ class NativeWindow : public base::SupportsUserData,
virtual void UpdateFrame() = 0;
#endif
// whether windows should be ignored by mission control
#if BUILDFLAG(IS_MAC)
virtual bool IsHiddenInMissionControl() = 0;
virtual void SetHiddenInMissionControl(bool hidden) = 0;
#endif
// Touchbar API
virtual void SetTouchBar(std::vector<gin_helper::PersistentDictionary> items);
virtual void RefreshTouchBarItem(const std::string& item_id);

View File

@@ -102,6 +102,8 @@ class NativeWindowMac : public NativeWindow,
void SetDocumentEdited(bool edited) override;
bool IsDocumentEdited() override;
void SetIgnoreMouseEvents(bool ignore, bool forward) override;
bool IsHiddenInMissionControl() override;
void SetHiddenInMissionControl(bool hidden) override;
void SetContentProtection(bool enable) override;
void SetFocusable(bool focusable) override;
bool IsFocusable() override;

View File

@@ -22,6 +22,7 @@
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/desktop_media_id.h"
#include "shell/browser/browser.h"
#include "shell/browser/javascript_environment.h"
#include "shell/browser/native_browser_view_mac.h"
#include "shell/browser/ui/cocoa/electron_native_widget_mac.h"
@@ -280,6 +281,9 @@ NativeWindowMac::NativeWindowMac(const gin_helper::Dictionary& options,
std::string windowType;
options.Get(options::kType, &windowType);
bool hiddenInMissionControl = false;
options.Get(options::kHiddenInMissionControl, &hiddenInMissionControl);
bool useStandardWindow = true;
// eventually deprecate separate "standardWindow" option in favor of
// standard / textured window types
@@ -418,6 +422,8 @@ NativeWindowMac::NativeWindowMac(const gin_helper::Dictionary& options,
options.Get(options::kDisableAutoHideCursor, &disableAutoHideCursor);
[window_ setDisableAutoHideCursor:disableAutoHideCursor];
SetHiddenInMissionControl(hiddenInMissionControl);
// Set maximizable state last to ensure zoom button does not get reset
// by calls to other APIs.
SetMaximizable(maximizable);
@@ -1159,9 +1165,17 @@ bool NativeWindowMac::IsDocumentEdited() {
return [window_ isDocumentEdited];
}
bool NativeWindowMac::IsHiddenInMissionControl() {
NSUInteger collectionBehavior = [window_ collectionBehavior];
return collectionBehavior & NSWindowCollectionBehaviorTransient;
}
void NativeWindowMac::SetHiddenInMissionControl(bool hidden) {
SetCollectionBehavior(hidden, NSWindowCollectionBehaviorTransient);
}
void NativeWindowMac::SetIgnoreMouseEvents(bool ignore, bool forward) {
[window_ setIgnoresMouseEvents:ignore];
if (!ignore) {
SetForwardMouseMessages(NO);
} else {
@@ -1335,18 +1349,15 @@ void NativeWindowMac::SetOverlayIcon(const gfx::Image& overlay,
void NativeWindowMac::SetVisibleOnAllWorkspaces(bool visible,
bool visibleOnFullScreen,
bool skipTransformProcessType) {
// In order for NSWindows to be visible on fullscreen we need to functionally
// mimic app.dock.hide() since Apple changed the underlying functionality of
// In order for NSWindows to be visible on fullscreen we need to invoke
// app.dock.hide() since Apple changed the underlying functionality of
// NSWindows starting with 10.14 to disallow NSWindows from floating on top of
// fullscreen apps.
if (!skipTransformProcessType) {
ProcessSerialNumber psn = {0, kCurrentProcess};
if (visibleOnFullScreen) {
[window_ setCanHide:NO];
TransformProcessType(&psn, kProcessTransformToUIElementApplication);
Browser::Get()->DockHide();
} else {
[window_ setCanHide:YES];
TransformProcessType(&psn, kProcessTransformToForegroundApplication);
Browser::Get()->DockShow(JavascriptEnvironment::GetIsolate());
}
}

View File

@@ -58,7 +58,11 @@ void CocoaNotification::Show(const NotificationOptions& options) {
[notification_ setSoundName:base::SysUTF16ToNSString(options.sound)];
}
[notification_ setHasActionButton:false];
if (options.has_reply) {
[notification_ setHasReplyButton:true];
[notification_ setResponsePlaceholder:base::SysUTF16ToNSString(
options.reply_placeholder)];
}
int i = 0;
action_index_ = UINT_MAX;
@@ -66,7 +70,10 @@ void CocoaNotification::Show(const NotificationOptions& options) {
[[[NSMutableArray alloc] init] autorelease];
for (const auto& action : options.actions) {
if (action.type == u"button") {
if (action_index_ == UINT_MAX) {
// If the notification has both a reply and actions,
// the reply takes precedence and the actions all
// become additional actions.
if (!options.has_reply && action_index_ == UINT_MAX) {
// First button observed is the displayed action
[notification_ setHasActionButton:true];
[notification_
@@ -86,16 +93,11 @@ void CocoaNotification::Show(const NotificationOptions& options) {
}
i++;
}
if ([additionalActions count] > 0) {
[notification_ setAdditionalActions:additionalActions];
}
if (options.has_reply) {
[notification_ setResponsePlaceholder:base::SysUTF16ToNSString(
options.reply_placeholder)];
[notification_ setHasReplyButton:true];
}
if (!options.close_button_text.empty()) {
[notification_ setOtherButtonTitle:base::SysUTF16ToNSString(
options.close_button_text)];

View File

@@ -185,12 +185,10 @@ int ScopedDisableResize::disable_resize_ = 0;
}
- (void)beginPreviewPanelControl:(QLPreviewPanel*)panel {
panel.delegate = [self delegate];
panel.dataSource = static_cast<id<QLPreviewPanelDataSource>>([self delegate]);
}
- (void)endPreviewPanelControl:(QLPreviewPanel*)panel {
panel.delegate = nil;
panel.dataSource = nil;
}

View File

@@ -128,16 +128,17 @@ using FullScreenTransitionState =
- (NSSize)windowWillResize:(NSWindow*)sender toSize:(NSSize)frameSize {
NSSize newSize = frameSize;
double aspectRatio = shell_->GetAspectRatio();
NSWindow* window = shell_->GetNativeWindow().GetNativeNSWindow();
if (aspectRatio > 0.0) {
gfx::Size windowSize = shell_->GetSize();
gfx::Size contentSize = shell_->GetContentSize();
gfx::Size extraSize = shell_->GetAspectRatioExtraSize();
double titleBarHeight = windowSize.height() - contentSize.height();
double extraWidthPlusFrame =
windowSize.width() - contentSize.width() + extraSize.width();
double extraHeightPlusFrame =
windowSize.height() - contentSize.height() + extraSize.height();
double extraHeightPlusFrame = titleBarHeight + extraSize.height();
newSize.width =
roundf((frameSize.height - extraHeightPlusFrame) * aspectRatio +
@@ -145,10 +146,44 @@ using FullScreenTransitionState =
newSize.height =
roundf((newSize.width - extraWidthPlusFrame) / aspectRatio +
extraHeightPlusFrame);
// Clamp to minimum width/height while ensuring aspect ratio remains.
NSSize minSize = [window minSize];
NSSize zeroSize =
shell_->has_frame() ? NSMakeSize(0, titleBarHeight) : NSZeroSize;
if (!NSEqualSizes(minSize, zeroSize)) {
double minWidthForAspectRatio =
(minSize.height - titleBarHeight) * aspectRatio;
bool atMinHeight =
minSize.height > zeroSize.height && newSize.height <= minSize.height;
newSize.width = atMinHeight ? minWidthForAspectRatio
: std::max(newSize.width, minSize.width);
double minHeightForAspectRatio = minSize.width / aspectRatio;
bool atMinWidth =
minSize.width > zeroSize.width && newSize.width <= minSize.width;
newSize.height = atMinWidth ? minHeightForAspectRatio
: std::max(newSize.height, minSize.height);
}
// Clamp to maximum width/height while ensuring aspect ratio remains.
NSSize maxSize = [window maxSize];
if (!NSEqualSizes(maxSize, NSMakeSize(FLT_MAX, FLT_MAX))) {
double maxWidthForAspectRatio = maxSize.height * aspectRatio;
bool atMaxHeight =
maxSize.height < FLT_MAX && newSize.height >= maxSize.height;
newSize.width = atMaxHeight ? maxWidthForAspectRatio
: std::min(newSize.width, maxSize.width);
double maxHeightForAspectRatio = maxSize.width / aspectRatio;
bool atMaxWidth =
maxSize.width < FLT_MAX && newSize.width >= maxSize.width;
newSize.height = atMaxWidth ? maxHeightForAspectRatio
: std::min(newSize.height, maxSize.height);
}
}
if (!resizingHorizontally_) {
NSWindow* window = shell_->GetNativeWindow().GetNativeNSWindow();
const auto widthDelta = frameSize.width - [window frame].size.width;
const auto heightDelta = frameSize.height - [window frame].size.height;
resizingHorizontally_ = std::abs(widthDelta) > std::abs(heightDelta);

View File

@@ -0,0 +1,70 @@
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "shell/browser/ui/gtk/menu_gtk.h"
#include <gtk/gtk.h>
#include "shell/browser/ui/gtk/menu_util.h"
#include "ui/base/models/menu_model.h"
namespace electron {
namespace gtkui {
MenuGtk::MenuGtk(ui::MenuModel* model)
: menu_model_(model), gtk_menu_(TakeGObject(gtk_menu_new())) {
if (menu_model_) {
BuildSubmenuFromModel(menu_model_, gtk_menu_,
G_CALLBACK(OnMenuItemActivatedThunk),
&block_activation_, this);
Refresh();
}
}
MenuGtk::~MenuGtk() {
gtk_widget_destroy(gtk_menu_);
}
void MenuGtk::Refresh() {
gtk_container_foreach(GTK_CONTAINER(gtk_menu_.get()), SetMenuItemInfo,
&block_activation_);
}
GtkMenu* MenuGtk::GetGtkMenu() {
return GTK_MENU(gtk_menu_.get());
}
void MenuGtk::OnMenuItemActivated(GtkWidget* menu_item) {
if (block_activation_)
return;
ui::MenuModel* model = ModelForMenuItem(GTK_MENU_ITEM(menu_item));
if (!model) {
// There won't be a model for "native" submenus like the "Input Methods"
// context menu. We don't need to handle activation messages for submenus
// anyway, so we can just return here.
DCHECK(gtk_menu_item_get_submenu(GTK_MENU_ITEM(menu_item)));
return;
}
// The activate signal is sent to radio items as they get deselected;
// ignore it in this case.
if (GTK_IS_RADIO_MENU_ITEM(menu_item) &&
!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_item))) {
return;
}
int id;
if (!GetMenuItemID(menu_item, &id))
return;
// The menu item can still be activated by hotkeys even if it is disabled.
if (model->IsEnabledAt(id))
ExecuteCommand(model, id);
}
} // namespace gtkui
} // namespace electron

View File

@@ -0,0 +1,48 @@
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ELECTRON_SHELL_BROWSER_UI_GTK_MENU_GTK_H_
#define ELECTRON_SHELL_BROWSER_UI_GTK_MENU_GTK_H_
#include "base/callback.h"
#include "base/memory/raw_ptr.h"
#include "ui/base/glib/glib_signal.h"
#include "ui/base/glib/scoped_gobject.h"
typedef struct _GtkMenu GtkMenu;
typedef struct _GtkWidget GtkWidget;
namespace ui {
class MenuModel;
}
namespace electron {
namespace gtkui {
class MenuGtk {
public:
explicit MenuGtk(ui::MenuModel* model);
virtual ~MenuGtk();
// Refreshes all the menu item labels and menu item checked/enabled states.
void Refresh();
GtkMenu* GetGtkMenu();
private:
// Callback for when a menu item is activated.
CHROMEG_CALLBACK_0(MenuGtk, void, OnMenuItemActivated, GtkWidget*);
raw_ptr<ui::MenuModel> menu_model_; // not owned
ScopedGObject<GtkWidget> gtk_menu_;
bool block_activation_ = false;
};
} // namespace gtkui
} // namespace electron
#endif // ELECTRON_SHELL_BROWSER_UI_GTK_MENU_GTK_H_

View File

@@ -0,0 +1,68 @@
// Copyright (c) 2023 Microsoft, Inc.
// Copyright (c) 2011 The Chromium Authors.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "shell/browser/ui/status_icon_gtk.h"
#include <gtk/gtk.h>
#include "base/strings/utf_string_conversions.h"
#include "shell/browser/ui/gtk/menu_gtk.h"
#include "shell/browser/ui/gtk_util.h"
#include "ui/gfx/image/image_skia.h"
namespace electron {
StatusIconGtk::StatusIconGtk() : icon_(TakeGObject(gtk_status_icon_new())) {
g_signal_connect(icon_, "activate", G_CALLBACK(OnClickThunk), this);
g_signal_connect(icon_, "popup_menu", G_CALLBACK(OnContextMenuRequestedThunk),
this);
}
StatusIconGtk::~StatusIconGtk() = default;
void StatusIconGtk::SetIcon(const gfx::ImageSkia& image) {
if (image.isNull())
return;
GdkPixbuf* pixbuf = gtk_util::GdkPixbufFromSkBitmap(*image.bitmap());
gtk_status_icon_set_from_pixbuf(icon_, pixbuf);
g_object_unref(pixbuf);
}
void StatusIconGtk::SetToolTip(const std::u16string& tool_tip) {
gtk_status_icon_set_tooltip_text(icon_, base::UTF16ToUTF8(tool_tip).c_str());
}
void StatusIconGtk::UpdatePlatformContextMenu(ui::MenuModel* model) {
if (model)
menu_ = std::make_unique<gtkui::MenuGtk>(model);
}
void StatusIconGtk::RefreshPlatformContextMenu() {
if (menu_)
menu_->Refresh();
}
void StatusIconGtk::OnSetDelegate() {
SetIcon(delegate_->GetImage());
SetToolTip(delegate_->GetToolTip());
UpdatePlatformContextMenu(delegate_->GetMenuModel());
gtk_status_icon_set_visible(icon_, TRUE);
}
void StatusIconGtk::OnClick(GtkStatusIcon* status_icon) {
delegate_->OnClick();
}
void StatusIconGtk::OnContextMenuRequested(GtkStatusIcon* status_icon,
guint button,
guint32 activate_time) {
if (menu_.get()) {
gtk_menu_popup(menu_->GetGtkMenu(), nullptr, nullptr,
gtk_status_icon_position_menu, icon_, button, activate_time);
}
}
} // namespace electron

View File

@@ -0,0 +1,52 @@
// Copyright (c) 2023 Microsoft, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ELECTRON_SHELL_BROWSER_UI_STATUS_ICON_GTK_H_
#define ELECTRON_SHELL_BROWSER_UI_STATUS_ICON_GTK_H_
#include <memory>
#include "ui/base/glib/glib_integers.h"
#include "ui/base/glib/glib_signal.h"
#include "ui/base/glib/scoped_gobject.h"
#include "ui/linux/status_icon_linux.h"
typedef struct _GtkStatusIcon GtkStatusIcon;
namespace electron {
namespace gtkui {
class MenuGtk;
}
class StatusIconGtk : public ui::StatusIconLinux {
public:
StatusIconGtk();
StatusIconGtk(const StatusIconGtk&) = delete;
StatusIconGtk& operator=(const StatusIconGtk&) = delete;
~StatusIconGtk() override;
// ui::StatusIconLinux:
void SetIcon(const gfx::ImageSkia& image) override;
void SetToolTip(const std::u16string& tool_tip) override;
void UpdatePlatformContextMenu(ui::MenuModel* model) override;
void RefreshPlatformContextMenu() override;
void OnSetDelegate() override;
private:
CHROMEG_CALLBACK_0(StatusIconGtk, void, OnClick, GtkStatusIcon*);
CHROMEG_CALLBACK_2(StatusIconGtk,
void,
OnContextMenuRequested,
GtkStatusIcon*,
guint,
guint);
std::unique_ptr<gtkui::MenuGtk> menu_;
ScopedGObject<GtkStatusIcon> icon_;
};
} // namespace electron
#endif // ELECTRON_SHELL_BROWSER_UI_STATUS_ICON_GTK_H_

View File

@@ -1,95 +0,0 @@
// Copyright (c) 2014 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "shell/browser/ui/tray_icon_gtk.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/ui/views/status_icons/status_icon_linux_dbus.h"
#include "ui/gfx/image/image_skia_rep.h"
namespace electron {
namespace {
gfx::ImageSkia GetBestImageRep(const gfx::ImageSkia& image) {
image.EnsureRepsForSupportedScales();
float best_scale = 0.0f;
SkBitmap best_rep;
for (const auto& rep : image.image_reps()) {
if (rep.scale() > best_scale) {
best_scale = rep.scale();
best_rep = rep.GetBitmap();
}
}
// All status icon implementations want the image in pixel coordinates, so use
// a scale factor of 1.
return gfx::ImageSkia::CreateFromBitmap(best_rep, 1.0f);
}
} // namespace
TrayIconGtk::TrayIconGtk()
: status_icon_(new StatusIconLinuxDbus), status_icon_type_(kTypeDbus) {
status_icon_->SetDelegate(this);
}
TrayIconGtk::~TrayIconGtk() = default;
void TrayIconGtk::SetImage(const gfx::Image& image) {
image_ = GetBestImageRep(image.AsImageSkia());
if (status_icon_)
status_icon_->SetIcon(image_);
}
void TrayIconGtk::SetToolTip(const std::string& tool_tip) {
tool_tip_ = base::UTF8ToUTF16(tool_tip);
if (status_icon_)
status_icon_->SetToolTip(tool_tip_);
}
void TrayIconGtk::SetContextMenu(ElectronMenuModel* menu_model) {
menu_model_ = menu_model;
if (status_icon_)
status_icon_->UpdatePlatformContextMenu(menu_model_);
}
const gfx::ImageSkia& TrayIconGtk::GetImage() const {
return image_;
}
const std::u16string& TrayIconGtk::GetToolTip() const {
return tool_tip_;
}
ui::MenuModel* TrayIconGtk::GetMenuModel() const {
return menu_model_;
}
void TrayIconGtk::OnImplInitializationFailed() {
switch (status_icon_type_) {
case kTypeDbus:
status_icon_ = nullptr;
status_icon_type_ = kTypeNone;
return;
case kTypeNone:
NOTREACHED();
}
}
void TrayIconGtk::OnClick() {
NotifyClicked();
}
bool TrayIconGtk::HasClickAction() {
// Returning true will make the tooltip show as an additional context menu
// item, which makes sense in Chrome but not in most Electron apps.
return false;
}
// static
TrayIcon* TrayIcon::Create(absl::optional<UUID> guid) {
return new TrayIconGtk;
}
} // namespace electron

View File

@@ -0,0 +1,115 @@
// Copyright (c) 2014 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "shell/browser/ui/tray_icon_linux.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/ui/views/status_icons/status_icon_linux_dbus.h"
#include "shell/browser/ui/status_icon_gtk.h"
#include "ui/gfx/image/image_skia_rep.h"
namespace electron {
namespace {
gfx::ImageSkia GetBestImageRep(const gfx::ImageSkia& image) {
image.EnsureRepsForSupportedScales();
float best_scale = 0.0f;
SkBitmap best_rep;
for (const auto& rep : image.image_reps()) {
if (rep.scale() > best_scale) {
best_scale = rep.scale();
best_rep = rep.GetBitmap();
}
}
// All status icon implementations want the image in pixel coordinates, so use
// a scale factor of 1.
return gfx::ImageSkia::CreateFromBitmap(best_rep, 1.0f);
}
} // namespace
TrayIconLinux::TrayIconLinux()
: status_icon_dbus_(new StatusIconLinuxDbus),
status_icon_type_(StatusIconType::kDbus) {
status_icon_dbus_->SetDelegate(this);
}
TrayIconLinux::~TrayIconLinux() = default;
void TrayIconLinux::SetImage(const gfx::Image& image) {
image_ = GetBestImageRep(image.AsImageSkia());
if (auto* status_icon = GetStatusIcon())
status_icon->SetIcon(image_);
}
void TrayIconLinux::SetToolTip(const std::string& tool_tip) {
tool_tip_ = base::UTF8ToUTF16(tool_tip);
if (auto* status_icon = GetStatusIcon())
status_icon->SetToolTip(tool_tip_);
}
void TrayIconLinux::SetContextMenu(ElectronMenuModel* menu_model) {
menu_model_ = menu_model;
if (auto* status_icon = GetStatusIcon())
status_icon->UpdatePlatformContextMenu(menu_model_);
}
const gfx::ImageSkia& TrayIconLinux::GetImage() const {
return image_;
}
const std::u16string& TrayIconLinux::GetToolTip() const {
return tool_tip_;
}
ui::MenuModel* TrayIconLinux::GetMenuModel() const {
return menu_model_;
}
void TrayIconLinux::OnImplInitializationFailed() {
switch (status_icon_type_) {
case StatusIconType::kDbus:
status_icon_dbus_.reset();
status_icon_gtk_ = std::make_unique<StatusIconGtk>();
status_icon_type_ = StatusIconType::kGtk;
status_icon_gtk_->SetDelegate(this);
return;
case StatusIconType::kGtk:
status_icon_gtk_.reset();
status_icon_type_ = StatusIconType::kNone;
menu_model_ = nullptr;
return;
case StatusIconType::kNone:
NOTREACHED();
}
}
void TrayIconLinux::OnClick() {
NotifyClicked();
}
bool TrayIconLinux::HasClickAction() {
// Returning true will make the tooltip show as an additional context menu
// item, which makes sense in Chrome but not in most Electron apps.
return false;
}
ui::StatusIconLinux* TrayIconLinux::GetStatusIcon() {
switch (status_icon_type_) {
case StatusIconType::kDbus:
return status_icon_dbus_.get();
case StatusIconType::kGtk:
return status_icon_gtk_.get();
case StatusIconType::kNone:
return nullptr;
}
}
// static
TrayIcon* TrayIcon::Create(absl::optional<UUID> guid) {
return new TrayIconLinux;
}
} // namespace electron

View File

@@ -2,8 +2,8 @@
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ELECTRON_SHELL_BROWSER_UI_TRAY_ICON_GTK_H_
#define ELECTRON_SHELL_BROWSER_UI_TRAY_ICON_GTK_H_
#ifndef ELECTRON_SHELL_BROWSER_UI_TRAY_ICON_LINUX_H_
#define ELECTRON_SHELL_BROWSER_UI_TRAY_ICON_LINUX_H_
#include <memory>
#include <string>
@@ -15,10 +15,12 @@ class StatusIconLinuxDbus;
namespace electron {
class TrayIconGtk : public TrayIcon, public ui::StatusIconLinux::Delegate {
class StatusIconGtk;
class TrayIconLinux : public TrayIcon, public ui::StatusIconLinux::Delegate {
public:
TrayIconGtk();
~TrayIconGtk() override;
TrayIconLinux();
~TrayIconLinux() override;
// TrayIcon:
void SetImage(const gfx::Image& image) override;
@@ -28,20 +30,22 @@ class TrayIconGtk : public TrayIcon, public ui::StatusIconLinux::Delegate {
// ui::StatusIconLinux::Delegate
void OnClick() override;
bool HasClickAction() override;
// The following four methods are only used by StatusIconLinuxDbus, which we
// aren't yet using, so they are given stub implementations.
const gfx::ImageSkia& GetImage() const override;
const std::u16string& GetToolTip() const override;
ui::MenuModel* GetMenuModel() const override;
void OnImplInitializationFailed() override;
private:
enum StatusIconType {
kTypeDbus,
kTypeNone,
enum class StatusIconType {
kDbus,
kGtk,
kNone,
};
scoped_refptr<StatusIconLinuxDbus> status_icon_;
ui::StatusIconLinux* GetStatusIcon();
scoped_refptr<StatusIconLinuxDbus> status_icon_dbus_;
std::unique_ptr<StatusIconGtk> status_icon_gtk_;
StatusIconType status_icon_type_;
gfx::ImageSkia image_;
@@ -51,4 +55,4 @@ class TrayIconGtk : public TrayIcon, public ui::StatusIconLinux::Delegate {
} // namespace electron
#endif // ELECTRON_SHELL_BROWSER_UI_TRAY_ICON_GTK_H_
#endif // ELECTRON_SHELL_BROWSER_UI_TRAY_ICON_LINUX_H_

View File

@@ -144,6 +144,7 @@ v8::Local<v8::Value> Converter<display::Display>::ToV8(
gin_helper::Dictionary dict = gin::Dictionary::CreateEmpty(isolate);
dict.SetHidden("simple", true);
dict.Set("id", val.id());
dict.Set("label", val.label());
dict.Set("bounds", val.bounds());
dict.Set("workArea", val.work_area());
dict.Set("accelerometerSupport", val.accelerometer_support());

View File

@@ -11,7 +11,6 @@
#include "base/path_service.h"
#include "base/strings/string_util.h"
#include "content/common/mac_helpers.h"
#include "ppapi/buildflags/buildflags.h"
namespace electron {
@@ -33,10 +32,8 @@ base::FilePath MainApplicationBundlePath() {
// Up to Contents.
if (!HasMainProcessKey() &&
(base::EndsWith(path.value(), " Helper", base::CompareCase::SENSITIVE) ||
#if BUILDFLAG(ENABLE_PLUGINS)
base::EndsWith(path.value(), content::kMacHelperSuffix_plugin,
base::CompareCase::SENSITIVE) ||
#endif
base::EndsWith(path.value(), content::kMacHelperSuffix_renderer,
base::CompareCase::SENSITIVE) ||
base::EndsWith(path.value(), content::kMacHelperSuffix_gpu,

View File

@@ -24,6 +24,7 @@
#include "base/trace_event/trace_event.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/content_paths.h"
#include "content/public/common/content_switches.h"
#include "electron/buildflags/buildflags.h"
#include "electron/fuses.h"
#include "shell/browser/api/electron_api_app.h"
@@ -43,7 +44,7 @@
#include "shell/common/crash_keys.h"
#endif
#define ELECTRON_BUILTIN_MODULES(V) \
#define ELECTRON_BROWSER_MODULES(V) \
V(electron_browser_app) \
V(electron_browser_auto_updater) \
V(electron_browser_browser_view) \
@@ -76,21 +77,26 @@
V(electron_browser_web_contents_view) \
V(electron_browser_web_frame_main) \
V(electron_browser_web_view_manager) \
V(electron_browser_window) \
V(electron_common_asar) \
V(electron_common_clipboard) \
V(electron_common_command_line) \
V(electron_common_crashpad_support) \
V(electron_common_environment) \
V(electron_common_features) \
V(electron_common_native_image) \
V(electron_common_shell) \
V(electron_common_v8_util) \
V(electron_renderer_context_bridge) \
V(electron_renderer_crash_reporter) \
V(electron_renderer_ipc) \
V(electron_renderer_web_frame) \
V(electron_utility_parent_port)
V(electron_browser_window)
#define ELECTRON_COMMON_MODULES(V) \
V(electron_common_asar) \
V(electron_common_clipboard) \
V(electron_common_command_line) \
V(electron_common_crashpad_support) \
V(electron_common_environment) \
V(electron_common_features) \
V(electron_common_native_image) \
V(electron_common_shell) \
V(electron_common_v8_util)
#define ELECTRON_RENDERER_MODULES(V) \
V(electron_renderer_context_bridge) \
V(electron_renderer_crash_reporter) \
V(electron_renderer_ipc) \
V(electron_renderer_web_frame)
#define ELECTRON_UTILITY_MODULES(V) V(electron_utility_parent_port)
#define ELECTRON_VIEWS_MODULES(V) V(electron_browser_image_view)
@@ -104,7 +110,10 @@
// forward declaration. The definitions are in each module's
// implementation when calling the NODE_LINKED_MODULE_CONTEXT_AWARE.
#define V(modname) void _register_##modname();
ELECTRON_BUILTIN_MODULES(V)
ELECTRON_BROWSER_MODULES(V)
ELECTRON_COMMON_MODULES(V)
ELECTRON_RENDERER_MODULES(V)
ELECTRON_UTILITY_MODULES(V)
#if BUILDFLAG(ENABLE_VIEWS_API)
ELECTRON_VIEWS_MODULES(V)
#endif
@@ -370,13 +379,25 @@ NodeBindings::~NodeBindings() {
void NodeBindings::RegisterBuiltinModules() {
#define V(modname) _register_##modname();
ELECTRON_BUILTIN_MODULES(V)
auto* command_line = base::CommandLine::ForCurrentProcess();
std::string process_type =
command_line->GetSwitchValueASCII(::switches::kProcessType);
if (process_type.empty()) {
ELECTRON_BROWSER_MODULES(V)
#if BUILDFLAG(ENABLE_VIEWS_API)
ELECTRON_VIEWS_MODULES(V)
ELECTRON_VIEWS_MODULES(V)
#endif
#if BUILDFLAG(ENABLE_DESKTOP_CAPTURER)
ELECTRON_DESKTOP_CAPTURER_MODULE(V)
ELECTRON_DESKTOP_CAPTURER_MODULE(V)
#endif
}
ELECTRON_COMMON_MODULES(V)
if (process_type == ::switches::kRendererProcess) {
ELECTRON_RENDERER_MODULES(V)
}
if (process_type == ::switches::kUtilityProcess) {
ELECTRON_UTILITY_MODULES(V)
}
#if DCHECK_IS_ON()
ELECTRON_TESTING_MODULE(V)
#endif

View File

@@ -39,6 +39,8 @@ const char kOverlaySymbolColor[] = "symbolColor";
// The custom height for Window Controls Overlay.
const char kOverlayHeight[] = "height";
// whether to keep the window out of mission control
const char kHiddenInMissionControl[] = "hiddenInMissionControl";
// Whether the window should show in taskbar.
const char kSkipTaskbar[] = "skipTaskbar";

View File

@@ -30,6 +30,7 @@ extern const char kMinimizable[];
extern const char kMaximizable[];
extern const char kFullScreenable[];
extern const char kClosable[];
extern const char kHiddenInMissionControl[];
extern const char kFullscreen[];
extern const char kSkipTaskbar[];
extern const char kKiosk[];

View File

@@ -96,7 +96,7 @@ void ElectronRendererClient::DidCreateScriptContext(
env->options()->force_context_aware = true;
// We do not want to crash the renderer process on unhandled rejections.
env->options()->unhandled_rejections = "warn";
env->options()->unhandled_rejections = "warn-with-error-code";
environments_.insert(env);

View File

@@ -85,8 +85,7 @@ ElectronContentUtilityClient::ElectronContentUtilityClient() = default;
ElectronContentUtilityClient::~ElectronContentUtilityClient() = default;
// The guts of this came from the chromium implementation
// https://cs.chromium.org/chromium/src/chrome/utility/
// chrome_content_utility_client.cc?sq=package:chromium&dr=CSs&g=0&l=142
// https://source.chromium.org/chromium/chromium/src/+/main:chrome/utility/chrome_content_utility_client.cc
void ElectronContentUtilityClient::ExposeInterfacesToBrowser(
mojo::BinderMap* binders) {
#if BUILDFLAG(IS_WIN)

View File

@@ -3977,6 +3977,24 @@ describe('BrowserWindow module', () => {
w.hide();
w.show();
});
// TODO(zcbenz):
// This test does not run on Linux CI. See:
// https://github.com/electron/electron/issues/28699
ifit(process.platform === 'linux' && !process.env.CI)('should bring a minimized maximized window back to maximized state', async () => {
const w = new BrowserWindow({});
const maximize = emittedOnce(w, 'maximize');
w.maximize();
await maximize;
const minimize = emittedOnce(w, 'minimize');
w.minimize();
await minimize;
expect(w.isMaximized()).to.equal(false);
const restore = emittedOnce(w, 'restore');
w.restore();
await restore;
expect(w.isMaximized()).to.equal(true);
});
});
// TODO(dsanders11): Enable once maximize event works on Linux again on CI
@@ -4774,6 +4792,24 @@ describe('BrowserWindow module', () => {
});
});
ifdescribe(process.platform === 'darwin')('isHiddenInMissionControl state', () => {
it('with functions', () => {
it('can be set with ignoreMissionControl constructor option', () => {
const w = new BrowserWindow({ show: false, hiddenInMissionControl: true });
expect(w.isHiddenInMissionControl()).to.be.true('isHiddenInMissionControl');
});
it('can be changed', () => {
const w = new BrowserWindow({ show: false });
expect(w.isHiddenInMissionControl()).to.be.false('isHiddenInMissionControl');
w.setHiddenInMissionControl(true);
expect(w.isHiddenInMissionControl()).to.be.true('isHiddenInMissionControl');
w.setHiddenInMissionControl(false);
expect(w.isHiddenInMissionControl()).to.be.false('isHiddenInMissionControl');
});
});
});
// fullscreen events are dispatched eagerly and twiddling things too fast can confuse poor Electron
ifdescribe(process.platform === 'darwin')('kiosk state', () => {
@@ -5166,6 +5202,22 @@ describe('BrowserWindow module', () => {
w.closeFilePreview();
}).to.not.throw();
});
it('should not call BrowserWindow show event', async () => {
const w = new BrowserWindow({ show: false });
const shown = emittedOnce(w, 'show');
w.show();
await shown;
let showCalled = false;
w.on('show', () => {
showCalled = true;
});
w.previewFile(__filename);
await delay(500);
expect(showCalled).to.equal(false, 'should not have called show twice');
});
});
// TODO (jkleinsc) renable these tests on mas arm64

View File

@@ -80,7 +80,7 @@ describe('dialog module', () => {
afterEach(closeAllWindows);
// parentless message boxes are synchronous on macOS
// dangling message boxes on windows cause a DCHECK: https://cs.chromium.org/chromium/src/base/win/message_window.cc?l=68&rcl=7faa4bf236a866d007dc5672c9ce42660e67a6a6
// dangling message boxes on windows cause a DCHECK: https://source.chromium.org/chromium/chromium/src/+/main:base/win/message_window.cc;drc=7faa4bf236a866d007dc5672c9ce42660e67a6a6;l=68
ifit(process.platform !== 'darwin' && process.platform !== 'win32')('should not throw for a parentless message box', () => {
expect(() => {
dialog.showMessageBox({ message: 'i am message' });

View File

@@ -796,6 +796,81 @@ describe('net module', () => {
});
}
it('should be able correctly filter out cookies that are secure', async () => {
const sess = session.fromPartition(`cookie-tests-${Math.random()}`);
await Promise.all([
sess.cookies.set({
url: 'https://electronjs.org',
domain: 'electronjs.org',
name: 'cookie1',
value: '1',
secure: true
}),
sess.cookies.set({
url: 'https://electronjs.org',
domain: 'electronjs.org',
name: 'cookie2',
value: '2',
secure: false
})
]);
const secureCookies = await sess.cookies.get({
secure: true
});
expect(secureCookies).to.have.lengthOf(1);
expect(secureCookies[0].name).to.equal('cookie1');
const cookies = await sess.cookies.get({
secure: false
});
expect(cookies).to.have.lengthOf(1);
expect(cookies[0].name).to.equal('cookie2');
});
it('throws when an invalid domain is passed', async () => {
const sess = session.fromPartition(`cookie-tests-${Math.random()}`);
await expect(sess.cookies.set({
url: 'https://electronjs.org',
domain: 'wssss.iamabaddomain.fun',
name: 'cookie1'
})).to.eventually.be.rejectedWith(/Failed to set cookie with an invalid domain attribute/);
});
it('should be able correctly filter out cookies that are session', async () => {
const sess = session.fromPartition(`cookie-tests-${Math.random()}`);
await Promise.all([
sess.cookies.set({
url: 'https://electronjs.org',
domain: 'electronjs.org',
name: 'cookie1',
value: '1'
}),
sess.cookies.set({
url: 'https://electronjs.org',
domain: 'electronjs.org',
name: 'cookie2',
value: '2',
expirationDate: Math.round(Date.now() / 1000) + 10000
})
]);
const sessionCookies = await sess.cookies.get({
session: true
});
expect(sessionCookies).to.have.lengthOf(1);
expect(sessionCookies[0].name).to.equal('cookie1');
const cookies = await sess.cookies.get({
session: false
});
expect(cookies).to.have.lengthOf(1);
expect(cookies[0].name).to.equal('cookie2');
});
describe('when {"credentials":"omit"}', () => {
it('should not send cookies');
it('should not store cookies');

View File

@@ -34,6 +34,7 @@ describe('screen module', () => {
expect(display).to.have.property('scaleFactor').that.is.a('number');
expect(display).to.have.property('id').that.is.a('number');
expect(display).to.have.property('label').that.is.a('string');
expect(display).to.have.property('rotation').that.is.a('number');
expect(display).to.have.property('touchSupport').that.is.a('string');
expect(display).to.have.property('accelerometerSupport').that.is.a('string');

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