Compare commits

...

173 Commits

Author SHA1 Message Date
Electron Bot
c4bd63b420 Bump v8.5.0 2020-08-05 10:28:00 -07:00
trop[bot]
6acb443b91 fix: duplicate suspend/resume events (#24844)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-08-05 10:25:23 -07:00
Robo
d3e5b791a5 fix: crash when navigating from a page with webview that has inherited zoom level (#24757) (#24766) 2020-08-03 15:55:24 -04:00
trop[bot]
96bd258b0f fix: disable rosetta as Electron does not run under rosetta (#24744)
Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
2020-07-28 10:56:46 -07:00
Electron Bot
23d0d409b4 Bump v8.4.1 2020-07-21 09:26:13 -07:00
Shelley Vohr
ad94c7472e fix: broken --trace-sync-io flag in Node.js (#24649) 2020-07-20 14:11:11 -07:00
Shelley Vohr
f3df14c7ae fix: Node.js cpu and heap profiling (#24542)
* fix: Node.js cpu and heap profiling

* fix: Node.js cpu and heap profiling

* chore: enable more now-working Node.js specs

* Replace disabled tests
2020-07-20 10:26:11 -07:00
Cheng Zhao
bd1c7487ba chore: cherry-pick fix from chromium issue 1074340 (#24622) 2020-07-20 09:57:25 +09:00
Cheng Zhao
bc4d3dc578 chore: cherry-pick fix from chromium issue 1073409 (#24626) 2020-07-18 09:47:09 +09:00
Cheng Zhao
05ef36db59 chore: cherry-pick fix from chromium issue 978779 (#24618) 2020-07-18 09:46:08 +09:00
Cheng Zhao
b852f1de13 chore: cherry-pick fix from chromium issue 986051 (#24615) 2020-07-18 09:45:27 +09:00
Cheng Zhao
3e36f7a245 chore: cherry-pick fix from chromium issue 1065731 (#24595) 2020-07-17 12:52:33 +09:00
Cheng Zhao
d623e7cd44 chore: cherry-pick fix from chromium issue 1080481 (#24587) 2020-07-17 08:47:53 +09:00
Cheng Zhao
42435fcad8 chore: cherry-pick fix from chromium issue 1081722 (#24585) 2020-07-17 08:46:53 +09:00
Cheng Zhao
bd90898181 chore: cherry-pick fix from chromium issue 1076703 (#24562) 2020-07-16 18:36:35 +09:00
Cheng Zhao
c20701b600 chore: cherry-pick fix from chromium issue 1090543 (#24568) 2020-07-16 15:08:54 +09:00
Shelley Vohr
8272ea5b5f fix: use default NSVisualEffectState enum case (#24546) 2020-07-15 21:01:14 -07:00
Cheng Zhao
6317ef75a1 chore: cherry-pick fix from chromium issue 1074317 (#24559) 2020-07-16 12:48:01 +09:00
Cheng Zhao
e5cb1872f5 chore: cherry-pick fix from chromium issue 1091404 (#24570) 2020-07-16 09:25:42 +09:00
Cheng Zhao
25e3fadd56 chore: cherry-pick fix from chromium issue 1084820 (#24565) 2020-07-16 09:02:15 +09:00
Cheng Zhao
6adf6b8b7d chore: cherry-pick fix from chromium issue 1065122 (#24556) 2020-07-16 08:12:33 +09:00
trop[bot]
d67ff0fe0e docs: fix incorrect formatting in browser docs. (#24515)
Address incorrect typing for isEnabled. The root cause of this was due
to missing backticks which caused the docs parser to think that the
return type of the `isEnabled` function was null, where it was supposed
to be a boolean type.

The side effect of this was that the generated typescript typings were
incorrect for this function.

Fixes #24409

Co-authored-by: Sam Saccone <samccone@gmail.com>
2020-07-13 08:56:51 -07:00
Robo
49e63948b7 fix: unresponsive window when reloading with breakpoint in devtools (#24490)
* fix: unresponsive window when reloading with breakpoint in devtools

Backports https://chromium-review.googlesource.com/c/v8/v8/+/1924366

* update patches

Co-authored-by: Electron Bot <anonymous@electronjs.org>
2020-07-13 11:55:00 -04:00
Robo
8dae8da778 fix: crash when opening in remote X server (#24491)
Backports
https://chromium-review.googlesource.com/c/chromium/src/+/1980971
https://chromium-review.googlesource.com/c/chromium/src/+/2062900
2020-07-13 09:58:32 -04:00
trop[bot]
b762563257 fix: uv_walk crash on web worker close (#24463)
* fix: uv_walk crash on web worker close

* Use DCHECK_EQ

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-07-10 13:58:07 -07:00
trop[bot]
9ccf1b569b fix: clipboard.readBuffer returning empty value (#24468)
Co-authored-by: Deepak Mohan <hop2deep@gmail.com>
2020-07-08 17:24:24 -07:00
Samuel Attard
653bb602e2 build: remove bad 'when' clause from CI config (#24466) 2020-07-08 14:57:24 -07:00
Electron Bot
94a5b304d0 Bump v8.4.0 2020-07-07 09:05:07 -07:00
Milan Burda
a22384c9ff feat: implement systemPreferences.getMediaAccessStatus() on Windows (#24313) 2020-07-07 09:03:55 -07:00
Andrey Belenko
96eeddd46b chore: backport Chromium fixes (#24419)
* Backport 1063177 (https://chromium-review.googlesource.com/c/chromium/src/+/2111393/)

* Backport 1019161 (https://chromium-review.googlesource.com/c/chromium/src/+/2125690)

* update patches

Co-authored-by: Andrey Belenko <anbelen@microsoft.com>
Co-authored-by: Electron Bot <anonymous@electronjs.org>
2020-07-06 12:41:13 -07:00
Robo
7a776198db feat: expose sessionId in debugger module (#24399) 2020-07-06 12:37:24 -07:00
trop[bot]
93a9512ce1 fix: intermittent 100% CPU usage on macOS (#24414)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-07-06 09:02:08 -07:00
trop[bot]
843dd5c33f chore: use node_bindings loop for clarity (#24417)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-07-03 18:47:23 -07:00
trop[bot]
b812e78f51 feat: add app render-process-gone event (#24314)
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2020-07-03 16:35:37 -07:00
trop[bot]
b080dab28c fix: remove same-tag notifications before showing new ones (#24405)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-07-03 09:20:24 -07:00
trop[bot]
c451a90cfb feat: add new render-process-gone event (#24308)
Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
2020-07-03 07:21:11 -07:00
Milan Burda
b32ffe0ab2 feat: add tracing info to WebContents IPC methods (#24307) 2020-07-01 16:43:17 -07:00
trop[bot]
adfc0f55bc fix: macOS modal focus (#24353)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-06-29 15:49:29 -07:00
trop[bot]
6852bfb86e feat: support suspend/resume on macOS (#24295)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-06-29 10:42:14 -07:00
trop[bot]
6d3e56d70f feat: support suspend/resume on Windows (#24282)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-06-29 09:07:21 -07:00
Milan Burda
f70161856c tests: do not check expectations inside IPC handlers (#24310)
Co-authored-by: Milan Burda <miburda@microsoft.com>
2020-06-26 13:15:48 -07:00
Electron Bot
736749522b Bump v8.3.4 2020-06-24 14:00:11 -07:00
Jeremy Rose
9964e3f389 fix: backport nodejs/node#33682 and nodejs/node#30195 (#24268) 2020-06-24 00:58:51 -07:00
Shelley Vohr
8c4c4fb4f0 fix: emit click events with tray context menu (#24239) 2020-06-23 08:57:51 -07:00
trop[bot]
0565d22597 fix: isTrustedSender() in test-app (#24231)
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2020-06-22 08:24:26 -07:00
Electron Bot
87fd06bc96 Bump v8.3.3 2020-06-18 09:52:13 -07:00
Cheng Zhao
4079d60021 fix: do not use CONTEXT_MENU flag for tray menu (reland) (#24194) 2020-06-18 09:03:02 -07:00
Cheng Zhao
6cc75d9f92 fix: correctly handle nexttick scheduling in stream reads (#24133)
Co-authored-by: Paul Frazee <pfrazee@gmail.com>
2020-06-18 01:25:13 -07:00
trop[bot]
af5be47aa7 fix: make pasteandmatchstyle accelerator OS specific (#24184)
Co-authored-by: Elena Topaka <el1topa@gmail.com>
2020-06-17 21:48:07 -07:00
Pedro Pontes
b2454eeb52 chore: cherry-pick eac3d9283d11 from chromium (#24152)
* chore: cherry-pick eac3d9283d11 from chromium

* update patches

Co-authored-by: Electron Bot <anonymous@electronjs.org>
Co-authored-by: Robo <hop2deep@gmail.com>
2020-06-17 21:47:04 -07:00
Robo
1ee98b4a73 fix: let Node.js perform microtask checkpoint in the main process (#24131) (#24180)
* fix: let Node.js perform microtask checkpoint in the main process

* fix: don't specify v8::MicrotasksScope for explicit policy

* fix: remove checkpoint from some call-sites

We already perform checkpoint at the end of a task,
either through MicrotaskRunner or through NodeBindings.
There isn't a need to add them again when calling into JS
except when dealing with promises.

* fix: remove checkpoint from some call-sites

We already perform checkpoint at the end of a task,
either through MicrotaskRunner or through NodeBindings.
There isn't a need to add them again when calling into JS
except when dealing with promises.

* fix incorrect specs

* default constructor arguments are considered for explicit mark

* add regression spec
2020-06-17 16:00:41 -07:00
Robo
e74a402976 chore: cherry-pick c20afc96e36f57 from chromium (#24181) 2020-06-17 16:00:10 -07:00
trop[bot]
8e5a88799c docs: fix MenuItem click handler type (#24176)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-06-17 11:30:14 -07:00
trop[bot]
0b846b2f13 chore: cherry-pick bc4df9dd11e609e from chromium (#24084)
* chore: cherry-pick bc4df9dd11e609e from chromium

* chore: update patches

Co-authored-by: deepak1556 <hop2deep@gmail.com>
2020-06-17 00:49:49 -07:00
trop[bot]
25539dcb73 fix: volume key globalShortcut deregistration (#24154)
Co-authored-by: Aleksei Kuzmin <alkuzmin@microsoft.com>
2020-06-16 13:52:39 -07:00
trop[bot]
2a4aaa9661 fix: emit 'shutdown' outside -[NSApplication terminate:] (#24140)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-06-15 21:02:56 -07:00
trop[bot]
793da44151 fix: handle non-client area pointer events from pen on Win10 (#24101) 2020-06-15 18:58:05 -07:00
trop[bot]
4c28b23b06 fix: fs.readdir should support withFileTypes (#24107)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-06-16 10:56:09 +09:00
Electron Bot
952603d9ae Bump v8.3.2 2020-06-15 09:05:09 -07:00
Jeremy Rose
32b45e7783 fix: throw instead of crash when using ipcRenderer after context released (#23979)
* fix: throw instead of crash when using ipcRenderer after context released (#23917)

* meh

* Update api-ipc-renderer-spec.ts
2020-06-13 08:28:17 -07:00
trop[bot]
514c1e6d4b fix: showing certificate dialog with no window (#24120)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-06-13 08:19:30 -07:00
trop[bot]
67b04b4040 chore: cherry-pick 867fcd45891e from chromium (#24088)
https://chromium-review.googlesource.com/c/chromium/src/+/2134037

Co-authored-by: deepak1556 <hop2deep@gmail.com>
2020-06-12 12:13:29 -07:00
Samuel Attard
415387cc2c Revert "fix: do not use CONTEXT_MENU flag for tray menu (#23886)" (#24079)
This reverts commit 91d1bd651e.
2020-06-11 11:28:02 -07:00
Electron Bot
0826770b20 Revert "Bump v8.3.2"
This reverts commit c2e22abf08.
2020-06-11 09:42:29 -07:00
Electron Bot
c2e22abf08 Bump v8.3.2 2020-06-11 09:24:35 -07:00
Milan Burda
9c28c8f637 chore: revert deprecated WebContents properties (#24071) 2020-06-11 09:16:33 -07:00
Milan Burda
478d405d42 chore: support props/fns for BrowserWindow (#24074) 2020-06-11 09:14:47 -07:00
Milan Burda
0b616b3e2e chore: more modules to dual prop/fn support (#22734) (#24075)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
2020-06-11 11:06:54 -05:00
Milan Burda
49711d12f8 chore: update app module property support (#22747) (#24072)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-06-11 08:56:28 -07:00
Cheng Zhao
fe56f1dda6 fix: add .paks for media-internals and webrtc-internals pages (#24063)
Co-authored-by: Gellert Hegyi <gellert.hegyi@around.co>
2020-06-11 08:38:49 -07:00
Shelley Vohr
f10c8e6dd5 chore: roll latest Node.js security release (#23953) 2020-06-09 11:55:34 -04:00
Charles Kerr
27c1fc87e3 fix: add missing isComposing KeyboardEvent property (#24015) 2020-06-08 17:45:57 -07:00
Shelley Vohr
be08ff1665 fix: nativeImage remote serialization (#23797)
* fix: nativeImage remote serialization (#23543)

We weren't serializing nativeImages properly in the remote module, leading to gin conversion errors when trying to, for example, create a new context menu in the renderer with icons using nativeImage. This fixes that by adding a new special case to handle them.

* refactor: correctly serialize nativeImage/buffer with typeUtils (#23666)

* refactor: correctly serialize nativeImage/buffer with typeUtils

* test: add serialization specs

* fix: construct from dataURL

* test: test for dataURL specificity

* refactor: use typeutils for nativeImage serialization

* fix: ensure nativeImage serialization main->renderer

* chore: fix FTBFS

Co-authored-by: Charles Kerr <charles@charleskerr.com>
2020-06-08 12:08:54 -07:00
Charles Kerr
547e50c699 docs: errors in isolated world are not dispatched (#24016)
* docs: errors in isolated world are not dispatched

* empty commit

* fix manual oops

Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2020-06-08 14:51:39 -04:00
Shelley Vohr
a06170648c fix: compensate for lazy-loaded circular deps (#23955) 2020-06-08 10:09:40 -07:00
Milan Burda
88fdf8ccf5 fix: use acceptLanguages argument in session.setUserAgent() (#23944) (#23963)
Co-authored-by: Milan Burda <miburda@microsoft.com>
2020-06-08 09:19:32 -07:00
trop[bot]
d12be5d392 feat: add V8CacheOptions webpreference (#23869)
* feat: add V8CacheOptions webpreference

* address review comments

Co-authored-by: deepak1556 <hop2deep@gmail.com>
2020-06-08 11:07:44 -05:00
Cheng Zhao
e62cd6a5fa fix: read GTK dark theme setting on Linux (#23965) 2020-06-04 19:33:53 -07:00
Shelley Vohr
c412f7ddf1 fix: handle asynchronous URL loading in bw proxy (#23947) 2020-06-03 15:54:43 -07:00
Shelley Vohr
0afec38c81 fix: volume key globalShortcut registration (#23948) 2020-06-03 13:31:18 -07:00
Robo
38f0a8e85b fix: default to NTLM v2 in the network service for POSIX platforms (#23933)
* fix: default to NTLM v2 in the network service for POSIX platforms

* chore: update patch
2020-06-03 11:48:37 -07:00
Shelley Vohr
0aa7b7f712 test: skip 'handles Promise timeouts correctly' when ELECTRON_RUN_AS_NODE is disabled (#23949) 2020-06-03 14:18:07 -04:00
trop[bot]
23bd9166d7 fix: restore original GTK/appindicator implementation of tray icons (#23927)
Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
2020-06-03 11:08:04 -07:00
Charles Kerr
c374f20fd1 fix: don't run environment bootstrapper (#23924)
* fix: don't prepareMainExecution twice

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-06-03 10:12:29 -05:00
trop[bot]
b5839f42a2 fix: correctly support the --inspect-brk-node flag (#23919)
Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
2020-06-03 17:01:26 +09:00
trop[bot]
2dcfefa577 build: make electron renderer init scripts profilable (#23914)
The devtools profiler is not attached at the point we run out init scripts (or our apps preload scripts), we do not really want to change when we run these init scripts but for when a dev is doing performance work it makes sense to give them an option to make the devtools profiler actually work on both our init scripts and their preload script.  This PR adds that logic behind an environment variable ELECTRON_PROFILE_INIT_SCRIPTS.

Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
2020-06-02 12:28:27 -07:00
trop[bot]
b045ee77af fix: add patch to prevent crash during frame swap with ctx isolation enabled (#23894)
* fix: add patch to prevent crash during frame swap with ctx isolation enabled

* Update .patches

* chore: update patches

Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
Co-authored-by: Samuel Attard <sattard@slack-corp.com>
2020-06-02 10:54:35 -07:00
Biru Mohanathas
32c2736c07 fix: Make the --disable-color-correct-rendering switch work again (8-x-y) (#23827)
Backport of #23787

See that PR for details.

Notes: Fix disabling color correct rendering with `--disable-color-correct-rendering`
2020-06-02 13:50:35 -04:00
Charles Kerr
91d1bd651e fix: do not use CONTEXT_MENU flag for tray menu (#23886) 2020-06-02 11:11:35 +09:00
Electron Bot
c8177f8418 Bump v8.3.1 2020-06-01 09:32:39 -07:00
trop[bot]
b8c086613f fix: weakly reference MenuModel from MenuController (#23807)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-05-28 09:47:47 -07:00
Alexey Kuzmin
2e80a2e447 test: refactor how spec files are collected (#23815)
(cherry picked from commit 3a7775fa73)
2020-05-28 09:41:27 -07:00
Pedro Pontes
936a1659f6 chore: cherry-pick d795ac1209c8 and 919dd0c1244a from chromium (#23788)
* Onstate handler is allowed to close a PeerConnection.

Backports the 2-part fix to https://crbug.com/1068084

===

Avoid nullptr dereference in RTCPeerConnectionHandler

Bug: 1071327
Change-Id: Icf4189905dc5c95854b5af4b3e5e25e0607dd39e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2153325
Reviewed-by: Harald Alvestrand <hta@chromium.org>
Commit-Queue: Dan McArdle <dmcardle@chromium.org>
Cr-Commit-Position: refs/heads/master@{#759775}

===

Onstate handler is allowed to close a PeerConnection.

Bug: chromium:1068084
Change-Id: Icd3f70b6784ac22ef4e3bc1c99233f51145a917f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2146542
Commit-Queue: Harald Alvestrand <hta@chromium.org>
Reviewed-by: Guido Urdaneta <guidou@chromium.org>
Cr-Commit-Position: refs/heads/master@{#759242}

===

* update patches

Co-authored-by: Electron Bot <anonymous@electronjs.org>
2020-05-28 11:34:49 -04:00
Cheng Zhao
d7289cbb55 Revert "fix: trigger activate event when app is activated via app switcher (#23772)" (#23820)
This reverts commit e671c2c053.
2020-05-28 09:01:37 -04:00
trop[bot]
aab0c66817 fix: pass correct buffer length (#23799)
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2020-05-27 14:09:35 -07:00
trop[bot]
e671c2c053 fix: trigger activate event when app is activated via app switcher (#23772)
When application is activated thru macOS app switcher (cmd+tab) the
App's activate event is note emitted. The reason is that
`applicationShouldHandleReopen:hasVisibleWindows:` is sent only when app
is activated via Dock. Using `applicationDidBecomeActive:` is handling
all cases properly.

Co-authored-by: Lukas Weber <luweber@microsoft.com>
2020-05-27 09:52:20 +09:00
Pedro Pontes
c7778a8f2f chore: cherry-pick d4ddf645c3ca from chromium (#23747)
* chore: cherry-pick d4ddf645c3ca from chromium

* update patches

* [turbofan] Turn some DCHECKs into CHECKs in Schedule methods

Bug: chromium:1076708
Change-Id: I7f065791310606e11fe89936a36f0fe7cb0d38e7
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2182639
Auto-Submit: Georg Neis <neis@chromium.org>
Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#67576}

Co-authored-by: Electron Bot <anonymous@electronjs.org>
2020-05-25 12:02:08 -07:00
trop[bot]
c35803aee1 fix: trigger about panel for about role on on win (#23714)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-05-21 21:40:09 -04:00
LuoJinghua
9f2fc5d72c net: Don't ignore the referer header in net.request (#23688) 2020-05-21 20:24:28 -04:00
trop[bot]
a65fe57342 fix: make sure hunspell file is not destroyed in UI thread (#23658)
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2020-05-21 15:40:03 -07:00
Alexey Kuzmin
473219bfbe test: call "expect()" on a correct call stack (#23697)
* test: call "expect()" on a correct call stack

(cherry picked from commit 33d6a99d40)

* fixup! test: call "expect()" on a correct call stack
2020-05-21 15:38:42 -07:00
trop[bot]
a8196fbc18 refactor: improve MoveItemToTrash error description (#23629)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-05-18 11:11:05 -04:00
Alexey Kuzmin
6b8ca86459 test: fix conditions for some tests (#23489) (#23607) 2020-05-18 10:12:38 +09:00
Samuel Attard
7290d77cdc refactor: remove the RenderFrameFunctionStore and use privates to memory manage (#23592) (#23612) 2020-05-15 16:33:48 -07:00
Electron Bot
426d45cd85 Bump v8.3.0 2020-05-14 17:33:43 -07:00
trop[bot]
79298d37cd build: remove unused header from a patch (#23591)
It can cause build failures because the header is generated
and there's no explicit dependency on a target that creates it.

Co-authored-by: Aleksei Kuzmin <alkuzmin@microsoft.com>
2020-05-14 20:32:29 -04:00
Robo
2a44b1a20f feat: add enableWebSQL webpreference (#23311) (#23581) 2020-05-14 20:31:45 -04:00
Charles Kerr
6f331e4f6a feat: add force option to app.focus() (#23574) 2020-05-14 17:30:52 -07:00
Andrey Belenko
dc71541641 chore: cherry-pick 7101418f85a0 from chromium (#23532)
* chore: cherry-pick 7101418f85a0 from chromium

* update patches

Co-authored-by: Electron Bot <anonymous@electronjs.org>
Co-authored-by: Andrey Belenko <anbelen@microsoft.com>
2020-05-14 11:21:32 -04:00
Pedro Pontes
a4de4793dd chore: cherry-pick 1288aa12369e from angle (#23561) 2020-05-14 11:08:16 -04:00
trop[bot]
f7509d590c fix: leave behind the unmodified XDG_CURRENT_DESKTOP variable (#23552)
Co-authored-by: Samuel Attard <sattard@slack-corp.com>
2020-05-14 10:43:51 -04:00
Shelley Vohr
42ab97f905 fix: run Node.js at-exit callbacks in renderer proc (#23564) 2020-05-14 10:08:34 -04:00
Andrey Belenko
faf2871efe chore: cherry-pick 86c02c5dcd37 from chromium (#23528)
Co-authored-by: Andrey Belenko <anbelen@microsoft.com>
2020-05-13 15:59:10 -07:00
Cheng Zhao
ea4e92f64d fix: do not destroy thread in UI thread (#23550) 2020-05-13 10:01:22 -07:00
trop[bot]
15d792aded build: use correct v8_context_snapshot_generator in mksnapshot zip (#23542)
Co-authored-by: John Kleinschmidt <jkleinsc@github.com>
2020-05-13 09:39:56 -04:00
Cheng Zhao
70f05a1579 chore: cherry-pick e89fe66d0473 from Chromium (#23514) 2020-05-13 17:07:54 +09:00
Cheng Zhao
2d40fad79e chore: cherry-pick 67864c214770 from Chromium (#23517) 2020-05-13 14:43:22 +09:00
Pedro Pontes
edabc96e75 chore: cherry-pick 38990b7d56e6 from chromium (#23504)
* chore: cherry-pick 38990b7d56e6 from chromium

* update patches

Co-authored-by: Electron Bot <anonymous@electronjs.org>
2020-05-13 09:07:40 +09:00
Jeremy Apthorp
4a45196ff1 chore: cherry-pick 45b8c2bb07d2 from v8 (#23465) 2020-05-08 11:42:27 -07:00
Jeremy Apthorp
0bd661bd99 chore: cherry-pick 826a4af58b3d from chromium (#23462) 2020-05-08 11:24:41 -07:00
Jeremy Apthorp
b9e709039e chore: cherry-pick 686d1bfbcb8f from chromium (#23456) 2020-05-08 11:16:26 -07:00
trop[bot]
c63430c5d0 fix: multiple extension filters on macOS (#23449)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-05-07 11:57:40 -07:00
Charles Kerr
60bcf42edf fix: respect system language preferences on Windows & macOS (#23407)
* fix: respect system language preferences on Win/macOS (#23247)

This commit fixes https://github.com/electron/electron/issues/18829

Previously the full preferences set to OS was not given to Chromium.

Also, this commit improves fallback font selection for CJK text.
Chromium uses browser languages to determine fallback fonts on Windows,
especially kanji/han characters in CJK.

For instance, when user sets 'en-US, ja-JP' to Accept-Language,
while Chromium chooses Japanese font for kanji text, but Electron
chooses Chinese font.  This is because only the first language was given
to Accept-Language on Electron.

This patch is based on https://github.com/electron/electron/pull/15532

Co-authored-by: Nitish Sakhawalkar <nitsakh@icloud.com>
Co-authored-by: Kasumi Hanazuki <kasumi@rollingapple.net>

Co-authored-by: Nitish Sakhawalkar <nitsakh@icloud.com>
Co-authored-by: Kasumi Hanazuki <kasumi@rollingapple.net>

* fix: remove unintentionally-committed code

Some excess code was accidentally included in the last commit's cherry-pick.

* chore: fix extraneous #include found by lint

* fix: correct another manual backport error :P

Co-authored-by: Sorah Fukumori <her@sorah.jp>
Co-authored-by: Nitish Sakhawalkar <nitsakh@icloud.com>
Co-authored-by: Kasumi Hanazuki <kasumi@rollingapple.net>
2020-05-05 09:35:51 -07:00
Shelley Vohr
d5f9654c12 refactor: make passing empty template no-op in setMenu (#23402) 2020-05-04 20:03:36 -07:00
trop[bot]
d2fb214a54 docs: event.newGuest for new-window in WebContents and webContents in BrowsweWindow's constructor (#23355)
* docs: `newGuest` in `WebContents` and `webContents` in `BrowsweWindow`

According to the example codes in the documentation of `new-window`
event in `WebContents`, `webContents` in `BrowsweWindow` constructor
options and `newGuest` in `event` argument of `new-window` handler are
both existing but documented. This patch is for adding the related
documentations. Also, it provides typescript-definitations for these
two properties.

* Remove the documnent of `webContents` in BrowserWindow constructor option.

Co-authored-by: Sean Lee <sean.l@canva.com>
2020-05-04 12:41:37 -07:00
Robo
6294f811a7 fix: hold browser_context instead of render_frame_host to fix lifetime issues (#23271) (#23396)
Co-authored-by: Paul Frazee <pfrazee@gmail.com>
2020-05-04 10:16:56 -07:00
Robo
30ae6f45a4 fix: ensure guest-embedder map is updated when webview is removed (#23342) (#23397)
There are use cases of webview where the container holding the webview is not
actually destroyed first, instead just webview gets removed from DOM, in such
situations the browser process map is not updated accordingly and holds reference
to stale guest contents, and any window operations like scroll, resize or keyboard
events that has to chain through browser embedder will lead to UAF crash.

Ref: https://github.com/microsoft/vscode/issues/92420
2020-05-04 08:30:28 -07:00
trop[bot]
60ef8ac58d ci: make sure msedge isn't running at end of woa test (#23358)
Co-authored-by: John Kleinschmidt <jkleinsc@github.com>
2020-04-30 15:12:53 -04:00
Electron Bot
6c42564337 Bump v8.2.5 2020-04-30 10:03:43 -07:00
Samuel Attard
479fc57cef fix: do not leak IPC or context bridge promises (#23321) (#23339) 2020-04-30 09:51:51 -07:00
Samuel Attard
b2fb14fd48 fix: backport fix for zero-size pixels in blink (#23336) 2020-04-30 08:26:48 -07:00
Electron Bot
d8f90444aa Bump v8.2.4 2020-04-27 18:07:21 -07:00
Samuel Attard
045331666c refactor: port window-setup to use ctx bridge instead of being run in the main world (#23302)
* refactor: port parts of window-setup to use ctx bridge instead of being run in the main world (#23194)

* refactor: port parts of window-setup to use ctx bridge instead of being run in the main world

* chore: update ctx bridge specs for new base numbers

* refactor: port window.open and window.opener to use ctx bridge instead of hole punching (#23235)

* refactor: port window.open and window.opener to use ctx bridge instead of hole punching

* refactor: only run the isolated init bundle when webview is enabled

* s/gin/mate

* fix: do not inject in content scripts and do not override window.history because it does not work
2020-04-27 18:05:15 -07:00
Samuel Attard
0ac42125d2 style: use build/include_directory for NOLINT (#23266) (#23303)
build/include linter was splitted to build/include_directory at
depot_tools upstream.

https://crrev.com/c/2159690
https://crbug.com/1073191

Co-authored-by: Sorah Fukumori <sora134@gmail.com>
2020-04-27 14:35:34 -07:00
Charles Kerr
ce04014739 fix: use Node's microtasks policy in node_main.cc (#23234) 2020-04-23 11:00:33 -07:00
trop[bot]
19bd97d80c ci: robustify doc only change check (#23258) 2020-04-23 10:55:36 -07:00
Electron Bot
ea2e34c4c3 chore: bump chromium to 80.0.3987.165 (8-x-y) (#23217)
* chore: bump chromium in DEPS to 80.0.3987.165

* update patches

Co-authored-by: Electron Bot <anonymous@electronjs.org>
2020-04-23 10:50:40 -07:00
Samuel Attard
5f6498d13a fix: do not mutate ipc instances across contexts (#23240) 2020-04-22 17:36:45 -07:00
Jeremy Apthorp
e3c1292548 fix: block custom window.open when nativeWindowOpen is true (#23188) (#23225) 2020-04-22 17:05:42 -07:00
Samuel Attard
b3e53839a4 fix: do not allow child windows to specify their own preload script (#23230) 2020-04-22 16:02:31 -07:00
Samuel Attard
f3e9f10cad fix: ensure that functions are not retained beyond their context being released (#23207) (#23231) 2020-04-22 15:54:19 -07:00
shelley vohr
2c8927a9a2 test: fix type errors in devToolsWebContents (#23206) 2020-04-22 09:23:21 -07:00
trop[bot]
c6786aed26 build: improve patch filename remembering (#23093)
Co-authored-by: Jeremy Apthorp <nornagon@nornagon.net>
2020-04-21 14:06:29 -07:00
Jeremy Apthorp
5b3b09fb7f fix: heap-use-after-free in tray.popUpContextMenu (#22842) (#23181) 2020-04-21 13:27:06 -07:00
Samuel Attard
9f5924c5ea fix: backport V8 promise context fix (#23177) 2020-04-20 18:01:16 -07:00
Shelley Vohr
25f5d764ac fix: wasm codegen in script.runInNewContext (#23147) 2020-04-20 15:29:13 -04:00
trop[bot]
941c72fcfe docs: fix devToolsWebContents union type (#23172)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-04-20 11:35:54 -07:00
Electron Bot
663d389925 Bump v8.2.3 2020-04-16 14:16:08 -07:00
Samuel Attard
b8e3477092 Merge pull request from GHSA-h9jc-284h-533g 2020-04-16 14:10:18 -07:00
trop[bot]
035c784b6c docs: explain the swipe event on macOS (#23133)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-04-16 10:55:37 -07:00
Electron Bot
8faf8a3535 Bump v8.2.2 2020-04-13 11:31:46 -07:00
trop[bot]
331125d35a fix: don't assign NSAlert to window which is not visible (#23088)
* fix: don't assign NSAlert to window which is not visible

Without this change it's possible to create message box which can't
be dismissed on mac.

* fixup! fix: don't assign NSAlert to window which is not visible

* fixup! fix: don't assign NSAlert to window which is not visible

Co-authored-by: Cezary Kulakowski <cezary@openfin.co>
2020-04-13 11:28:01 -07:00
trop[bot]
7316ebde79 fix: reset node env earlier during shutdown (#23069)
Co-authored-by: Jeremy Apthorp <nornagon@nornagon.net>
2020-04-13 11:25:37 -07:00
Jeremy Apthorp
c3340ad21c chore: cherry-pick 85f708fa7ab8 from chromium (#23047)
* chore: cherry-pick 85f708fa7ab8 from chromium

* additionally backport 3626b1f19e
2020-04-13 09:17:18 -04:00
trop[bot]
1e84816c96 fix: persist maximizable state when toggling fullscreen (#23020)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-04-10 09:40:29 -07:00
Jeremy Apthorp
58c6ea5de8 ci: auto-3way patches and detect changes (#23032) 2020-04-08 15:31:00 -07:00
trop[bot]
34be80602c fix: nullptr check when closing windows (#23022) 2020-04-07 22:10:41 -07:00
Shelley Vohr
ce40be475b fix: webframe crashes for removed render frame (#22975)
* fix: webframe crashes for removed render frame

* Make errors more descriptive
2020-04-07 21:54:56 -07:00
trop[bot]
5f7bd36119 build: set merge=union for .patches (#22992)
Co-authored-by: Jeremy Apthorp <nornagon@nornagon.net>
2020-04-07 09:55:24 -07:00
Electron Bot
0f19193afd Bump v8.2.1 2020-04-06 14:12:11 -07:00
Samuel Attard
06b3b0ea15 Revert "Bump v8.2.1"
This reverts commit 32f973b010.
2020-04-06 12:43:27 -07:00
Electron Bot
32f973b010 Bump v8.2.1 2020-04-06 12:17:38 -07:00
Samuel Attard
ad2c2a055b Revert "Bump v8.2.1"
This reverts commit d70b1c68fe.
2020-04-06 12:16:21 -07:00
Electron Bot
3069ef3827 chore: bump chromium in DEPS to 80.0.3987.163 (#22931) 2020-04-03 09:20:45 -07:00
Electron Bot
d70b1c68fe Bump v8.2.1 2020-04-02 11:16:28 -07:00
Samuel Attard
3ba4a35c9c fix: propagate preferred color scheme to the renderer (#22896) (#22901)
* fix: propagate preferred color scheme to the renderer (#22896)

* fix: do not crash if the window is closed syncronously with a nativeTheme change

* fix: propogate preferred color scheme to the renderer and keep it up to date

* chore: update native theme source patch for linux
2020-04-01 22:12:14 -07:00
trop[bot]
2c4c1a3dd9 fix: screen module should still be creatable if the first create is before the ready event (#22913)
Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
2020-04-01 11:37:15 -07:00
John Kleinschmidt
a4d8974556 fix: revive offscreen rendering support (#22431)
* fix: revive offscreen rendering support (#22160)

(cherry picked from commit 36f982aee2)

* Fixup compile issues

* skip offscreen tests on 32-bit linux
2020-03-31 17:32:52 -04:00
Electron Bot
b7d4759c19 chore: bump chromium in DEPS to 80.0.3987.162 (#22905) 2020-03-31 17:32:30 -04:00
trop[bot]
d6ecc65df3 fix: dialog fails to show after modal close (#22889)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-03-30 16:29:31 -04:00
Electron Bot
98b67cdb69 chore: bump chromium in DEPS to 80.0.3987.159 (#22847) 2020-03-30 15:58:17 -04:00
John Kleinschmidt
eb37822e03 ci: Add goma to older branches (#22784)
* ci: use goma for windows and linux builds (#21868)

* ci: use goma for windows and linux builds

(cherry picked from commit dc2fcff01c)

* ci:  enable goma for all testing builds (#21992) (#22203)

(cherry picked from commit e7982623ec)
(cherry picked from commit 0e9727e8d5)
2020-03-25 15:28:15 -04:00
trop[bot]
8751f485c5 fix: workaround for hang when preventDefault-ing nativeWindowOpen (#22749)
* fix: enable workaround for nativeWindowOpen hang

* add test

* test: ensure window doesn't leak into other test

* update to use new webcontents delegate methods

Co-authored-by: Andy Locascio <andy@slack-corp.com>
2020-03-25 10:40:26 +09:00
331 changed files with 32841 additions and 2478 deletions

File diff suppressed because it is too large Load Diff

1
.gitattributes vendored
View File

@@ -1,3 +1,4 @@
# `git apply` and friends don't understand CRLF, even on windows. Force those
# files to be checked out with LF endings even if core.autocrlf is true.
*.patch text eol=lf
patches/**/.patches merge=union

View File

@@ -358,6 +358,7 @@ source_set("electron_lib") {
"shell/common/api:mojo",
"//base:base_static",
"//base/allocator:buildflags",
"//chrome/app:command_ids",
"//chrome/app/resources:platform_locale_settings",
"//chrome/services/printing/public/mojom",
"//components/certificate_transparency",
@@ -549,6 +550,16 @@ source_set("electron_lib") {
sources += filenames.lib_sources_nss
sources += [
"shell/browser/ui/gtk/app_indicator_icon.cc",
"shell/browser/ui/gtk/app_indicator_icon.h",
"shell/browser/ui/gtk/app_indicator_icon_menu.cc",
"shell/browser/ui/gtk/app_indicator_icon_menu.h",
"shell/browser/ui/gtk/gtk_status_icon.cc",
"shell/browser/ui/gtk/gtk_status_icon.h",
"shell/browser/ui/gtk/menu_util.cc",
"shell/browser/ui/gtk/menu_util.h",
"shell/browser/ui/gtk/status_icon.cc",
"shell/browser/ui/gtk/status_icon.h",
"shell/browser/ui/gtk_util.cc",
"shell/browser/ui/gtk_util.h",
]
@@ -829,6 +840,7 @@ if (is_mac) {
include_dirs = [ "." ]
sources = filenames.framework_sources
libs = []
if (enable_osr) {
libs += [ "IOSurface.framework" ]
@@ -1354,7 +1366,7 @@ dist_zip("electron_chromedriver_zip") {
mksnapshot_deps = [
":licenses",
"//tools/v8_context_snapshot:v8_context_snapshot_generator",
"//tools/v8_context_snapshot:v8_context_snapshot_generator($v8_snapshot_toolchain)",
"//v8:mksnapshot($v8_snapshot_toolchain)",
]

4
DEPS
View File

@@ -11,7 +11,7 @@ gclient_gn_args = [
vars = {
'chromium_version':
'80.0.3987.158',
'80.0.3987.165',
'node_version':
'v12.13.0',
'nan_version':
@@ -152,3 +152,5 @@ hooks = [
recursedeps = [
'src',
]
# Touch DEPS to bust cache

View File

@@ -1 +1 @@
8.2.0
8.5.0

View File

@@ -77,15 +77,39 @@ build_script:
%GCLIENT_EXTRA_ARGS%
"https://github.com/electron/electron"
- gclient sync --with_branch_heads --with_tags --ignore_locks --break_repo_locks
- ps: >-
if ($env:SAVE_GCLIENT_SRC -eq 'true') {
# archive current source for future use
# only run on x64/woa to avoid contention saving
if ($(7z a $zipfile src -xr!android_webview -xr!electron -xr'!*\.git' -xr!third_party\WebKit\LayoutTests! -xr!third_party\blink\web_tests -xr!third_party\blink\perf_tests -slp -t7z -mmt=30;$LASTEXITCODE -ne 0)) {
Write-warning "Could not save source to shared drive; continuing anyway"
}
}
- ps: >-
if ($env:GN_CONFIG -ne 'release') {
if (Test-Path 'env:RAW_GOMA_AUTH') {
$env:GOMA_OAUTH2_CONFIG_FILE = "$pwd\.goma_oauth2_config"
$env:RAW_GOMA_AUTH | Set-Content $env:GOMA_OAUTH2_CONFIG_FILE
}
git clone https://github.com/electron/build-tools.git
cd build-tools
npm install
mkdir third_party
node -e "require('./src/utils/goma.js').downloadAndPrepare()"
$env:GN_GOMA_FILE = node -e "console.log(require('./src/utils/goma.js').gnFilePath)"
$env:LOCAL_GOMA_DIR = node -e "console.log(require('./src/utils/goma.js').dir)"
cd ..
.\src\electron\script\start-goma.ps1 -gomaDir $env:LOCAL_GOMA_DIR
}
- cd src
- ps: $env:BUILD_CONFIG_PATH="//electron/build/args/%GN_CONFIG%.gn"
- gn gen out/Default "--args=import(\"%BUILD_CONFIG_PATH%\") %GN_EXTRA_ARGS% cc_wrapper=\"%SCCACHE_PATH%\""
- set BUILD_CONFIG_PATH=//electron/build/args/%GN_CONFIG%.gn
- if DEFINED GN_GOMA_FILE (gn gen out/Default "--args=import(\"%BUILD_CONFIG_PATH%\") import(\"%GN_GOMA_FILE%\") %GN_EXTRA_ARGS% ") else (gn gen out/Default "--args=import(\"%BUILD_CONFIG_PATH%\") %GN_EXTRA_ARGS% cc_wrapper=\"%SCCACHE_PATH%\"")
- gn check out/Default //electron:electron_lib
- gn check out/Default //electron:electron_app
- gn check out/Default //electron:manifests
- gn check out/Default //electron/shell/common/api:mojo
- ninja -C out/Default electron:electron_app
- if "%GN_CONFIG%"=="testing" ( python C:\Users\electron\depot_tools\post_build_ninja_summary.py -C out\Default )
- if DEFINED GN_GOMA_FILE (ninja -j 300 -C out/Default electron:electron_app) else (ninja -C out/Default electron:electron_app)
- if "%GN_CONFIG%"=="testing" ( python C:\Users\electron\depot_tools\post_build_ninja_summary.py -C out\Default )
- gn gen out/ffmpeg "--args=import(\"//electron/build/args/ffmpeg.gn\") %GN_EXTRA_ARGS%"
- ninja -C out/ffmpeg electron:electron_ffmpeg_zip
- ninja -C out/Default electron:electron_dist_zip
@@ -94,7 +118,7 @@ build_script:
- ninja -C out/Default electron:hunspell_dictionaries_zip
- ninja -C out/Default electron:electron_chromedriver_zip
- ninja -C out/Default third_party/electron_node:headers
- cmd /C %SCCACHE_PATH% --show-stats
- if "%GN_CONFIG%"=="testing" ( python %LOCAL_GOMA_DIR%\goma_ctl.py stat )
- appveyor PushArtifact out/Default/dist.zip
- appveyor PushArtifact out/Default/shell_browser_ui_unittests.exe
- appveyor PushArtifact out/Default/chromedriver.zip

View File

@@ -88,5 +88,6 @@ steps:
- powershell: |
Get-Process | Where Name Like "electron*" | Stop-Process
Get-Process | Where Name Like "MicrosoftEdge*" | Stop-Process
Get-Process | Where Name Like "msedge*" | Stop-Process
displayName: 'Kill processes left running from last test run'
condition: always()

View File

@@ -27,5 +27,4 @@ dawn_enable_vulkan_validation_layers = false
is_cfi = false
# TODO: disabled due to crashes. re-enable.
enable_osr = false
enable_osr = true

View File

@@ -1,3 +1,4 @@
const fs = require('fs');
const path = require('path')
const webpack = require('webpack')
@@ -9,6 +10,9 @@ config.output = {
filename: path.basename(outPath)
}
const { wrapInitWithProfilingTimeout } = config;
delete config.wrapInitWithProfilingTimeout;
webpack(config, (err, stats) => {
if (err) {
console.error(err)
@@ -17,6 +21,18 @@ webpack(config, (err, stats) => {
console.error(stats.toString('normal'))
process.exit(1)
} else {
if (wrapInitWithProfilingTimeout) {
const contents = fs.readFileSync(outPath, 'utf8');
const newContents = `function ___electron_webpack_init__() {
${contents}
};
if ((globalThis.process || binding.process).argv.includes("--profile-electron-init")) {
setTimeout(___electron_webpack_init__, 0);
} else {
___electron_webpack_init__();
}`;
fs.writeFileSync(outPath, newContents);
}
process.exit(0)
}
})

View File

@@ -24,7 +24,8 @@ module.exports = ({
alwaysHasNode,
loadElectronFromAlternateTarget,
targetDeletesNodeGlobals,
target
target,
wrapInitWithProfilingTimeout
}) => {
let entry = path.resolve(electronRoot, 'lib', target, 'init.ts')
if (!fs.existsSync(entry)) {
@@ -39,6 +40,7 @@ module.exports = ({
output: {
filename: `${target}.bundle.js`
},
wrapInitWithProfilingTimeout,
resolve: {
alias: {
'@electron/internal': path.resolve(electronRoot, 'lib'),

View File

@@ -1,5 +1,6 @@
module.exports = require('./webpack.config.base')({
target: 'renderer',
alwaysHasNode: true,
targetDeletesNodeGlobals: true
targetDeletesNodeGlobals: true,
wrapInitWithProfilingTimeout: true
})

View File

@@ -1,4 +1,5 @@
module.exports = require('./webpack.config.base')({
target: 'sandboxed_renderer',
alwaysHasNode: false
alwaysHasNode: false,
wrapInitWithProfilingTimeout: true,
})

View File

@@ -16,6 +16,7 @@ template("webpack_build") {
inputs = [
invoker.config_file,
"//electron/build/webpack/webpack.config.base.js",
"//electron/build/webpack/run-compiler.js",
"//electron/tsconfig.json",
"//electron/yarn.lock",
"//electron/typings/internal-ambient.d.ts",

View File

@@ -1,5 +1,6 @@
import { app, dialog, BrowserWindow, shell, ipcMain } from 'electron';
import * as path from 'path';
import * as url from 'url';
let mainWindow: BrowserWindow | null = null;
@@ -31,12 +32,11 @@ function isTrustedSender (webContents: Electron.WebContents) {
return false;
}
const parsedUrl = new URL(webContents.getURL());
const urlPath = process.platform === 'win32'
// Strip the prefixed "/" that occurs on windows
? path.resolve(parsedUrl.pathname.substr(1))
: parsedUrl.pathname;
return parsedUrl.protocol === 'file:' && urlPath === indexPath;
try {
return url.fileURLToPath(webContents.getURL()) === indexPath;
} catch {
return false;
}
}
ipcMain.handle('bootstrap', (event) => {

View File

@@ -368,6 +368,25 @@ Returns:
Emitted when the renderer process of `webContents` crashes or is killed.
#### Event: 'render-process-gone'
Returns:
* `event` Event
* `webContents` [WebContents](web-contents.md)
* `details` Object
* `reason` String - The reason the render process is gone. Possible values:
* `clean-exit` - Process exited with an exit code of zero
* `abnormal-exit` - Process exited with a non-zero exit code
* `killed` - Process was sent a SIGTERM or otherwise killed externally
* `crashed` - Process crashed
* `oom` - Process ran out of memory
* `launch-failure` - Process never successfully launched
* `integrity-failure` - Windows code integrity checks failed
Emitted when the renderer process unexpectedly dissapears. This is normally
because it was crashed or killed.
### Event: 'accessibility-support-changed' _macOS_ _Windows_
Returns:
@@ -564,11 +583,17 @@ Returns `Promise<void>` - fulfilled when Electron is initialized.
May be used as a convenient alternative to checking `app.isReady()`
and subscribing to the `ready` event if the app is not ready yet.
### `app.focus()`
### `app.focus([options])`
* `options` Object (optional)
* `steal` Boolean _macOS_ - Make the receiver the active app even if another app is
currently active.
On Linux, focuses on the first visible window. On macOS, makes the application
the active app. On Windows, focuses on the application's first window.
You should seek to use the `steal` option as sparingly as possible.
### `app.hide()` _macOS_
Hides all application windows without minimizing them.
@@ -669,8 +694,6 @@ to the npm modules spec. You should usually also specify a `productName`
field, which is your application's full capitalized name, and which will be
preferred over `name` by Electron.
**[Deprecated](modernization/property-updates.md)**
### `app.setName(name)`
* `name` String
@@ -679,8 +702,6 @@ Overrides the current application's name.
**Note:** This function overrides the name used internally by Electron; it does not affect the name that the OS uses.
**[Deprecated](modernization/property-updates.md)**
### `app.getLocale()`
Returns `String` - The current application locale. Possible return values are documented [here](locales.md).
@@ -1088,14 +1109,10 @@ On macOS, it shows on the dock icon. On Linux, it only works for Unity launcher.
**Note:** Unity launcher requires the existence of a `.desktop` file to work,
for more information please read [Desktop Environment Integration][unity-requirement].
**[Deprecated](modernization/property-updates.md)**
### `app.getBadgeCount()` _Linux_ _macOS_
Returns `Integer` - The current value displayed in the counter badge.
**[Deprecated](modernization/property-updates.md)**
### `app.isUnityRunning()` _Linux_
Returns `Boolean` - Whether the current desktop environment is Unity launcher.
@@ -1170,8 +1187,6 @@ technologies, such as screen readers, has been detected. See
https://www.chromium.org/developers/design-documents/accessibility for more
details.
**[Deprecated](modernization/property-updates.md)**
### `app.setAccessibilitySupportEnabled(enabled)` _macOS_ _Windows_
* `enabled` Boolean - Enable or disable [accessibility tree](https://developers.google.com/web/fundamentals/accessibility/semantics-builtin/the-accessibility-tree) rendering
@@ -1183,8 +1198,6 @@ This API must be called after the `ready` event is emitted.
**Note:** Rendering accessibility tree can significantly affect the performance of your app. It should not be enabled by default.
**[Deprecated](modernization/property-updates.md)**
### `app.showAboutPanel()`
Show the app's about panel options. These options can be overridden with `app.setAboutPanelOptions(options)`.

View File

@@ -388,6 +388,15 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
visible to users.
* `spellcheck` Boolean (optional) - Whether to enable the builtin spellchecker.
Default is `false`.
* `enableWebSQL` Boolean (optional) - Whether to enable the [WebSQL api](https://www.w3.org/TR/webdatabase/).
Default is `true`.
* `v8CacheOptions` String (optional) - Enforces the v8 code caching policy
used by blink. Accepted values are
* `none` - Disables code caching
* `code` - Heuristic based code caching
* `bypassHeatCheck` - Bypass code caching heuristics but with lazy compilation
* `bypassHeatCheckAndEagerCompile` - Same as above except compilation is eager.
Default policy is `code`.
When setting minimum or maximum window size with `minWidth`/`maxWidth`/
`minHeight`/`maxHeight`, it only constrains the users. It won't prevent you from
@@ -626,6 +635,12 @@ Returns:
Emitted on 3-finger swipe. Possible directions are `up`, `right`, `down`, `left`.
The method underlying this event is built to handle older macOS-style trackpad swiping,
where the content on the screen doesn't move with the swipe. Most macOS trackpads are not
configured to allow this kind of swiping anymore, so in order for it to emit properly the
'Swipe between pages' preference in `System Preferences > Trackpad > More Gestures` must be
set to 'Swipe with two or three fingers'.
#### Event: 'rotate-gesture' _macOS_
Returns:
@@ -1046,7 +1061,7 @@ Disable or enable the window.
#### `win.isEnabled()`
Returns Boolean - whether the window is enabled.
Returns `Boolean` - whether the window is enabled.
#### `win.setSize(width, height[, animate])`
@@ -1098,15 +1113,11 @@ Returns `Integer[]` - Contains the window's maximum width and height.
* `resizable` Boolean
Sets whether the window can be manually resized by user.
**[Deprecated](modernization/property-updates.md)**
Sets whether the window can be manually resized by the user.
#### `win.isResizable()`
Returns `Boolean` - Whether the window can be manually resized by user.
**[Deprecated](modernization/property-updates.md)**
Returns `Boolean` - Whether the window can be manually resized by the user.
#### `win.setMovable(movable)` _macOS_ _Windows_
@@ -1114,41 +1125,29 @@ Returns `Boolean` - Whether the window can be manually resized by user.
Sets whether the window can be moved by user. On Linux does nothing.
**[Deprecated](modernization/property-updates.md)**
#### `win.isMovable()` _macOS_ _Windows_
Returns `Boolean` - Whether the window can be moved by user.
On Linux always returns `true`.
**[Deprecated](modernization/property-updates.md)**
#### `win.setMinimizable(minimizable)` _macOS_ _Windows_
* `minimizable` Boolean
Sets whether the window can be manually minimized by user. On Linux does
nothing.
**[Deprecated](modernization/property-updates.md)**
Sets whether the window can be manually minimized by user. On Linux does nothing.
#### `win.isMinimizable()` _macOS_ _Windows_
Returns `Boolean` - Whether the window can be manually minimized by user
Returns `Boolean` - Whether the window can be manually minimized by the user.
On Linux always returns `true`.
**[Deprecated](modernization/property-updates.md)**
#### `win.setMaximizable(maximizable)` _macOS_ _Windows_
* `maximizable` Boolean
Sets whether the window can be manually maximized by user. On Linux does
nothing.
**[Deprecated](modernization/property-updates.md)**
Sets whether the window can be manually maximized by user. On Linux does nothing.
#### `win.isMaximizable()` _macOS_ _Windows_
@@ -1156,23 +1155,15 @@ Returns `Boolean` - Whether the window can be manually maximized by user.
On Linux always returns `true`.
**[Deprecated](modernization/property-updates.md)**
#### `win.setFullScreenable(fullscreenable)`
* `fullscreenable` Boolean
Sets whether the maximize/zoom window button toggles fullscreen mode or
maximizes the window.
**[Deprecated](modernization/property-updates.md)**
Sets whether the maximize/zoom window button toggles fullscreen mode or maximizes the window.
#### `win.isFullScreenable()`
Returns `Boolean` - Whether the maximize/zoom window button toggles fullscreen mode or
maximizes the window.
**[Deprecated](modernization/property-updates.md)**
Returns `Boolean` - Whether the maximize/zoom window button toggles fullscreen mode or maximizes the window.
#### `win.setClosable(closable)` _macOS_ _Windows_
@@ -1180,16 +1171,12 @@ maximizes the window.
Sets whether the window can be manually closed by user. On Linux does nothing.
**[Deprecated](modernization/property-updates.md)**
#### `win.isClosable()` _macOS_ _Windows_
Returns `Boolean` - Whether the window can be manually closed by user.
On Linux always returns `true`.
**[Deprecated](modernization/property-updates.md)**
#### `win.setAlwaysOnTop(flag[, level][, relativeLevel])`
* `flag` Boolean
@@ -1601,23 +1588,17 @@ This cannot be called when `titleBarStyle` is set to `customButtonsOnHover`.
Sets whether the window menu bar should hide itself automatically. Once set the
menu bar will only show when users press the single `Alt` key.
If the menu bar is already visible, calling `setAutoHideMenuBar(true)` won't
hide it immediately.
**[Deprecated](modernization/property-updates.md)**
If the menu bar is already visible, calling `setAutoHideMenuBar(true)` won't hide it immediately.
#### `win.isMenuBarAutoHide()`
Returns `Boolean` - Whether menu bar automatically hides itself.
**[Deprecated](modernization/property-updates.md)**
#### `win.setMenuBarVisibility(visible)` _Windows_ _Linux_
* `visible` Boolean
Sets whether the menu bar should be visible. If the menu bar is auto-hide, users
can still bring up the menu bar by pressing the single `Alt` key.
Sets whether the menu bar should be visible. If the menu bar is auto-hide, users can still bring up the menu bar by pressing the single `Alt` key.
#### `win.isMenuBarVisible()`

View File

@@ -28,6 +28,10 @@ Disables the disk cache for HTTP requests.
Disable HTTP/2 and SPDY/3.1 protocols.
### --disable-ntlm-v2
Disables NTLM v2 for posix platforms, no effect elsewhere.
## --lang
Set a custom locale.

View File

@@ -38,6 +38,9 @@ Get a set of category groups. The category groups can change as new code paths
are reached. See also the [list of built-in tracing
categories](https://chromium.googlesource.com/chromium/src/+/master/base/trace_event/builtin_categories.h).
> **NOTE:** Electron adds a non-default tracing category called `"electron"`.
> This category can be used to capture Electron-specific tracing events.
### `contentTracing.startRecording(options)`
* `options` ([TraceConfig](structures/trace-config.md) | [TraceCategoriesAndOptions](structures/trace-categories-and-options.md))

View File

@@ -52,6 +52,8 @@ Returns:
* `method` String - Method name.
* `params` any - Event parameters defined by the 'parameters'
attribute in the remote debugging protocol.
* `sessionId` String - Unique identifier of attached debugging session,
will match the value sent from `debugger.sendCommand`.
Emitted whenever the debugging target issues an instrumentation event.
@@ -74,11 +76,16 @@ Returns `Boolean` - Whether a debugger is attached to the `webContents`.
Detaches the debugger from the `webContents`.
#### `debugger.sendCommand(method[, commandParams])`
#### `debugger.sendCommand(method[, commandParams, sessionId])`
* `method` String - Method name, should be one of the methods defined by the
[remote debugging protocol][rdp].
* `commandParams` any (optional) - JSON object with request parameters.
* `sessionId` String (optional) - send command to the target with associated
debugging session id. The initial value can be obtained by sending
[Target.attachToTarget][attachToTarget] message.
[attachToTarget]: https://chromedevtools.github.io/devtools-protocol/tot/Target/#method-attachToTarget
Returns `Promise<any>` - A promise that resolves with the response defined by
the 'returns' attribute of the command description in the remote debugging protocol

View File

@@ -269,6 +269,7 @@ Shows a message box, it will block the process until the message box is closed.
It returns the index of the clicked button.
The `browserWindow` argument allows the dialog to attach itself to a parent window, making it modal.
If `browserWindow` is not shown dialog will not be attached to it. In such case It will be displayed as independed window.
### `dialog.showMessageBox([browserWindow, ]options)`

View File

@@ -82,16 +82,12 @@ The API is only available in session's `will-download` callback function.
If user doesn't set the save path via the API, Electron will use the original
routine to determine the save path; this usually prompts a save dialog.
**[Deprecated](modernization/property-updates.md): use the `savePath` property instead.**
#### `downloadItem.getSavePath()`
Returns `String` - The save path of the download item. This will be either the path
set via `downloadItem.setSavePath(path)` or the path selected from the shown
save dialog.
**[Deprecated](modernization/property-updates.md): use the `savePath` property instead.**
#### `downloadItem.setSaveDialogOptions(options)`
* `options` SaveDialogOptions - Set the save file dialog options. This object has the same

View File

@@ -128,3 +128,14 @@ the one downloaded by `npm install`. Usage:
```sh
export ELECTRON_OVERRIDE_DIST_PATH=/Users/username/projects/electron/out/Debug
```
## Set By Electron
Electron sets some variables in your environment at runtime.
### `ORIGINAL_XDG_CURRENT_DESKTOP`
This variable is set to the value of `XDG_CURRENT_DESKTOP` that your application
originally launched with. Electron sometimes modifies the value of `XDG_CURRENT_DESKTOP`
to affect other logic within Chromium so if you want access to the _original_ value
you should look up this environment variable instead.

View File

@@ -12,7 +12,7 @@ See [`Menu`](menu.md) for examples.
* `click` Function (optional) - Will be called with
`click(menuItem, browserWindow, event)` when the menu item is clicked.
* `menuItem` MenuItem
* `browserWindow` [BrowserWindow](browser-window.md)
* `browserWindow` [BrowserWindow](browser-window.md) | undefined - This will not be defined if no window is open.
* `event` [KeyboardEvent](structures/keyboard-event.md)
* `role` String (optional) - Can be `undo`, `redo`, `cut`, `copy`, `paste`, `pasteAndMatchStyle`, `delete`, `selectAll`, `reload`, `forceReload`, `toggleDevTools`, `resetZoom`, `zoomIn`, `zoomOut`, `togglefullscreen`, `window`, `minimize`, `close`, `help`, `about`, `services`, `hide`, `hideOthers`, `unhide`, `quit`, `startSpeaking`, `stopSpeaking`, `close`, `minimize`, `zoom`, `front`, `appMenu`, `fileMenu`, `editMenu`, `viewMenu`, `recentDocuments`, `toggleTabBar`, `selectNextTab`, `selectPreviousTab`, `mergeAllWindows`, `clearRecentDocuments`, `moveTabToNewWindow` or `windowMenu` - Define the action of the menu item, when specified the
`click` property will be ignored. See [roles](#roles).
@@ -69,6 +69,7 @@ a `type`.
The `role` property can have following values:
* `undo`
* `about` - Trigger a native about panel (custom message box on Window, which does not provide its own).
* `redo`
* `cut`
* `copy`
@@ -94,7 +95,6 @@ The `role` property can have following values:
The following additional roles are available on _macOS_:
* `appMenu` - Whole default "App" menu (About, Services, etc.)
* `about` - Map to the `orderFrontStandardAboutPanel` action.
* `hide` - Map to the `hide` action.
* `hideOthers` - Map to the `hideOtherApplications` action.
* `unhide` - Map to the `unhideAllApplications` action.

View File

@@ -45,9 +45,3 @@ The Electron team is currently undergoing an initiative to convert separate gett
* `isMacTemplateImage`
* `SystemPreferences` module
* `appLevelAppearance`
* `webContents` module
* `audioMuted`
* `frameRate`
* `userAgent`
* `zoomFactor`
* `zoomLevel`

View File

@@ -276,14 +276,10 @@ Returns [`Size`](structures/size.md)
Marks the image as a template image.
**[Deprecated](modernization/property-updates.md)**
#### `image.isTemplateImage()`
Returns `Boolean` - Whether the image is a template image.
**[Deprecated](modernization/property-updates.md)**
#### `image.crop(rect)`
* `rect` [Rectangle](structures/rectangle.md) - The area of the image to crop.

View File

@@ -24,11 +24,11 @@ app.on('ready', () => {
The `powerMonitor` module emits the following events:
### Event: 'suspend'
### Event: 'suspend' _Linux_ _Windows_
Emitted when the system is suspending.
### Event: 'resume'
### Event: 'resume' _Linux_ _Windows_
Emitted when system is resuming.

View File

@@ -0,0 +1,4 @@
# NewWindowEvent Object extends `Event`
* `newGuest` BrowserWindow (optional)

View File

@@ -360,7 +360,7 @@ Returns `Boolean` - `true` if an inverted color scheme (a high contrast color sc
Returns `Boolean` - `true` if a high contrast theme is active, `false` otherwise.
**Depreacted:** Should use the new [`nativeTheme.shouldUseHighContrastColors`](native-theme.md#nativethemeshouldusehighcontrastcolors-macos-windows-readonly) API.
**Deprecated:** Should use the new [`nativeTheme.shouldUseHighContrastColors`](native-theme.md#nativethemeshouldusehighcontrastcolors-macos-windows-readonly) API.
### `systemPreferences.getEffectiveAppearance()` _macOS_
@@ -369,8 +369,6 @@ Returns `String` - Can be `dark`, `light` or `unknown`.
Gets the macOS appearance setting that is currently applied to your application,
maps to [NSApplication.effectiveAppearance](https://developer.apple.com/documentation/appkit/nsapplication/2967171-effectiveappearance?language=objc)
**[Deprecated](modernization/property-updates.md)**
### `systemPreferences.getAppLevelAppearance()` _macOS_ _Deprecated_
Returns `String` | `null` - Can be `dark`, `light` or `unknown`.
@@ -379,8 +377,6 @@ Gets the macOS appearance setting that you have declared you want for
your application, maps to [NSApplication.appearance](https://developer.apple.com/documentation/appkit/nsapplication/2967170-appearance?language=objc).
You can use the `setAppLevelAppearance` API to set this value.
**[Deprecated](modernization/property-updates.md)**
### `systemPreferences.setAppLevelAppearance(appearance)` _macOS_ _Deprecated_
* `appearance` String | null - Can be `dark` or `light`
@@ -388,8 +384,6 @@ You can use the `setAppLevelAppearance` API to set this value.
Sets the appearance setting for your application, this should override the
system default and override the value of `getEffectiveAppearance`.
**[Deprecated](modernization/property-updates.md)**
### `systemPreferences.canPromptTouchID()` _macOS_
Returns `Boolean` - whether or not this device has the ability to use Touch ID.
@@ -422,7 +416,7 @@ This API itself will not protect your user data; rather, it is a mechanism to al
Returns `Boolean` - `true` if the current process is a trusted accessibility client and `false` if it is not.
### `systemPreferences.getMediaAccessStatus(mediaType)` _macOS_
### `systemPreferences.getMediaAccessStatus(mediaType)` _Windows_ _macOS_
* `mediaType` String - Can be `microphone`, `camera` or `screen`.
@@ -432,6 +426,9 @@ This user consent was not required on macOS 10.13 High Sierra or lower so this m
macOS 10.14 Mojave or higher requires consent for `microphone` and `camera` access.
macOS 10.15 Catalina or higher requires consent for `screen` access.
Windows 10 has a global setting controlling `microphone` and `camera` access for all win32 applications.
It will always return `granted` for `screen` and for all media types on older versions of Windows.
### `systemPreferences.askForMediaAccess(mediaType)` _macOS_
* `mediaType` String - the type of media being requested; can be `microphone`, `camera`.

View File

@@ -138,7 +138,7 @@ Emitted when page receives favicon urls.
Returns:
* `event` Event
* `event` NewWindowEvent
* `url` String
* `frameName` String
* `disposition` String - Can be `default`, `foreground-tab`, `background-tab`,
@@ -334,6 +334,24 @@ Returns:
Emitted when the renderer process crashes or is killed.
#### Event: 'render-process-gone'
Returns:
* `event` Event
* `details` Object
* `reason` String - The reason the render process is gone. Possible values:
* `clean-exit` - Process exited with an exit code of zero
* `abnormal-exit` - Process exited with a non-zero exit code
* `killed` - Process was sent a SIGTERM or otherwise killed externally
* `crashed` - Process crashed
* `oom` - Process ran out of memory
* `launch-failure` - Process never successfully launched
* `integrity-failure` - Windows code integrity checks failed
Emitted when the renderer process unexpectedly dissapears. This is normally
because it was crashed or killed.
#### Event: 'unresponsive'
Emitted when the web page becomes unresponsive.
@@ -366,6 +384,7 @@ Returns:
* `key` String - Equivalent to [KeyboardEvent.key][keyboardevent].
* `code` String - Equivalent to [KeyboardEvent.code][keyboardevent].
* `isAutoRepeat` Boolean - Equivalent to [KeyboardEvent.repeat][keyboardevent].
* `isComposing` Boolean - Equivalent to [KeyboardEvent.isComposing][keyboardevent].
* `shift` Boolean - Equivalent to [KeyboardEvent.shiftKey][keyboardevent].
* `control` Boolean - Equivalent to [KeyboardEvent.controlKey][keyboardevent].
* `alt` Boolean - Equivalent to [KeyboardEvent.altKey][keyboardevent].
@@ -882,10 +901,10 @@ Returns `String` - The URL of the current web page.
```javascript
const { BrowserWindow } = require('electron')
let win = new BrowserWindow({ width: 800, height: 600 })
win.loadURL('http://github.com')
let currentURL = win.webContents.getURL()
console.log(currentURL)
win.loadURL('http://github.com').then(() => {
const currentURL = win.webContents.getURL()
console.log(currentURL)
})
```
#### `contents.getTitle()`
@@ -978,14 +997,10 @@ Returns `Boolean` - Whether the renderer process has crashed.
Overrides the user agent for this web page.
**[Deprecated](modernization/property-updates.md)**
#### `contents.getUserAgent()`
Returns `String` - The user agent for this web page.
**[Deprecated](modernization/property-updates.md)**
#### `contents.insertCSS(css[, options])`
* `css` String
@@ -1065,14 +1080,10 @@ Ignore application menu shortcuts while this web contents is focused.
Mute the audio on the current web page.
**[Deprecated](modernization/property-updates.md)**
#### `contents.isAudioMuted()`
Returns `Boolean` - Whether this page has been muted.
**[Deprecated](modernization/property-updates.md)**
#### `contents.isCurrentlyAudible()`
Returns `Boolean` - Whether audio is currently playing.
@@ -1086,14 +1097,10 @@ zoom percent divided by 100, so 300% = 3.0.
The factor must be greater than 0.0.
**[Deprecated](modernization/property-updates.md)**
#### `contents.getZoomFactor()`
Returns `Number` - the current zoom factor.
**[Deprecated](modernization/property-updates.md)**
#### `contents.setZoomLevel(level)`
* `level` Number - Zoom level.
@@ -1103,14 +1110,10 @@ increment above or below represents zooming 20% larger or smaller to default
limits of 300% and 50% of original size, respectively. The formula for this is
`scale := 1.2 ^ level`.
**[Deprecated](modernization/property-updates.md)**
#### `contents.getZoomLevel()`
Returns `Number` - the current zoom level.
**[Deprecated](modernization/property-updates.md)**
#### `contents.setVisualZoomLevelLimits(minimumLevel, maximumLevel)`
* `minimumLevel` Number
@@ -1713,14 +1716,10 @@ Returns `Boolean` - If *offscreen rendering* is enabled returns whether it is cu
If *offscreen rendering* is enabled sets the frame rate to the specified number.
Only values between 1 and 60 are accepted.
**[Deprecated](modernization/property-updates.md)**
#### `contents.getFrameRate()`
Returns `Integer` - If *offscreen rendering* is enabled returns the current frame rate.
**[Deprecated](modernization/property-updates.md)**
#### `contents.invalidate()`
Schedules a full repaint of the window this web contents is in.
@@ -1826,7 +1825,7 @@ A [`WebContents`](web-contents.md) instance that might own this `WebContents`.
#### `contents.devToolsWebContents` _Readonly_
A `WebContents` of DevTools for this `WebContents`.
A `WebContents | null` property that represents the of DevTools `WebContents` associated with a given `WebContents`.
**Note:** Users should never store this object because it may become `null`
when the DevTools has been closed.

View File

@@ -154,10 +154,14 @@ this limitation.
* `userGesture` Boolean (optional) - Default is `false`.
Returns `Promise<any>` - A promise that resolves with the result of the executed code
or is rejected if the result of the code is a rejected promise.
or is rejected if execution could not start.
Works like `executeJavaScript` but evaluates `scripts` in an isolated context.
Note that when the execution of script fails, the returned promise will not
reject and the `result` would be `undefined`. This is because Chromium does not
dispatch errors of isolated worlds to foreign worlds.
### `webFrame.setIsolatedWorldInfo(worldId, info)`
* `worldId` Integer - The ID of the world to run the javascript in, `0` is the default world, `999` is the world used by Electrons `contextIsolation` feature. Chrome extensions reserve the range of IDs in `[1 << 20, 1 << 29)`. You can provide any integer here.
* `info` Object

View File

@@ -54,7 +54,9 @@ template("electron_extra_paks") {
output = "${invoker.output_dir}/resources.pak"
sources = [
"$root_gen_dir/components/components_resources.pak",
"$root_gen_dir/content/browser/resources/media/media_internals_resources.pak",
"$root_gen_dir/content/browser/tracing/tracing_resources.pak",
"$root_gen_dir/content/browser/webrtc/resources/webrtc_internals_resources.pak",
"$root_gen_dir/content/content_resources.pak",
"$root_gen_dir/mojo/public/js/mojo_bindings_resources.pak",
"$root_gen_dir/net/net_resources.pak",
@@ -65,7 +67,9 @@ template("electron_extra_paks") {
deps = [
"//components/resources",
"//content:resources",
"//content/browser/resources/media:media_internals_resources",
"//content/browser/tracing:resources",
"//content/browser/webrtc/resources",
"//electron:resources",
"//mojo/public/js:resources",
"//net:net_resources",

View File

@@ -96,6 +96,7 @@ auto_filenames = {
"docs/api/structures/mime-typed-buffer.md",
"docs/api/structures/mouse-input-event.md",
"docs/api/structures/mouse-wheel-input-event.md",
"docs/api/structures/new-window-event.md",
"docs/api/structures/notification-action.md",
"docs/api/structures/point.md",
"docs/api/structures/printer-info.md",
@@ -177,11 +178,8 @@ auto_filenames = {
isolated_bundle_deps = [
"lib/common/electron-binding-setup.ts",
"lib/isolated_renderer/init.js",
"lib/renderer/ipc-renderer-internal-utils.ts",
"lib/renderer/ipc-renderer-internal.ts",
"lib/renderer/web-view/web-view-constants.ts",
"lib/renderer/web-view/web-view-element.ts",
"lib/renderer/window-setup.ts",
"package.json",
"tsconfig.electron.json",
"tsconfig.json",
@@ -191,6 +189,7 @@ auto_filenames = {
"lib/common/electron-binding-setup.ts",
"lib/common/webpack-globals-provider.ts",
"lib/content_script/init.js",
"lib/renderer/api/context-bridge.ts",
"lib/renderer/chrome-api.ts",
"lib/renderer/extensions/event.ts",
"lib/renderer/extensions/i18n.ts",

View File

@@ -389,6 +389,8 @@ filenames = {
"shell/browser/ui/views/submenu_button.h",
"shell/browser/ui/views/win_frame_view.cc",
"shell/browser/ui/views/win_frame_view.h",
"shell/browser/ui/win/dialog_thread.cc",
"shell/browser/ui/win/dialog_thread.h",
"shell/browser/ui/win/electron_desktop_native_widget_aura.cc",
"shell/browser/ui/win/electron_desktop_native_widget_aura.h",
"shell/browser/ui/win/electron_desktop_window_tree_host_win.cc",
@@ -518,6 +520,10 @@ filenames = {
"shell/common/key_weak_map.h",
"shell/common/keyboard_util.cc",
"shell/common/keyboard_util.h",
"shell/common/language_util.h",
"shell/common/language_util_linux.cc",
"shell/common/language_util_mac.mm",
"shell/common/language_util_win.cc",
"shell/common/mac/main_application_bundle.h",
"shell/common/mac/main_application_bundle.mm",
"shell/common/mouse_util.cc",
@@ -568,8 +574,6 @@ filenames = {
"shell/common/skia_util.h",
"shell/renderer/api/context_bridge/object_cache.cc",
"shell/renderer/api/context_bridge/object_cache.h",
"shell/renderer/api/context_bridge/render_frame_function_store.cc",
"shell/renderer/api/context_bridge/render_frame_function_store.h",
"shell/renderer/api/electron_api_context_bridge.cc",
"shell/renderer/api/electron_api_context_bridge.h",
"shell/renderer/api/electron_api_renderer_ipc.cc",

View File

@@ -1,7 +1,7 @@
import * as fs from 'fs';
import * as path from 'path';
import { deprecate, Menu } from 'electron';
import { Menu } from 'electron';
import { EventEmitter } from 'events';
const bindings = process.electronBinding('app');
@@ -17,6 +17,29 @@ let dockMenu: Electron.Menu | null = null;
Object.setPrototypeOf(App.prototype, EventEmitter.prototype);
EventEmitter.call(app as any);
// Properties.
const nativeASGetter = app.isAccessibilitySupportEnabled;
const nativeASSetter = app.setAccessibilitySupportEnabled;
Object.defineProperty(App.prototype, 'accessibilitySupportEnabled', {
get: () => nativeASGetter.call(app),
set: (enabled) => nativeASSetter.call(app, enabled)
});
const nativeBCGetter = app.getBadgeCount;
const nativeBCSetter = app.setBadgeCount;
Object.defineProperty(App.prototype, 'badgeCount', {
get: () => nativeBCGetter.call(app),
set: (count) => nativeBCSetter.call(app, count)
});
const nativeNGetter = app.getName;
const nativeNSetter = app.setName;
Object.defineProperty(App.prototype, 'name', {
get: () => nativeNGetter.call(app),
set: (name) => nativeNSetter.call(app, name)
});
Object.assign(app, {
commandLine: {
hasSwitch: (theSwitch: string) => commandLine.hasSwitch(String(theSwitch)),
@@ -112,11 +135,6 @@ for (const name of events) {
});
}
// Property Deprecations
deprecate.fnToProperty(App.prototype, 'accessibilitySupportEnabled', '_isAccessibilitySupportEnabled', '_setAccessibilitySupportEnabled');
deprecate.fnToProperty(App.prototype, 'badgeCount', '_getBadgeCount', '_setBadgeCount');
deprecate.fnToProperty(App.prototype, 'name', '_getName', '_setName');
// Wrappers for native classes.
const { DownloadItem } = process.electronBinding('download_item');
Object.setPrototypeOf(DownloadItem.prototype, EventEmitter.prototype);

View File

@@ -92,6 +92,43 @@ BrowserWindow.prototype._init = function () {
return this.webContents.devToolsWebContents;
}
});
// Properties
Object.defineProperty(this, 'autoHideMenuBar', {
get: () => this.isMenuBarAutoHide(),
set: (autoHide) => this.setAutoHideMenuBar(autoHide)
});
Object.defineProperty(this, 'minimizable', {
get: () => this.isMinimizable(),
set: (min) => this.setMinimizable(min)
});
Object.defineProperty(this, 'maximizable', {
get: () => this.isMaximizable(),
set: (max) => this.setMaximizable(max)
});
Object.defineProperty(this, 'resizable', {
get: () => this.isResizable(),
set: (res) => this.setResizable(res)
});
Object.defineProperty(this, 'fullScreenable', {
get: () => this.isFullScreenable(),
set: (full) => this.setFullScreenable(full)
});
Object.defineProperty(this, 'closable', {
get: () => this.isClosable(),
set: (close) => this.setClosable(close)
});
Object.defineProperty(this, 'movable', {
get: () => this.isMovable(),
set: (move) => this.setMovable(move)
});
};
const isBrowserWindow = (win) => {
@@ -185,13 +222,4 @@ Object.assign(BrowserWindow.prototype, {
}
});
// Deprecations
deprecate.fnToProperty(BrowserWindow.prototype, 'autoHideMenuBar', '_isMenuBarAutoHide', '_setAutoHideMenuBar');
deprecate.fnToProperty(BrowserWindow.prototype, 'minimizable', '_isMinimizable', '_setMinimizable');
deprecate.fnToProperty(BrowserWindow.prototype, 'maximizable', '_isMaximizable', '_setMaximizable');
deprecate.fnToProperty(BrowserWindow.prototype, 'resizable', '_isResizable', '_setResizable');
deprecate.fnToProperty(BrowserWindow.prototype, 'fullScreenable', '_isFullScreenable', '_setFullScreenable');
deprecate.fnToProperty(BrowserWindow.prototype, 'closable', '_isClosable', '_setClosable');
deprecate.fnToProperty(BrowserWindow.prototype, 'movable', '_isMovable', '_setMovable');
module.exports = BrowserWindow;

View File

@@ -249,7 +249,11 @@ module.exports = {
},
showCertificateTrustDialog: function (window, options) {
if (window && window.constructor !== BrowserWindow) options = window;
if (window && window.constructor !== BrowserWindow) {
options = window;
window = null;
}
if (options == null || typeof options !== 'object') {
throw new TypeError('options must be an object');
}

View File

@@ -10,7 +10,8 @@ const roles = {
about: {
get label () {
return isLinux ? 'About' : `About ${app.name}`;
}
},
...(isWindows && { appMethod: 'showAboutPanel' })
},
close: {
label: isMac ? 'Close Window' : 'Close',
@@ -70,7 +71,7 @@ const roles = {
},
pasteandmatchstyle: {
label: 'Paste and Match Style',
accelerator: 'Shift+CommandOrControl+V',
accelerator: isMac ? 'Cmd+Option+Shift+V' : 'Shift+CommandOrControl+V',
webContentsMethod: 'pasteAndMatchStyle',
registerAccelerator: false
},

View File

@@ -371,6 +371,7 @@ class ClientRequest extends Writable {
}
return ret;
};
this._urlLoaderOptions.referrer = this._urlLoaderOptions.extraHeaders.referer || '';
const opts = { ...this._urlLoaderOptions, extraHeaders: stringifyValues(this._urlLoaderOptions.extraHeaders) };
this._urlLoader = new URLLoader(opts);
this._urlLoader.on('response-started', (event, finalUrl, responseHead) => {

View File

@@ -6,21 +6,20 @@ const { systemPreferences, SystemPreferences } = process.electronBinding('system
Object.setPrototypeOf(SystemPreferences.prototype, EventEmitter.prototype);
EventEmitter.call(systemPreferences);
if ('appLevelAppearance' in systemPreferences) {
deprecate.fnToProperty(
SystemPreferences.prototype,
'appLevelAppearance',
'_getAppLevelAppearance',
'_setAppLevelAppearance'
);
if ('getAppLevelAppearance' in systemPreferences) {
const nativeALAGetter = systemPreferences.getAppLevelAppearance;
const nativeALASetter = systemPreferences.setAppLevelAppearance;
Object.defineProperty(SystemPreferences.prototype, 'appLevelAppearance', {
get: () => nativeALAGetter.call(systemPreferences),
set: (appearance) => nativeALASetter.call(systemPreferences, appearance)
});
}
if ('effectiveAppearance' in systemPreferences) {
deprecate.fnToProperty(
SystemPreferences.prototype,
'effectiveAppearance',
'_getEffectiveAppearance'
);
if ('getEffectiveAppearance' in systemPreferences) {
const nativeEAGetter = systemPreferences.getAppLevelAppearance;
Object.defineProperty(SystemPreferences.prototype, 'effectiveAppearance', {
get: () => nativeEAGetter.call(systemPreferences)
});
}
SystemPreferences.prototype.isDarkMode = deprecate.moveAPI(

View File

@@ -389,6 +389,10 @@ WebContents.prototype._init = function () {
app.emit('renderer-process-crashed', event, this, ...args);
});
this.on('render-process-gone', (event, ...args) => {
app.emit('render-process-gone', event, this, ...args);
});
// The devtools requests the webContents to reload.
this.on('devtools-reload-page', function () {
this.reload();
@@ -429,6 +433,11 @@ WebContents.prototype._init = function () {
const referrer = { url: '', policy: 'default' };
internalWindowOpen(event, url, referrer, frameName, disposition, options);
});
const prefs = this.getWebPreferences() || {};
if (prefs.webviewTag && prefs.contextIsolation) {
electron.deprecate.log('Security Warning: A WebContents was just created with both webviewTag and contextIsolation enabled. This combination is fundamentally less secure and effectively bypasses the protections of contextIsolation. We strongly recommend you move away from webviews to OOPIF or BrowserView in order for your app to be more secure');
}
}
this.on('login', (event, ...args) => {
@@ -437,14 +446,34 @@ WebContents.prototype._init = function () {
const event = process.electronBinding('event').createEmpty();
app.emit('web-contents-created', event, this);
};
// Deprecations
deprecate.fnToProperty(WebContents.prototype, 'audioMuted', '_isAudioMuted', '_setAudioMuted');
deprecate.fnToProperty(WebContents.prototype, 'userAgent', '_getUserAgent', '_setUserAgent');
deprecate.fnToProperty(WebContents.prototype, 'zoomLevel', '_getZoomLevel', '_setZoomLevel');
deprecate.fnToProperty(WebContents.prototype, 'zoomFactor', '_getZoomFactor', '_setZoomFactor');
deprecate.fnToProperty(WebContents.prototype, 'frameRate', '_getFrameRate', '_setFrameRate');
// Properties
Object.defineProperty(this, 'audioMuted', {
get: () => this.isAudioMuted(),
set: (muted) => this.setAudioMuted(muted)
});
Object.defineProperty(this, 'userAgent', {
get: () => this.getUserAgent(),
set: (agent) => this.setUserAgent(agent)
});
Object.defineProperty(this, 'zoomLevel', {
get: () => this.getZoomLevel(),
set: (level) => this.setZoomLevel(level)
});
Object.defineProperty(this, 'zoomFactor', {
get: () => this.getZoomFactor(),
set: (factor) => this.setZoomFactor(factor)
});
Object.defineProperty(this, 'frameRate', {
get: () => this.getFrameRate(),
set: (rate) => this.setFrameRate(rate)
});
};
// JavaScript wrapper of Debugger.
const { Debugger } = process.electronBinding('debugger');

View File

@@ -32,6 +32,7 @@ const supportedWebViewEvents = [
'focus-change',
'close',
'crashed',
'render-process-gone',
'plugin-crashed',
'destroyed',
'page-title-updated',
@@ -232,7 +233,8 @@ const attachGuest = function (event, embedderFrameId, elementInstanceId, guestIn
['nodeIntegration', false],
['enableRemoteModule', false],
['sandbox', true],
['nodeIntegrationInSubFrames', false]
['nodeIntegrationInSubFrames', false],
['enableWebSQL', false]
]);
// Inherit certain option values from embedder
@@ -266,6 +268,9 @@ const attachGuest = function (event, embedderFrameId, elementInstanceId, guestIn
// Remove an guest-embedder relationship.
const detachGuest = function (embedder, guestInstanceId) {
const guestInstance = guestInstances[guestInstanceId];
if (!guestInstance) return;
if (embedder !== guestInstance.embedder) {
return;
}
@@ -360,6 +365,10 @@ handleMessage('ELECTRON_GUEST_VIEW_MANAGER_ATTACH_GUEST', function (event, embed
}
});
handleMessageSync('ELECTRON_GUEST_VIEW_MANAGER_DETACH_GUEST', function (event, guestInstanceId) {
return detachGuest(event.sender, guestInstanceId);
});
// this message is sent by the actual <webview>
ipcMainInternal.on('ELECTRON_GUEST_VIEW_MANAGER_FOCUS_CHANGE', function (event, focus, guestInstanceId) {
const guest = getGuest(guestInstanceId);

View File

@@ -19,7 +19,8 @@ const inheritedWebPreferences = new Map([
['enableRemoteModule', false],
['sandbox', true],
['webviewTag', false],
['nodeIntegrationInSubFrames', false]
['nodeIntegrationInSubFrames', false],
['enableWebSQL', false]
]);
// Copy attribute of |parent| to |child| if it is not defined in |child|.
@@ -188,6 +189,14 @@ const canAccessWindow = function (sender, target) {
// Routed window.open messages with raw options
ipcMainInternal.on('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_OPEN', (event, url, frameName, features) => {
// This should only be allowed for senders that have nativeWindowOpen: false
{
const webPreferences = event.sender.getLastWebPreferences();
if (webPreferences.nativeWindowOpen || webPreferences.sandbox) {
event.returnValue = null;
throw new Error('GUEST_WINDOW_MANAGER_WINDOW_OPEN denied: expected native window.open');
}
}
if (url == null || url === '') url = 'about:blank';
if (frameName == null) frameName = '';
if (features == null) features = '';
@@ -195,7 +204,7 @@ ipcMainInternal.on('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_OPEN', (event, url, fra
const options = {};
const ints = ['x', 'y', 'width', 'height', 'minWidth', 'maxWidth', 'minHeight', 'maxHeight', 'zoomFactor'];
const webPreferences = ['zoomFactor', 'nodeIntegration', 'enableRemoteModule', 'preload', 'javascript', 'contextIsolation', 'webviewTag'];
const webPreferences = ['zoomFactor', 'nodeIntegration', 'enableRemoteModule', 'javascript', 'contextIsolation', 'webviewTag'];
const disposition = 'new-window';
// Used to store additional features

View File

@@ -186,6 +186,7 @@ function currentPlatformSupportsAppIndicator () {
}
// Workaround for electron/electron#5050 and electron/electron#9046
process.env.ORIGINAL_XDG_CURRENT_DESKTOP = process.env.XDG_CURRENT_DESKTOP;
if (currentPlatformSupportsAppIndicator()) {
process.env.XDG_CURRENT_DESKTOP = 'Unity';
}

View File

@@ -5,11 +5,12 @@ import { EventEmitter } from 'events';
import objectsRegistry from './objects-registry';
import { ipcMainInternal } from '../ipc-main-internal';
import * as guestViewManager from '@electron/internal/browser/guest-view-manager';
import { isPromise, isSerializableObject } from '@electron/internal/common/type-utils';
import { isPromise, isSerializableObject, deserialize, serialize } from '@electron/internal/common/type-utils';
const v8Util = process.electronBinding('v8_util');
const eventBinding = process.electronBinding('event');
const features = process.electronBinding('features');
const { NativeImage } = process.electronBinding('native_image');
if (!features.isRemoteModuleEnabled()) {
throw new Error('remote module is disabled');
@@ -114,6 +115,9 @@ type MetaType = {
} | {
type: 'promise',
then: MetaType
} | {
type: 'nativeimage'
value: electron.NativeImage
}
// Convert a real value into meta data.
@@ -124,6 +128,8 @@ const valueToMeta = function (sender: electron.WebContents, contextId: string, v
// Recognize certain types of objects.
if (value instanceof Buffer) {
type = 'buffer';
} else if (value instanceof NativeImage) {
type = 'nativeimage';
} else if (Array.isArray(value)) {
type = 'array';
} else if (value instanceof Error) {
@@ -147,6 +153,8 @@ const valueToMeta = function (sender: electron.WebContents, contextId: string, v
type,
members: value.map((el: any) => valueToMeta(sender, contextId, el, optimizeSimpleObject))
};
} else if (type === 'nativeimage') {
return { type, value: serialize(value) };
} else if (type === 'object' || type === 'function') {
return {
type,
@@ -234,7 +242,10 @@ type MetaTypeFromRenderer = {
} | {
type: 'object',
name: string,
members: { name: string, value: MetaTypeFromRenderer }[]
members: {
name: string,
value: MetaTypeFromRenderer
}[]
} | {
type: 'function-with-return-value',
value: MetaTypeFromRenderer
@@ -243,6 +254,14 @@ type MetaTypeFromRenderer = {
id: number,
location: string,
length: number
} | {
type: 'nativeimage',
value: {
size: electron.Size,
buffer: Buffer,
scaleFactor: number,
dataURL: string
}[]
}
const fakeConstructor = (constructor: Function, name: string) =>
@@ -260,6 +279,8 @@ const fakeConstructor = (constructor: Function, name: string) =>
const unwrapArgs = function (sender: electron.WebContents, frameId: number, contextId: string, args: any[]) {
const metaToValue = function (meta: MetaTypeFromRenderer): any {
switch (meta.type) {
case 'nativeimage':
return deserialize(meta.value);
case 'value':
return meta.value;
case 'remote-object':

View File

@@ -1,8 +1,5 @@
'use strict';
const { deprecate } = require('electron');
const { NativeImage, nativeImage } = process.electronBinding('native_image');
deprecate.fnToProperty(NativeImage.prototype, 'isMacTemplateImage', '_isTemplateImage', '_setTemplateImage');
const { nativeImage } = process.electronBinding('native_image');
module.exports = nativeImage;

View File

@@ -572,7 +572,7 @@
};
const { readdir } = fs;
fs.readdir = function (pathArgument, options, callback) {
fs.readdir = function (pathArgument, options = {}, callback) {
const { isAsar, asarPath, filePath } = splitPath(pathArgument);
if (typeof options === 'function') {
callback = options;
@@ -594,13 +594,29 @@
return;
}
if (options.withFileTypes) {
const dirents = [];
for (const file of files) {
const stats = archive.stat(file);
if (stats.isFile) {
dirents.push(new fs.Dirent(file, fs.constants.UV_DIRENT_FILE));
} else if (stats.isDirectory) {
dirents.push(new fs.Dirent(file, fs.constants.UV_DIRENT_DIR));
} else if (stats.isLink) {
dirents.push(new fs.Dirent(file, fs.constants.UV_DIRENT_LINK));
}
}
nextTick(callback, [null, dirents]);
return;
}
nextTick(callback, [null, files]);
};
fs.promises.readdir = util.promisify(fs.readdir);
const { readdirSync } = fs;
fs.readdirSync = function (pathArgument, options) {
fs.readdirSync = function (pathArgument, options = {}) {
const { isAsar, asarPath, filePath } = splitPath(pathArgument);
if (!isAsar) return readdirSync.apply(this, arguments);
@@ -614,6 +630,21 @@
throw createError(AsarError.NOT_FOUND, { asarPath, filePath });
}
if (options.withFileTypes) {
const dirents = [];
for (const file of files) {
const stats = archive.stat(file);
if (stats.isFile) {
dirents.push(new fs.Dirent(file, fs.constants.UV_DIRENT_FILE));
} else if (stats.isDirectory) {
dirents.push(new fs.Dirent(file, fs.constants.UV_DIRENT_DIR));
} else if (stats.isLink) {
dirents.push(new fs.Dirent(file, fs.constants.UV_DIRENT_LINK));
}
}
return dirents;
}
return files;
};

View File

@@ -23,6 +23,7 @@ const serializableTypes = [
ArrayBuffer
];
// https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm#Supported_types
export function isSerializableObject (value: any) {
return value === null || ArrayBuffer.isView(value) || serializableTypes.some(type => value instanceof type);
}
@@ -33,14 +34,55 @@ const objectMap = function (source: Object, mapper: (value: any) => any) {
return Object.fromEntries(targetEntries);
};
function serializeNativeImage (image: any) {
const representations = [];
const scaleFactors = image.getScaleFactors();
// Use Buffer when there's only one representation for better perf.
// This avoids compressing to/from PNG where it's not necessary to
// ensure uniqueness of dataURLs (since there's only one).
if (scaleFactors.length === 1) {
const scaleFactor = scaleFactors[0];
const size = image.getSize(scaleFactor);
const buffer = image.toBitmap({ scaleFactor });
representations.push({ scaleFactor, size, buffer });
} else {
// Construct from dataURLs to ensure that they are not lost in creation.
for (const scaleFactor of scaleFactors) {
const size = image.getSize(scaleFactor);
const dataURL = image.toDataURL({ scaleFactor });
representations.push({ scaleFactor, size, dataURL });
}
}
return { __ELECTRON_SERIALIZED_NativeImage__: true, representations };
}
function deserializeNativeImage (value: any) {
const image = nativeImage.createEmpty();
// Use Buffer when there's only one representation for better perf.
// This avoids compressing to/from PNG where it's not necessary to
// ensure uniqueness of dataURLs (since there's only one).
if (value.representations.length === 1) {
const { buffer, size, scaleFactor } = value.representations[0];
const { width, height } = size;
image.addRepresentation({ buffer, scaleFactor, width, height });
} else {
// Construct from dataURLs to ensure that they are not lost in creation.
for (const rep of value.representations) {
const { dataURL, size, scaleFactor } = rep;
const { width, height } = size;
image.addRepresentation({ dataURL, scaleFactor, width, height });
}
}
return image;
}
export function serialize (value: any): any {
if (value instanceof NativeImage) {
return {
buffer: value.toBitmap(),
size: value.getSize(),
__ELECTRON_SERIALIZED_NativeImage__: true
};
} else if (Array.isArray(value)) {
return serializeNativeImage(value);
} if (Array.isArray(value)) {
return value.map(serialize);
} else if (isSerializableObject(value)) {
return value;
@@ -53,7 +95,7 @@ export function serialize (value: any): any {
export function deserialize (value: any): any {
if (value && value.__ELECTRON_SERIALIZED_NativeImage__) {
return nativeImage.createFromBitmap(value.buffer, value.size);
return deserializeNativeImage(value);
} else if (Array.isArray(value)) {
return value.map(deserialize);
} else if (isSerializableObject(value)) {

View File

@@ -6,10 +6,6 @@ process.electronBinding = require('@electron/internal/common/electron-binding-se
const v8Util = process.electronBinding('v8_util');
// The `lib/renderer/ipc-renderer-internal.js` module looks for the ipc object in the
// "ipc-internal" hidden value
v8Util.setHiddenValue(global, 'ipc-internal', v8Util.getHiddenValue(isolatedWorld, 'ipc-internal'));
const webViewImpl = v8Util.getHiddenValue(isolatedWorld, 'web-view-impl');
if (webViewImpl) {
@@ -17,11 +13,3 @@ if (webViewImpl) {
const { setupWebView } = require('@electron/internal/renderer/web-view/web-view-element');
setupWebView(v8Util, webViewImpl);
}
const isolatedWorldArgs = v8Util.getHiddenValue(isolatedWorld, 'isolated-world-args');
if (isolatedWorldArgs) {
const { guestInstanceId, isHiddenPage, openerId, usesNativeWindowOpen } = isolatedWorldArgs;
const { windowSetup } = require('@electron/internal/renderer/window-setup');
windowSetup(guestInstanceId, openerId, isHiddenPage, usesNativeWindowOpen);
}

View File

@@ -11,10 +11,22 @@ const contextBridge = {
exposeInMainWorld: (key: string, api: Record<string, any>) => {
checkContextIsolationEnabled();
return binding.exposeAPIInMainWorld(key, api);
},
debugGC: () => binding._debugGCMaps({})
}
};
if (!binding._debugGCMaps) delete contextBridge.debugGC;
export default contextBridge;
export const internalContextBridge = {
contextIsolationEnabled,
overrideGlobalValueFromIsolatedWorld: (keys: string[], value: any) => {
return binding._overrideGlobalValueFromIsolatedWorld(keys, value, false);
},
overrideGlobalValueWithDynamicPropsFromIsolatedWorld: (keys: string[], value: any) => {
return binding._overrideGlobalValueFromIsolatedWorld(keys, value, true);
},
overrideGlobalPropertyFromIsolatedWorld: (keys: string[], getter: Function, setter?: Function) => {
return binding._overrideGlobalPropertyFromIsolatedWorld(keys, getter, setter || null);
},
isInMainWorld: () => binding._isCalledFromMainWorld() as boolean,
isInIsolatedWorld: () => binding._isCalledFromIsolatedWorld() as boolean
};

View File

@@ -5,28 +5,30 @@ const v8Util = process.electronBinding('v8_util');
const ipcRenderer = v8Util.getHiddenValue<Electron.IpcRenderer>(global, 'ipc');
const internal = false;
ipcRenderer.send = function (channel, ...args) {
return ipc.send(internal, channel, args);
};
if (!ipcRenderer.send) {
ipcRenderer.send = function (channel, ...args) {
return ipc.send(internal, channel, args);
};
ipcRenderer.sendSync = function (channel, ...args) {
return ipc.sendSync(internal, channel, args)[0];
};
ipcRenderer.sendSync = function (channel, ...args) {
return ipc.sendSync(internal, channel, args)[0];
};
ipcRenderer.sendToHost = function (channel, ...args) {
return ipc.sendToHost(channel, args);
};
ipcRenderer.sendToHost = function (channel, ...args) {
return ipc.sendToHost(channel, args);
};
ipcRenderer.sendTo = function (webContentsId, channel, ...args) {
return ipc.sendTo(internal, false, webContentsId, channel, args);
};
ipcRenderer.sendTo = function (webContentsId, channel, ...args) {
return ipc.sendTo(internal, false, webContentsId, channel, args);
};
ipcRenderer.invoke = async function (channel, ...args) {
const { error, result } = await ipc.invoke(internal, channel, args);
if (error) {
throw new Error(`Error invoking remote method '${channel}': ${error}`);
}
return result;
};
ipcRenderer.invoke = async function (channel, ...args) {
const { error, result } = await ipc.invoke(internal, channel, args);
if (error) {
throw new Error(`Error invoking remote method '${channel}': ${error}`);
}
return result;
};
}
export default ipcRenderer;

View File

@@ -2,9 +2,10 @@
const v8Util = process.electronBinding('v8_util');
const { hasSwitch } = process.electronBinding('command_line');
const { NativeImage } = process.electronBinding('native_image');
const { CallbacksRegistry } = require('@electron/internal/renderer/remote/callbacks-registry');
const { isPromise, isSerializableObject } = require('@electron/internal/common/type-utils');
const { isPromise, isSerializableObject, serialize, deserialize } = require('@electron/internal/common/type-utils');
const { ipcRendererInternal } = require('@electron/internal/renderer/ipc-renderer-internal');
const callbacksRegistry = new CallbacksRegistry();
@@ -33,7 +34,9 @@ function wrapArgs (args, visited = new Set()) {
};
}
if (Array.isArray(value)) {
if (value instanceof NativeImage) {
return { type: 'nativeimage', value: serialize(value) };
} else if (Array.isArray(value)) {
visited.add(value);
const meta = {
type: 'array',
@@ -213,6 +216,7 @@ function metaToValue (meta) {
const types = {
value: () => meta.value,
array: () => meta.members.map((member) => metaToValue(member)),
nativeimage: () => deserialize(meta.value),
buffer: () => Buffer.from(meta.value.buffer, meta.value.byteOffset, meta.value.byteLength),
promise: () => Promise.resolve({ then: metaToValue(meta.then) }),
error: () => metaToError(meta),

View File

@@ -5,26 +5,28 @@ const v8Util = process.electronBinding('v8_util');
export const ipcRendererInternal = v8Util.getHiddenValue<Electron.IpcRendererInternal>(global, 'ipc-internal');
const internal = true;
ipcRendererInternal.send = function (channel, ...args) {
return ipc.send(internal, channel, args);
};
if (!ipcRendererInternal.send) {
ipcRendererInternal.send = function (channel, ...args) {
return ipc.send(internal, channel, args);
};
ipcRendererInternal.sendSync = function (channel, ...args) {
return ipc.sendSync(internal, channel, args)[0];
};
ipcRendererInternal.sendSync = function (channel, ...args) {
return ipc.sendSync(internal, channel, args)[0];
};
ipcRendererInternal.sendTo = function (webContentsId, channel, ...args) {
return ipc.sendTo(internal, false, webContentsId, channel, args);
};
ipcRendererInternal.sendTo = function (webContentsId, channel, ...args) {
return ipc.sendTo(internal, false, webContentsId, channel, args);
};
ipcRendererInternal.sendToAll = function (webContentsId, channel, ...args) {
return ipc.sendTo(internal, true, webContentsId, channel, args);
};
ipcRendererInternal.sendToAll = function (webContentsId, channel, ...args) {
return ipc.sendTo(internal, true, webContentsId, channel, args);
};
ipcRendererInternal.invoke = async function<T> (channel: string, ...args: any[]) {
const { error, result } = await ipc.invoke<T>(internal, channel, args);
if (error) {
throw new Error(`Error invoking remote method '${channel}': ${error}`);
}
return result;
};
ipcRendererInternal.invoke = async function<T> (channel: string, ...args: any[]) {
const { error, result } = await ipc.invoke<T>(internal, channel, args);
if (error) {
throw new Error(`Error invoking remote method '${channel}': ${error}`);
}
return result;
};
}

View File

@@ -110,9 +110,14 @@ export function attachGuest (
ipcRendererInternal.invoke('ELECTRON_GUEST_VIEW_MANAGER_ATTACH_GUEST', embedderFrameId, elementInstanceId, guestInstanceId, params);
}
export function detachGuest (guestInstanceId: number) {
return ipcRendererUtils.invokeSync('ELECTRON_GUEST_VIEW_MANAGER_DETACH_GUEST', guestInstanceId);
}
export const guestViewInternalModule = {
deregisterEvents,
createGuest,
createGuestSync,
attachGuest
attachGuest,
detachGuest
};

View File

@@ -66,6 +66,9 @@ const defineWebViewElement = (v8Util: NodeJS.V8UtilBinding, webViewImpl: typeof
return;
}
guestViewInternal.deregisterEvents(internal.viewInstanceId);
if (internal.guestInstanceId) {
guestViewInternal.detachGuest(internal.guestInstanceId);
}
internal.elementAttached = false;
this.internalInstanceId = 0;
internal.reset();

View File

@@ -1,11 +1,11 @@
import { ipcRendererInternal } from '@electron/internal/renderer/ipc-renderer-internal';
import * as ipcRendererUtils from '@electron/internal/renderer/ipc-renderer-internal-utils';
import { internalContextBridge } from '@electron/internal/renderer/api/context-bridge';
// This file implements the following APIs:
// - window.history.back()
// - window.history.forward()
// - window.history.go()
// - window.history.length
const { contextIsolationEnabled, isInIsolatedWorld } = internalContextBridge;
const shouldUseContextBridge = contextIsolationEnabled && isInIsolatedWorld();
// This file implements the following APIs over the ctx bridge:
// - window.open()
// - window.opener.blur()
// - window.opener.close()
@@ -13,7 +13,12 @@ import * as ipcRendererUtils from '@electron/internal/renderer/ipc-renderer-inte
// - window.opener.focus()
// - window.opener.location
// - window.opener.print()
// - window.opener.closed
// - window.opener.postMessage()
// - window.history.back()
// - window.history.forward()
// - window.history.go()
// - window.history.length
// - window.prompt()
// - document.hidden
// - document.visibilityState
@@ -30,13 +35,13 @@ const toString = (value: any) => {
const windowProxies = new Map<number, BrowserWindowProxy>();
const getOrCreateProxy = (guestId: number) => {
const getOrCreateProxy = (guestId: number): SafelyBoundBrowserWindowProxy => {
let proxy = windowProxies.get(guestId);
if (proxy == null) {
proxy = new BrowserWindowProxy(guestId);
windowProxies.set(guestId, proxy);
}
return proxy;
return proxy.getSafe();
};
const removeProxy = (guestId: number) => {
@@ -64,6 +69,8 @@ class LocationProxy {
*/
private static ProxyProperty<T> (target: LocationProxy, propertyKey: LocationProperties) {
Object.defineProperty(target, propertyKey, {
enumerable: true,
configurable: true,
get: function (this: LocationProxy): T | string {
const guestURL = this.getGuestURL();
const value = guestURL ? guestURL[propertyKey] : '';
@@ -82,6 +89,30 @@ class LocationProxy {
});
}
public getSafe = () => {
const that = this;
return {
get href () { return that.href; },
set href (newValue) { that.href = newValue; },
get hash () { return that.hash; },
set hash (newValue) { that.hash = newValue; },
get host () { return that.host; },
set host (newValue) { that.host = newValue; },
get hostname () { return that.hostname; },
set hostname (newValue) { that.hostname = newValue; },
get origin () { return that.origin; },
set origin (newValue) { that.origin = newValue; },
get pathname () { return that.pathname; },
set pathname (newValue) { that.pathname = newValue; },
get port () { return that.port; },
set port (newValue) { that.port = newValue; },
get protocol () { return that.protocol; },
set protocol (newValue) { that.protocol = newValue; },
get search () { return that.search; },
set search (newValue) { that.search = newValue; }
};
}
constructor (guestId: number) {
// eslint will consider the constructor "useless"
// unless we assign them in the body. It's fine, that's what
@@ -95,7 +126,11 @@ class LocationProxy {
}
private getGuestURL (): URL | null {
const urlString = this._invokeWebContentsMethodSync('getURL') as string;
const maybeURL = this._invokeWebContentsMethodSync('getURL') as string;
// When there's no previous frame the url will be blank, so accountfor that here
// to prevent url parsing errors on an empty string.
const urlString = maybeURL !== '' ? maybeURL : 'about:blank';
try {
return new URL(urlString);
} catch (e) {
@@ -114,6 +149,17 @@ class LocationProxy {
}
}
interface SafelyBoundBrowserWindowProxy {
location: WindowProxy['location'];
blur: WindowProxy['blur'];
close: WindowProxy['close'];
eval: typeof eval; // eslint-disable-line no-eval
focus: WindowProxy['focus'];
print: WindowProxy['print'];
postMessage: WindowProxy['postMessage'];
closed: boolean;
}
class BrowserWindowProxy {
public closed: boolean = false
@@ -124,7 +170,7 @@ class BrowserWindowProxy {
// so for now, we'll have to make do with an "any" in the mix.
// https://github.com/Microsoft/TypeScript/issues/2521
public get location (): LocationProxy | any {
return this._location;
return this._location.getSafe();
}
public set location (url: string | any) {
url = resolveURL(url, this.location.href);
@@ -141,27 +187,48 @@ class BrowserWindowProxy {
});
}
public close () {
public getSafe = (): SafelyBoundBrowserWindowProxy => {
const that = this;
return {
postMessage: this.postMessage,
blur: this.blur,
close: this.close,
focus: this.focus,
print: this.print,
eval: this.eval,
get location () {
return that.location;
},
set location (url: string | any) {
that.location = url;
},
get closed () {
return that.closed;
}
};
}
public close = () => {
this._invokeWindowMethod('destroy');
}
public focus () {
public focus = () => {
this._invokeWindowMethod('focus');
}
public blur () {
public blur = () => {
this._invokeWindowMethod('blur');
}
public print () {
public print = () => {
this._invokeWebContentsMethod('print');
}
public postMessage (message: any, targetOrigin: string) {
public postMessage = (message: any, targetOrigin: string) => {
ipcRendererInternal.invoke('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_POSTMESSAGE', this.guestId, message, toString(targetOrigin), window.location.origin);
}
public eval (code: string) {
public eval = (code: string) => {
this._invokeWebContentsMethod('executeJavaScript', code);
}
@@ -182,9 +249,11 @@ export const windowSetup = (
window.close = function () {
ipcRendererInternal.sendSync('ELECTRON_BROWSER_WINDOW_CLOSE');
};
if (shouldUseContextBridge) internalContextBridge.overrideGlobalValueFromIsolatedWorld(['close'], window.close);
}
if (!usesNativeWindowOpen) {
// TODO(MarshallOfSound): Make compatible with ctx isolation without hole-punch
// Make the browser window or guest view emit "new-window" event.
(window as any).open = function (url?: string, frameName?: string, features?: string) {
if (url != null && url !== '') {
@@ -197,16 +266,19 @@ export const windowSetup = (
return null;
}
};
if (shouldUseContextBridge) internalContextBridge.overrideGlobalValueWithDynamicPropsFromIsolatedWorld(['open'], window.open);
}
if (openerId != null) {
window.opener = getOrCreateProxy(openerId);
if (shouldUseContextBridge) internalContextBridge.overrideGlobalValueWithDynamicPropsFromIsolatedWorld(['opener'], window.opener);
}
// But we do not support prompt().
window.prompt = function () {
throw new Error('prompt() is and will not be supported.');
};
if (shouldUseContextBridge) internalContextBridge.overrideGlobalValueFromIsolatedWorld(['prompt'], window.prompt);
if (!usesNativeWindowOpen || openerId != null) {
ipcRendererInternal.on('ELECTRON_GUEST_WINDOW_POSTMESSAGE', function (
@@ -233,20 +305,25 @@ export const windowSetup = (
window.history.back = function () {
ipcRendererInternal.send('ELECTRON_NAVIGATION_CONTROLLER_GO_BACK');
};
if (shouldUseContextBridge) internalContextBridge.overrideGlobalValueFromIsolatedWorld(['history', 'back'], window.history.back);
window.history.forward = function () {
ipcRendererInternal.send('ELECTRON_NAVIGATION_CONTROLLER_GO_FORWARD');
};
if (shouldUseContextBridge) internalContextBridge.overrideGlobalValueFromIsolatedWorld(['history', 'forward'], window.history.forward);
window.history.go = function (offset: number) {
ipcRendererInternal.send('ELECTRON_NAVIGATION_CONTROLLER_GO_TO_OFFSET', +offset);
};
if (shouldUseContextBridge) internalContextBridge.overrideGlobalValueFromIsolatedWorld(['history', 'go'], window.history.go);
const getHistoryLength = () => ipcRendererInternal.sendSync('ELECTRON_NAVIGATION_CONTROLLER_LENGTH');
Object.defineProperty(window.history, 'length', {
get: function () {
return ipcRendererInternal.sendSync('ELECTRON_NAVIGATION_CONTROLLER_LENGTH');
}
get: getHistoryLength,
set () {}
});
// TODO(MarshallOfSound): Fix so that the internal context bridge can override a non-configurable property
// if (shouldUseContextBridge) internalContextBridge.overrideGlobalPropertyFromIsolatedWorld(['history', 'length'], getHistoryLength);
}
if (guestInstanceId != null) {
@@ -268,16 +345,16 @@ export const windowSetup = (
});
// Make document.hidden and document.visibilityState return the correct value.
const getDocumentHidden = () => cachedVisibilityState !== 'visible';
Object.defineProperty(document, 'hidden', {
get: function () {
return cachedVisibilityState !== 'visible';
}
get: getDocumentHidden
});
if (shouldUseContextBridge) internalContextBridge.overrideGlobalPropertyFromIsolatedWorld(['document', 'hidden'], getDocumentHidden);
const getDocumentVisibilityState = () => cachedVisibilityState;
Object.defineProperty(document, 'visibilityState', {
get: function () {
return cachedVisibilityState;
}
get: getDocumentVisibilityState
});
if (shouldUseContextBridge) internalContextBridge.overrideGlobalPropertyFromIsolatedWorld(['document', 'visibilityState'], getDocumentVisibilityState);
}
};

View File

@@ -114,6 +114,12 @@ function preloadRequire (module) {
// Process command line arguments.
const { hasSwitch } = process.electronBinding('command_line');
// Similar to nodes --expose-internals flag, this exposes electronBinding so
// that tests can call it to get access to some test only bindings
if (hasSwitch('unsafely-expose-electron-internals-for-testing')) {
preloadProcess.electronBinding = process.electronBinding;
}
const contextIsolation = hasSwitch('context-isolation');
const isHiddenPage = hasSwitch('hidden-page');
const usesNativeWindowOpen = true;

View File

@@ -23,6 +23,8 @@ source_set("native_mate") {
"native_mate/function_template.cc",
"native_mate/function_template.h",
"native_mate/handle.h",
"native_mate/microtasks_scope.cc",
"native_mate/microtasks_scope.h",
"native_mate/object_template_builder.cc",
"native_mate/object_template_builder_deprecated.h",
"native_mate/persistent_dictionary.cc",

View File

@@ -9,6 +9,7 @@
#include "base/callback.h"
#include "native_mate/arguments.h"
#include "native_mate/microtasks_scope.h"
#include "native_mate/wrappable_base.h"
#include "shell/common/gin_helper/destroyable.h"
#include "shell/common/gin_helper/error_thrower.h"
@@ -194,8 +195,7 @@ class Invoker<IndicesHolder<indices...>, ArgTypes...>
template <typename ReturnType>
void DispatchToCallback(base::Callback<ReturnType(ArgTypes...)> callback) {
v8::MicrotasksScope script_scope(args_->isolate(),
v8::MicrotasksScope::kRunMicrotasks);
mate::MicrotasksScope microtasks_scope(args_->isolate(), true);
args_->Return(
callback.Run(std::move(ArgumentHolder<indices, ArgTypes>::value)...));
}
@@ -204,8 +204,7 @@ class Invoker<IndicesHolder<indices...>, ArgTypes...>
// expression to foo. As a result, we must specialize the case of Callbacks
// that have the void return type.
void DispatchToCallback(base::Callback<void(ArgTypes...)> callback) {
v8::MicrotasksScope script_scope(args_->isolate(),
v8::MicrotasksScope::kRunMicrotasks);
mate::MicrotasksScope microtasks_scope(args_->isolate(), true);
callback.Run(std::move(ArgumentHolder<indices, ArgTypes>::value)...);
}

View File

@@ -0,0 +1,22 @@
// Copyright (c) 2020 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "native_mate/microtasks_scope.h"
namespace mate {
MicrotasksScope::MicrotasksScope(v8::Isolate* isolate,
bool ignore_browser_checkpoint) {
if (v8::Locker::IsActive()) {
if (!ignore_browser_checkpoint)
v8::MicrotasksScope::PerformCheckpoint(isolate);
} else {
v8_microtasks_scope_ = std::make_unique<v8::MicrotasksScope>(
isolate, v8::MicrotasksScope::kRunMicrotasks);
}
}
MicrotasksScope::~MicrotasksScope() = default;
} // namespace mate

View File

@@ -0,0 +1,31 @@
// Copyright (c) 2020 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef NATIVE_MATE_NATIVE_MATE_MICROTASKS_SCOPE_H_
#define NATIVE_MATE_NATIVE_MATE_MICROTASKS_SCOPE_H_
#include <memory>
#include "base/macros.h"
#include "v8/include/v8.h"
namespace mate {
// In the browser process runs v8::MicrotasksScope::PerformCheckpoint
// In the render process creates a v8::MicrotasksScope.
class MicrotasksScope {
public:
explicit MicrotasksScope(v8::Isolate* isolate,
bool ignore_browser_checkpoint = false);
~MicrotasksScope();
private:
std::unique_ptr<v8::MicrotasksScope> v8_microtasks_scope_;
DISALLOW_COPY_AND_ASSIGN(MicrotasksScope);
};
} // namespace mate
#endif // NATIVE_MATE_NATIVE_MATE_MICROTASKS_SCOPE_H_

View File

@@ -1,6 +1,6 @@
{
"name": "electron",
"version": "8.2.0",
"version": "8.5.0",
"repository": "https://github.com/electron/electron",
"description": "Build cross platform desktop apps with JavaScript, HTML, and CSS",
"devDependencies": {

1
patches/angle/.patches Normal file
View File

@@ -0,0 +1 @@
update_the_active_texture_cache_before_changing_the_texture_binding.patch

View File

@@ -0,0 +1,38 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Geoff Lang <geofflang@chromium.org>
Date: Fri, 27 Mar 2020 12:24:52 -0400
Subject: Update the active texture cache before changing the texture binding.
When a new texture is bound, the texture binding state is updated before
updating the active texture cache. With this ordering, it is possible to delete
the currently bound texture when the binding changes and then use-after-free it
when updating the active texture cache.
BUG=angleproject:1065186
Change-Id: Id6d56b6c6db423755b195cda1e5cf1bcb1ee7aee
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2124588
Commit-Queue: Geoff Lang <geofflang@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/State.cpp b/src/libANGLE/State.cpp
index 3fab8404046846e5b8ed6253139537360e83c409..c6c6ee75ebf554ce47cfcef218dca6a22075a4aa 100644
--- a/src/libANGLE/State.cpp
+++ b/src/libANGLE/State.cpp
@@ -1138,14 +1138,14 @@ void State::setActiveSampler(unsigned int active)
void State::setSamplerTexture(const Context *context, TextureType type, Texture *texture)
{
- mSamplerTextures[type][mActiveSampler].set(context, texture);
-
if (mProgram && mProgram->getActiveSamplersMask()[mActiveSampler] &&
mProgram->getActiveSamplerTypes()[mActiveSampler] == type)
{
updateActiveTexture(context, mActiveSampler, texture);
}
+ mSamplerTextures[type][mActiveSampler].set(context, texture);
+
mDirtyBits.set(DIRTY_BIT_TEXTURE_BINDINGS);
}

View File

@@ -1,3 +1,3 @@
expose_ripemd160.patch
expose_aes-cfb.patch
fix_add_RSA-PSS_keygen_functions.patch
fix_add_RSA-PSS_keygen_functions.patch

View File

@@ -90,3 +90,33 @@ fix_route_mouse_event_navigations_through_the_web_contents_delegate.patch
feat_add_support_for_overriding_the_base_spellchecker_download_url.patch
os_metrics_mac.patch
feat_allow_embedders_to_add_observers_on_created_hunspell.patch
feat_enable_offscreen_rendering_with_viz_compositor.patch
when_suspending_context_don_t_clear_handlers.patch
use_keepselfalive_on_audiocontext_to_keep_it_alive_until_rendering.patch
never_let_a_non-zero-size_pixel_snap_to_zero_size.patch
cherry-pick-826a4af58b3d.patch
cherry-pick-686d1bfbcb8f.patch
cherry-pick-7101418f85a0.patch
cherry-pick-38990b7d56e6.patch
cherry-pick-67864c214770.patch
cherry-pick-86c02c5dcd37.patch
fix_hunspell_crash.patch
avoid_nullptr_dereference_in_rtcpeerconnectionhandler.patch
reland_onstate_handler_is_allowed_to_close_a_peerconnection.patch
fix_swap_global_proxies_before_initializing_the_windows_proxies.patch
fix_default_to_ntlm_v2_in_network_service.patch
a11y_allows_klistboxoption_as_an_item_to_kgroup.patch
fix_handling_non_client_pointer_events_from_pen_on_windows_10.patch
a11y_iterate_all_descendants_for_getselectioncount.patch
allow_ime_to_insert_zero-length_composition_string.patch
cherry-pick-eac3d9283d11.patch
remove_menu_window_task_item.patch
backport_1063177.patch
backport_1019161.patch
avoid_using_x11_shm_for_remote_connections.patch
backport_1065122.patch
backport_1074317.patch
backport_1090543.patch
backport_1081722.patch
backport_1073409.patch
backport_1074340.patch

View File

@@ -0,0 +1,80 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Julie Jeongeun Kim <jkim@igalia.com>
Date: Fri, 3 Apr 2020 19:22:20 +0000
Subject: a11y: Allows kListBoxOption as an item to kGroup
This CL adds ListBoxOption role as an item for Group role in
AXNode::SetRoleMatchesItemRole() since Group role could have
ListBoxOption as an item[1]. With this change, when the parent
of ListBoxOption is a group role, PosInSet and SetSize has
proper values.
[1]https://w3c.github.io/aria-practices/examples/listbox/listbox-grouped.html
Bug: 1066632
Change-Id: I23cf0c34ee479d6e8ee33b3f9e327def820527e1
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2134037
Commit-Queue: Dominic Mazzoni <dmazzoni@chromium.org>
Reviewed-by: Dominic Mazzoni <dmazzoni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#756360}
diff --git a/ui/accessibility/ax_node.cc b/ui/accessibility/ax_node.cc
index df021746aab26a61096922e902815931af4621dc..d4451bbb638b42164fe8ec9f4c37a0d93efd8aa3 100644
--- a/ui/accessibility/ax_node.cc
+++ b/ui/accessibility/ax_node.cc
@@ -778,6 +778,7 @@ bool AXNode::SetRoleMatchesItemRole(const AXNode* ordered_set) const {
return item_role == ax::mojom::Role::kListItem ||
item_role == ax::mojom::Role::kMenuItem ||
item_role == ax::mojom::Role::kMenuItemRadio ||
+ item_role == ax::mojom::Role::kListBoxOption ||
item_role == ax::mojom::Role::kTreeItem;
case ax::mojom::Role::kMenu:
return item_role == ax::mojom::Role::kMenuItem ||
diff --git a/ui/accessibility/ax_tree_unittest.cc b/ui/accessibility/ax_tree_unittest.cc
index 84952172938446254e53c2ee11cba37433d0e991..91a7be0f349116dc48cbe543104a6e7828ddf2e8 100644
--- a/ui/accessibility/ax_tree_unittest.cc
+++ b/ui/accessibility/ax_tree_unittest.cc
@@ -3549,6 +3549,43 @@ TEST(AXTreeTest, TestSetSizePosInSetMenuItemValidChildOfMenuListPopup) {
EXPECT_OPTIONAL_EQ(2, item2->GetSetSize());
}
+TEST(AXTreeTest, TestSetSizePostInSetListBoxOptionWithGroup) {
+ AXTreeUpdate initial_state;
+ initial_state.root_id = 1;
+ initial_state.nodes.resize(7);
+ initial_state.nodes[0].id = 1;
+ initial_state.nodes[0].child_ids = {2, 3};
+ initial_state.nodes[0].role = ax::mojom::Role::kListBox;
+ initial_state.nodes[1].id = 2;
+ initial_state.nodes[1].child_ids = {4, 5};
+ initial_state.nodes[1].role = ax::mojom::Role::kGroup;
+ initial_state.nodes[2].id = 3;
+ initial_state.nodes[2].child_ids = {6, 7};
+ initial_state.nodes[2].role = ax::mojom::Role::kGroup;
+ initial_state.nodes[3].id = 4;
+ initial_state.nodes[3].role = ax::mojom::Role::kListBoxOption;
+ initial_state.nodes[4].id = 5;
+ initial_state.nodes[4].role = ax::mojom::Role::kListBoxOption;
+ initial_state.nodes[5].id = 6;
+ initial_state.nodes[5].role = ax::mojom::Role::kListBoxOption;
+ initial_state.nodes[6].id = 7;
+ initial_state.nodes[6].role = ax::mojom::Role::kListBoxOption;
+ AXTree tree(initial_state);
+
+ AXNode* listbox_option1 = tree.GetFromId(4);
+ EXPECT_OPTIONAL_EQ(1, listbox_option1->GetPosInSet());
+ EXPECT_OPTIONAL_EQ(2, listbox_option1->GetSetSize());
+ AXNode* listbox_option2 = tree.GetFromId(5);
+ EXPECT_OPTIONAL_EQ(2, listbox_option2->GetPosInSet());
+ EXPECT_OPTIONAL_EQ(2, listbox_option2->GetSetSize());
+ AXNode* listbox_option3 = tree.GetFromId(6);
+ EXPECT_OPTIONAL_EQ(1, listbox_option3->GetPosInSet());
+ EXPECT_OPTIONAL_EQ(2, listbox_option3->GetSetSize());
+ AXNode* listbox_option4 = tree.GetFromId(7);
+ EXPECT_OPTIONAL_EQ(2, listbox_option4->GetPosInSet());
+ EXPECT_OPTIONAL_EQ(2, listbox_option4->GetSetSize());
+}
+
TEST(AXTreeTest, OnNodeWillBeDeletedHasValidUnignoredParent) {
AXTreeUpdate initial_state;
initial_state.root_id = 1;

View File

@@ -0,0 +1,393 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Julie Jeongeun Kim <jkim@igalia.com>
Date: Fri, 10 Apr 2020 05:50:17 +0000
Subject: a11y: Iterate all descendants for GetSelectionCount
This CL iterates all descendants for GetSelectionCount and
GetSelectedChild. When listbox has group children, it should
iterates their children as well to check the select state.
Bug: 1058961
Change-Id: Ib6459bf6f47023d4258ef4c2f2dc545739d7a61b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2115211
Commit-Queue: Julie Kim <jkim@igalia.com>
Reviewed-by: Nektarios Paisios <nektar@chromium.org>
Reviewed-by: Aaron Leventhal <aleventhal@chromium.org>
Reviewed-by: Joanmarie Diggs <jdiggs@igalia.com>
Cr-Commit-Position: refs/heads/master@{#758140}
diff --git a/ui/accessibility/platform/ax_platform_node_auralinux.cc b/ui/accessibility/platform/ax_platform_node_auralinux.cc
index 86ce9de34a5286b1c3990c4aab614450e1d6fb63..88528364e148284b7e45958451a65497c295f256 100644
--- a/ui/accessibility/platform/ax_platform_node_auralinux.cc
+++ b/ui/accessibility/platform/ax_platform_node_auralinux.cc
@@ -1435,19 +1435,10 @@ AtkObject* RefSelection(AtkSelection* selection, gint requested_child_index) {
if (!obj)
return nullptr;
- int child_count = obj->GetChildCount();
- gint selected_count = 0;
- for (int i = 0; i < child_count; ++i) {
- AtkObject* child = obj->ChildAtIndex(i);
- AXPlatformNodeAuraLinux* child_ax_node =
- AtkObjectToAXPlatformNodeAuraLinux(child);
- if (!child_ax_node)
- continue;
-
- if (child_ax_node->GetBoolAttribute(ax::mojom::BoolAttribute::kSelected)) {
- if (selected_count == requested_child_index)
- return static_cast<AtkObject*>(g_object_ref(child));
- ++selected_count;
+ if (auto* selected_child = obj->GetSelectedItem(requested_child_index)) {
+ if (AtkObject* atk_object = selected_child->GetNativeViewAccessible()) {
+ g_object_ref(atk_object);
+ return atk_object;
}
}
@@ -1460,19 +1451,7 @@ gint GetSelectionCount(AtkSelection* selection) {
if (!obj)
return 0;
- int child_count = obj->GetChildCount();
- gint selected_count = 0;
- for (int i = 0; i < child_count; ++i) {
- AXPlatformNodeAuraLinux* child =
- AtkObjectToAXPlatformNodeAuraLinux(obj->ChildAtIndex(i));
- if (!child)
- continue;
-
- if (child->GetBoolAttribute(ax::mojom::BoolAttribute::kSelected))
- ++selected_count;
- }
-
- return selected_count;
+ return obj->GetSelectionCount();
}
gboolean IsChildSelected(AtkSelection* selection, gint index) {
diff --git a/ui/accessibility/platform/ax_platform_node_auralinux_unittest.cc b/ui/accessibility/platform/ax_platform_node_auralinux_unittest.cc
index f17dbeda08917ef636f1f4342011394f076cee35..eb61fc1c1224e8a2ca94929e07f24bfa7dc41691 100644
--- a/ui/accessibility/platform/ax_platform_node_auralinux_unittest.cc
+++ b/ui/accessibility/platform/ax_platform_node_auralinux_unittest.cc
@@ -1853,6 +1853,8 @@ TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkSelectionInterface) {
AXNodeData root;
root.id = 1;
root.role = ax::mojom::Role::kListBox;
+ root.AddState(ax::mojom::State::kFocusable);
+ root.AddState(ax::mojom::State::kMultiselectable);
root.child_ids.push_back(2);
root.child_ids.push_back(3);
root.child_ids.push_back(4);
diff --git a/ui/accessibility/platform/ax_platform_node_base.cc b/ui/accessibility/platform/ax_platform_node_base.cc
index d705cd927ed816208b22106e5beb30c550c55ca3..bf9dc27604ff5ae7f88c8fd734ec26c699e7bc04 100644
--- a/ui/accessibility/platform/ax_platform_node_base.cc
+++ b/ui/accessibility/platform/ax_platform_node_base.cc
@@ -92,7 +92,7 @@ int AXPlatformNodeBase::GetChildCount() const {
return 0;
}
-gfx::NativeViewAccessible AXPlatformNodeBase::ChildAtIndex(int index) {
+gfx::NativeViewAccessible AXPlatformNodeBase::ChildAtIndex(int index) const {
if (delegate_)
return delegate_->ChildAtIndex(index);
return nullptr;
@@ -701,8 +701,8 @@ bool AXPlatformNodeBase::HasCaret() {
return focus_object->IsDescendantOf(this);
}
-bool AXPlatformNodeBase::IsLeaf() {
- if (GetChildCount() == 0)
+bool AXPlatformNodeBase::IsLeaf() const {
+ if (!GetChildCount())
return true;
// These types of objects may have children that we use as internal
@@ -1868,9 +1868,73 @@ ui::TextAttributeList AXPlatformNodeBase::ComputeTextAttributes() const {
return attributes;
}
+int AXPlatformNodeBase::GetSelectionCount() const {
+ int max_items = GetMaxSelectableItems();
+ if (!max_items)
+ return 0;
+ return GetSelectedItems(max_items);
+}
+
+AXPlatformNodeBase* AXPlatformNodeBase::GetSelectedItem(
+ int selected_index) const {
+ DCHECK_GE(selected_index, 0);
+ int max_items = GetMaxSelectableItems();
+ if (max_items == 0)
+ return nullptr;
+ if (selected_index >= max_items)
+ return nullptr;
+
+ std::vector<AXPlatformNodeBase*> selected_children;
+ int requested_count = selected_index + 1;
+ int returned_count = GetSelectedItems(requested_count, &selected_children);
+
+ if (returned_count <= selected_index)
+ return nullptr;
+
+ DCHECK(!selected_children.empty());
+ DCHECK_LT(selected_index, static_cast<int>(selected_children.size()));
+ return selected_children[selected_index];
+}
+
+int AXPlatformNodeBase::GetSelectedItems(
+ int max_items,
+ std::vector<AXPlatformNodeBase*>* out_selected_items) const {
+ int selected_count = 0;
+ // TODO(Nektar): Remove const_cast by making all tree traversal methods const.
+ for (AXPlatformNodeBase* child =
+ const_cast<AXPlatformNodeBase*>(this)->GetFirstChild();
+ child && selected_count < max_items; child = child->GetNextSibling()) {
+ if (!IsItemLike(child->GetData().role)) {
+ selected_count += child->GetSelectedItems(max_items - selected_count,
+ out_selected_items);
+ } else if (child->GetBoolAttribute(ax::mojom::BoolAttribute::kSelected)) {
+ selected_count++;
+ if (out_selected_items)
+ out_selected_items->emplace_back(child);
+ }
+ }
+ return selected_count;
+}
+
void AXPlatformNodeBase::SanitizeTextAttributeValue(const std::string& input,
std::string* output) const {
DCHECK(output);
}
+int AXPlatformNodeBase::GetMaxSelectableItems() const {
+ if (!GetData().HasState(ax::mojom::State::kFocusable))
+ return 0;
+
+ if (IsLeaf())
+ return 0;
+
+ if (!IsContainerWithSelectableChildren(GetData().role))
+ return 0;
+
+ int max_items = 1;
+ if (GetData().HasState(ax::mojom::State::kMultiselectable))
+ max_items = std::numeric_limits<int>::max();
+ return max_items;
+}
+
} // namespace ui
diff --git a/ui/accessibility/platform/ax_platform_node_base.h b/ui/accessibility/platform/ax_platform_node_base.h
index 2bee9a7e3108963847486139d40a087428323fbb..98a72c6be316803618f74ae0766e1fd24515509a 100644
--- a/ui/accessibility/platform/ax_platform_node_base.h
+++ b/ui/accessibility/platform/ax_platform_node_base.h
@@ -57,7 +57,7 @@ class AX_EXPORT AXPlatformNodeBase : public AXPlatformNode {
gfx::NativeViewAccessible GetFocus();
gfx::NativeViewAccessible GetParent() const;
int GetChildCount() const;
- gfx::NativeViewAccessible ChildAtIndex(int index);
+ gfx::NativeViewAccessible ChildAtIndex(int index) const;
// This needs to be implemented for each platform.
virtual int GetIndexInParent();
@@ -202,7 +202,7 @@ class AX_EXPORT AXPlatformNodeBase : public AXPlatformNode {
// The definition of a leaf may vary depending on the platform,
// but a leaf node should never have children that are focusable or
// that might send notifications.
- bool IsLeaf();
+ bool IsLeaf() const;
bool IsInvisibleOrIgnored() const;
@@ -275,6 +275,24 @@ class AX_EXPORT AXPlatformNodeBase : public AXPlatformNode {
ui::TextAttributeList ComputeTextAttributes() const;
+ // Get the number of items selected. It checks kMultiselectable and
+ // kFocusable. and uses GetSelectedItems to get the selected number.
+ int GetSelectionCount() const;
+
+ // If this object is a container that supports selectable children, returns
+ // the selected item at the provided index.
+ AXPlatformNodeBase* GetSelectedItem(int selected_index) const;
+
+ // If this object is a container that supports selectable children,
+ // returns the number of selected items in this container.
+ // |out_selected_items| could be set to nullptr if the caller just
+ // needs to know the number of items selected.
+ // |max_items| represents the number that the caller expects as a
+ // maximum. For a single selection list box, it will be 1.
+ int GetSelectedItems(
+ int max_items,
+ std::vector<AXPlatformNodeBase*>* out_selected_items = nullptr) const;
+
//
// Delegate. This is a weak reference which owns |this|.
//
@@ -412,6 +430,11 @@ class AX_EXPORT AXPlatformNodeBase : public AXPlatformNode {
std::string GetInvalidValue() const;
+ // Based on the characteristics of this object, such as its role and the
+ // presence of a multiselectable attribute, returns the maximum number of
+ // selectable children that this object could potentially contain.
+ int GetMaxSelectableItems() const;
+
AXHypertext hypertext_;
private:
diff --git a/ui/accessibility/platform/ax_platform_node_unittest.cc b/ui/accessibility/platform/ax_platform_node_unittest.cc
index 9950894e9fbb30b79b392ffe782dd31f75bd7f52..d8bfc0ed9c2b20c64dd15f3c6c2ef8cfaa87c510 100644
--- a/ui/accessibility/platform/ax_platform_node_unittest.cc
+++ b/ui/accessibility/platform/ax_platform_node_unittest.cc
@@ -379,13 +379,13 @@ AXTreeUpdate AXPlatformNodeTest::BuildListBox(
bool option_1_is_selected,
bool option_2_is_selected,
bool option_3_is_selected,
- ax::mojom::State additional_state /* ax::mojom::State::kNone */) {
+ const std::vector<ax::mojom::State>& additional_state) {
AXNodeData listbox;
listbox.id = 1;
listbox.SetName("ListBox");
listbox.role = ax::mojom::Role::kListBox;
- if (additional_state != ax::mojom::State::kNone)
- listbox.AddState(additional_state);
+ for (auto state : additional_state)
+ listbox.AddState(state);
AXNodeData option_1;
option_1.id = 2;
diff --git a/ui/accessibility/platform/ax_platform_node_unittest.h b/ui/accessibility/platform/ax_platform_node_unittest.h
index b512b5a79f103bf4524a7467f4ae60d8036054b6..2b5392f589b26795cc3971be297257b1c2ece615 100644
--- a/ui/accessibility/platform/ax_platform_node_unittest.h
+++ b/ui/accessibility/platform/ax_platform_node_unittest.h
@@ -58,10 +58,11 @@ class AXPlatformNodeTest : public testing::Test, public AXTreeManager {
AXTreeUpdate Build3X3Table();
AXTreeUpdate BuildAriaColumnAndRowCountGrids();
- AXTreeUpdate BuildListBox(bool option_1_is_selected,
- bool option_2_is_selected,
- bool option_3_is_selected,
- ax::mojom::State additional_state);
+ AXTreeUpdate BuildListBox(
+ bool option_1_is_selected,
+ bool option_2_is_selected,
+ bool option_3_is_selected,
+ const std::vector<ax::mojom::State>& additional_state);
std::unique_ptr<AXTree> tree_;
};
diff --git a/ui/accessibility/platform/ax_platform_node_win.cc b/ui/accessibility/platform/ax_platform_node_win.cc
index 6b70f5eed20290141adc659b71900536ef052bb2..232eff3c4af371eaa7026f2a14953c947b2bda7a 100644
--- a/ui/accessibility/platform/ax_platform_node_win.cc
+++ b/ui/accessibility/platform/ax_platform_node_win.cc
@@ -2148,15 +2148,10 @@ IFACEMETHODIMP AXPlatformNodeWin::GetSelection(SAFEARRAY** result) {
WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_SELECTION_GETSELECTION);
UIA_VALIDATE_CALL_1_ARG(result);
- std::vector<AXPlatformNodeWin*> selected_children;
- LONG child_count = GetDelegate()->GetChildCount();
- for (LONG i = 0; i < child_count; ++i) {
- auto* child = static_cast<AXPlatformNodeWin*>(
- FromNativeViewAccessible(GetDelegate()->ChildAtIndex(i)));
- DCHECK(child);
- if (child->GetData().GetBoolAttribute(ax::mojom::BoolAttribute::kSelected))
- selected_children.push_back(child);
- }
+ std::vector<AXPlatformNodeBase*> selected_children;
+ int max_items = GetMaxSelectableItems();
+ if (max_items)
+ GetSelectedItems(max_items, &selected_children);
LONG selected_children_count = selected_children.size();
*result = SafeArrayCreateVector(VT_UNKNOWN, 0, selected_children_count);
@@ -2164,9 +2159,10 @@ IFACEMETHODIMP AXPlatformNodeWin::GetSelection(SAFEARRAY** result) {
return E_OUTOFMEMORY;
for (LONG i = 0; i < selected_children_count; ++i) {
+ AXPlatformNodeWin* children =
+ static_cast<AXPlatformNodeWin*>(selected_children[i]);
HRESULT hr = SafeArrayPutElement(
- *result, &i,
- static_cast<IRawElementProviderSimple*>(selected_children[i]));
+ *result, &i, static_cast<IRawElementProviderSimple*>(children));
if (FAILED(hr)) {
SafeArrayDestroy(*result);
*result = nullptr;
diff --git a/ui/accessibility/platform/ax_platform_node_win_unittest.cc b/ui/accessibility/platform/ax_platform_node_win_unittest.cc
index 31ebeaaae3ea801add4e7f8a609649de425ead04..e64aa75a2dd98ce2968ba314f78423058488cbd7 100644
--- a/ui/accessibility/platform/ax_platform_node_win_unittest.cc
+++ b/ui/accessibility/platform/ax_platform_node_win_unittest.cc
@@ -4532,8 +4532,7 @@ TEST_F(AXPlatformNodeWinTest, TestUIANavigate) {
TEST_F(AXPlatformNodeWinTest, TestISelectionProviderCanSelectMultipleDefault) {
Init(BuildListBox(/*option_1_is_selected*/ false,
/*option_2_is_selected*/ false,
- /*option_3_is_selected*/ false,
- /*additional_state*/ ax::mojom::State::kNone));
+ /*option_3_is_selected*/ false, {}));
ComPtr<ISelectionProvider> selection_provider(
QueryInterfaceFromNode<ISelectionProvider>(GetRootNode()));
@@ -4545,10 +4544,12 @@ TEST_F(AXPlatformNodeWinTest, TestISelectionProviderCanSelectMultipleDefault) {
}
TEST_F(AXPlatformNodeWinTest, TestISelectionProviderCanSelectMultipleTrue) {
+ const std::vector<ax::mojom::State> state = {
+ ax::mojom::State::kMultiselectable, ax::mojom::State::kFocusable};
Init(BuildListBox(/*option_1_is_selected*/ false,
/*option_2_is_selected*/ false,
/*option_3_is_selected*/ false,
- /*additional_state*/ ax::mojom::State::kMultiselectable));
+ /*additional_state*/ state));
ComPtr<ISelectionProvider> selection_provider(
QueryInterfaceFromNode<ISelectionProvider>(GetRootNode()));
@@ -4564,7 +4565,7 @@ TEST_F(AXPlatformNodeWinTest,
Init(BuildListBox(/*option_1_is_selected*/ false,
/*option_2_is_selected*/ false,
/*option_3_is_selected*/ false,
- /*additional_state*/ ax::mojom::State::kNone));
+ /*additional_state*/ {}));
ComPtr<ISelectionProvider> selection_provider(
QueryInterfaceFromNode<ISelectionProvider>(GetRootNode()));
@@ -4579,7 +4580,7 @@ TEST_F(AXPlatformNodeWinTest, TestISelectionProviderIsSelectionRequiredTrue) {
Init(BuildListBox(/*option_1_is_selected*/ false,
/*option_2_is_selected*/ false,
/*option_3_is_selected*/ false,
- /*additional_state*/ ax::mojom::State::kRequired));
+ /*additional_state*/ {ax::mojom::State::kRequired}));
ComPtr<ISelectionProvider> selection_provider(
QueryInterfaceFromNode<ISelectionProvider>(GetRootNode()));
@@ -4594,7 +4595,7 @@ TEST_F(AXPlatformNodeWinTest, TestISelectionProviderGetSelectionNoneSelected) {
Init(BuildListBox(/*option_1_is_selected*/ false,
/*option_2_is_selected*/ false,
/*option_3_is_selected*/ false,
- /*additional_state*/ ax::mojom::State::kNone));
+ /*additional_state*/ {ax::mojom::State::kFocusable}));
ComPtr<ISelectionProvider> selection_provider(
QueryInterfaceFromNode<ISelectionProvider>(GetRootNode()));
@@ -4620,7 +4621,7 @@ TEST_F(AXPlatformNodeWinTest,
Init(BuildListBox(/*option_1_is_selected*/ false,
/*option_2_is_selected*/ true,
/*option_3_is_selected*/ false,
- /*additional_state*/ ax::mojom::State::kNone));
+ /*additional_state*/ {ax::mojom::State::kFocusable}));
ComPtr<ISelectionProvider> selection_provider(
QueryInterfaceFromNode<ISelectionProvider>(GetRootNode()));
@@ -4652,10 +4653,12 @@ TEST_F(AXPlatformNodeWinTest,
TEST_F(AXPlatformNodeWinTest,
TestISelectionProviderGetSelectionMultipleItemsSelected) {
+ const std::vector<ax::mojom::State> state = {
+ ax::mojom::State::kMultiselectable, ax::mojom::State::kFocusable};
Init(BuildListBox(/*option_1_is_selected*/ true,
/*option_2_is_selected*/ true,
/*option_3_is_selected*/ true,
- /*additional_state*/ ax::mojom::State::kNone));
+ /*additional_state*/ state));
ComPtr<ISelectionProvider> selection_provider(
QueryInterfaceFromNode<ISelectionProvider>(GetRootNode()));

View File

@@ -0,0 +1,142 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Siye Liu <siliu@microsoft.com>
Date: Mon, 8 Jun 2020 21:19:00 +0000
Subject: Allow IME to insert zero-length composition string.
Some IMEs and Windows OS dictation will either insert zero-length text
or delete existing composition text to commit active composition.
Therefore, we should allow IMEs to cancel composition by committing zero
length text.
Bug: 1091069
Change-Id: I99cb213dc2ba1965abfa88ccf6858b89bd7e82df
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2233234
Commit-Queue: Siye Liu <siliu@microsoft.com>
Reviewed-by: Yohei Yukawa <yukawa@chromium.org>
Cr-Commit-Position: refs/heads/master@{#776198}
diff --git a/ui/base/ime/win/tsf_text_store.cc b/ui/base/ime/win/tsf_text_store.cc
index 4c8552a427c2a559ee1f3753af2ef000e9fe4a8c..7642bb5a92dad553044ace1e17e33b5815e6217f 100644
--- a/ui/base/ime/win/tsf_text_store.cc
+++ b/ui/base/ime/win/tsf_text_store.cc
@@ -612,9 +612,7 @@ STDMETHODIMP TSFTextStore::RequestLock(DWORD lock_flags, HRESULT* result) {
// 3. User commits current composition text.
if (((new_composition_start > last_composition_start &&
text_input_client_->HasCompositionText()) ||
- (wparam_keydown_fired_ == 0 && !has_composition_range_ &&
- !text_input_client_->HasCompositionText()) ||
- (wparam_keydown_fired_ != 0 && !has_composition_range_)) &&
+ !has_composition_range_) &&
text_input_client_) {
CommitTextAndEndCompositionIfAny(last_composition_start,
new_composition_start);
@@ -1314,8 +1312,11 @@ void TSFTextStore::CommitTextAndEndCompositionIfAny(size_t old_size,
: new_committed_string_size);
// TODO(crbug.com/978678): Unify the behavior of
// |TextInputClient::InsertText(text)| for the empty text.
- if (!new_committed_string.empty())
+ if (!new_committed_string.empty()) {
text_input_client_->InsertText(new_committed_string);
+ } else {
+ text_input_client_->ClearCompositionText();
+ }
// Notify accessibility about this committed composition
text_input_client_->SetActiveCompositionForAccessibility(
replace_text_range_, new_committed_string,
diff --git a/ui/base/ime/win/tsf_text_store_unittest.cc b/ui/base/ime/win/tsf_text_store_unittest.cc
index 7909ade63ab752a3d0d450347bba15dc205ee466..77c5eb051e646401eaf22ca1753ef71c585fbc76 100644
--- a/ui/base/ime/win/tsf_text_store_unittest.cc
+++ b/ui/base/ime/win/tsf_text_store_unittest.cc
@@ -3139,5 +3139,92 @@ TEST_F(TSFTextStoreTest, RegressionTest5) {
EXPECT_EQ(S_OK, result);
}
+// regression tests for crbug.com/1091069.
+// We should allow inserting empty compositon string to cancel composition.
+class RegressionTest8Callback : public TSFTextStoreTestCallback {
+ public:
+ explicit RegressionTest8Callback(TSFTextStore* text_store)
+ : TSFTextStoreTestCallback(text_store) {}
+
+ HRESULT LockGranted1(DWORD flags) {
+ SetTextTest(0, 0, L"bbbb", S_OK);
+ SetSelectionTest(0, 4, S_OK);
+
+ text_spans()->clear();
+ ImeTextSpan text_span_1;
+ text_span_1.start_offset = 0;
+ text_span_1.end_offset = 4;
+ text_span_1.underline_color = SK_ColorBLACK;
+ text_span_1.thickness = ImeTextSpan::Thickness::kThin;
+ text_span_1.background_color = SK_ColorTRANSPARENT;
+ text_spans()->push_back(text_span_1);
+
+ *edit_flag() = true;
+ *composition_start() = 0;
+ composition_range()->set_start(0);
+ composition_range()->set_end(4);
+ *has_composition_range() = true;
+
+ text_store_->OnKeyTraceDown(65u, 1966081u);
+ return S_OK;
+ }
+
+ void SetCompositionText1(const ui::CompositionText& composition) {
+ EXPECT_EQ(L"bbbb", composition.text);
+ EXPECT_EQ(0u, composition.selection.start());
+ EXPECT_EQ(4u, composition.selection.end());
+ ASSERT_EQ(1u, composition.ime_text_spans.size());
+ EXPECT_EQ(0u, composition.ime_text_spans[0].start_offset);
+ EXPECT_EQ(4u, composition.ime_text_spans[0].end_offset);
+ SetHasCompositionText(true);
+ }
+
+ HRESULT LockGranted2(DWORD flags) {
+ GetTextTest(0, -1, L"bbbb", 4);
+ SetTextTest(0, 4, L"", S_OK);
+
+ text_spans()->clear();
+ *edit_flag() = true;
+ *composition_start() = 0;
+ composition_range()->set_start(0);
+ composition_range()->set_end(0);
+
+ *has_composition_range() = false;
+ text_store_->OnKeyTraceUp(65u, 1966081u);
+ return S_OK;
+ }
+
+ void ClearCompositionText2() { EXPECT_EQ(false, *has_composition_range()); }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(RegressionTest8Callback);
+};
+
+TEST_F(TSFTextStoreTest, RegressionTest8) {
+ RegressionTest8Callback callback(text_store_.get());
+ EXPECT_CALL(text_input_client_, SetCompositionText(_))
+ .WillOnce(
+ Invoke(&callback, &RegressionTest8Callback::SetCompositionText1));
+
+ EXPECT_CALL(text_input_client_, ClearCompositionText())
+ .WillOnce(
+ Invoke(&callback, &RegressionTest8Callback::ClearCompositionText2));
+
+ EXPECT_CALL(*sink_, OnLockGranted(_))
+ .WillOnce(Invoke(&callback, &RegressionTest8Callback::LockGranted1))
+ .WillOnce(Invoke(&callback, &RegressionTest8Callback::LockGranted2));
+
+ ON_CALL(text_input_client_, HasCompositionText())
+ .WillByDefault(
+ Invoke(&callback, &TSFTextStoreTestCallback::HasCompositionText));
+
+ HRESULT result = kInvalidResult;
+ EXPECT_EQ(S_OK, text_store_->RequestLock(TS_LF_READWRITE, &result));
+ EXPECT_EQ(S_OK, result);
+ result = kInvalidResult;
+ EXPECT_EQ(S_OK, text_store_->RequestLock(TS_LF_READWRITE, &result));
+ EXPECT_EQ(S_OK, result);
+}
+
} // namespace
} // namespace ui

View File

@@ -0,0 +1,36 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Daniel McArdle <dmcardle@chromium.org>
Date: Thu, 16 Apr 2020 20:18:47 +0000
Subject: Avoid nullptr dereference in RTCPeerConnectionHandler
Bug: 1071327
Change-Id: Icf4189905dc5c95854b5af4b3e5e25e0607dd39e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2153325
Reviewed-by: Harald Alvestrand <hta@chromium.org>
Commit-Queue: Dan McArdle <dmcardle@chromium.org>
Cr-Commit-Position: refs/heads/master@{#759775}
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.cc b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.cc
index 9457fb951fed176c54f9e792ea5f71cb73f5bbba..6745fc1ae9746a3f9949f856b1501c48e85b5260 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.cc
@@ -2304,7 +2304,8 @@ void RTCPeerConnectionHandler::OnRemoveReceiverPlanB(uintptr_t receiver_id) {
void RTCPeerConnectionHandler::OnModifySctpTransport(
blink::WebRTCSctpTransportSnapshot state) {
- client_->DidModifySctpTransport(state);
+ if (client_)
+ client_->DidModifySctpTransport(state);
}
void RTCPeerConnectionHandler::OnModifyTransceivers(
@@ -2431,7 +2432,8 @@ void RTCPeerConnectionHandler::OnIceCandidateError(const String& host_candidate,
}
void RTCPeerConnectionHandler::OnInterestingUsage(int usage_pattern) {
- client_->DidNoteInterestingUsage(usage_pattern);
+ if (client_)
+ client_->DidNoteInterestingUsage(usage_pattern);
}
webrtc::SessionDescriptionInterface*

View File

@@ -0,0 +1,99 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tom Anderson <thomasanderson@chromium.org>
Date: Mon, 6 Jan 2020 18:05:20 +0000
Subject: Avoid using X11 SHM for remote connections
For remote connections, SHM doesn't work, but the MIT-SHM extension may
still be available, so we need to do an explicit check before trying to
use SHM.
BUG=1035803
Change-Id: I189ab94b82922572e52b717dc2043b8404745dec
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1980971
Commit-Queue: Sadrul Chowdhury <sadrul@chromium.org>
Reviewed-by: Sadrul Chowdhury <sadrul@chromium.org>
Auto-Submit: Thomas Anderson <thomasanderson@chromium.org>
Cr-Commit-Position: refs/heads/master@{#728564}
diff --git a/ui/base/x/BUILD.gn b/ui/base/x/BUILD.gn
index 7b8a4f8a6126cd9516cbef7ed7d1aca57839d632..5269237d5872120cb520b1f0518ee037f7accfa2 100644
--- a/ui/base/x/BUILD.gn
+++ b/ui/base/x/BUILD.gn
@@ -53,6 +53,7 @@ jumbo_component("x") {
deps = [
"//base",
"//base:i18n",
+ "//net",
"//skia",
"//ui/base:hit_test",
"//ui/display/util",
diff --git a/ui/base/x/x11_shm_image_pool_base.cc b/ui/base/x/x11_shm_image_pool_base.cc
index 8505b6297f67cea7f8bf36c89414fad9c3108190..486762aa01d56b51864f418ccf68b77d7610fe23 100644
--- a/ui/base/x/x11_shm_image_pool_base.cc
+++ b/ui/base/x/x11_shm_image_pool_base.cc
@@ -18,6 +18,7 @@
#include "base/strings/string_util.h"
#include "base/threading/thread_task_runner_handle.h"
#include "build/build_config.h"
+#include "net/base/url_util.h"
#include "ui/events/platform/platform_event_dispatcher.h"
#include "ui/events/platform/platform_event_source.h"
#include "ui/gfx/geometry/rect.h"
@@ -54,8 +55,31 @@ std::size_t MaxShmSegmentSize() {
return max_size;
}
+bool IsRemoteHost(const std::string& name) {
+ if (name.empty())
+ return false;
+
+ return !net::HostStringIsLocalhost(name);
+}
+
+bool ShouldUseMitShm(XDisplay* display) {
+ // MIT-SHM may be available on remote connetions, but it will be unusable. Do
+ // a best-effort check to see if the host is remote to disable the SHM
+ // codepath. It may be possible in contrived cases for there to be a
+ // false-positive, but in that case we'll just fallback to the non-SHM
+ // codepath.
+ char* display_string = DisplayString(display);
+ char* host = nullptr;
+ int display_id = 0;
+ int screen = 0;
+ if (xcb_parse_display(display_string, &host, &display_id, &screen)) {
+ std::string name = host;
+ free(host);
+ if (IsRemoteHost(name))
+ return false;
+ }
+
#if !defined(OS_CHROMEOS)
-bool ShouldUseMitShm() {
std::unique_ptr<base::Environment> env = base::Environment::Create();
// Used by QT.
@@ -73,10 +97,10 @@ bool ShouldUseMitShm() {
// Used by GTK.
if (base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kNoXshm))
return false;
+#endif
return true;
}
-#endif
} // namespace
@@ -118,10 +142,8 @@ bool XShmImagePoolBase::Resize(const gfx::Size& pixel_size) {
if (!event_task_runner_)
return false;
-#if !defined(OS_CHROMEOS)
- if (!ShouldUseMitShm())
+ if (!ShouldUseMitShm(display_))
return false;
-#endif
if (!ui::QueryShmSupport())
return false;

View File

@@ -0,0 +1,91 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Andrey Belenko <anbelen@microsoft.com>
Date: Fri, 3 Jul 2020 17:27:20 +0200
Subject: Backport 1019161
(https://chromium-review.googlesource.com/c/chromium/src/+/2125690)
diff --git a/extensions/browser/service_worker_task_queue.cc b/extensions/browser/service_worker_task_queue.cc
index dedb8c39f7db8c416540cdb930683778c2a9a5a5..3519926a06a35b375e13695d59fafce0c7f49c81 100644
--- a/extensions/browser/service_worker_task_queue.cc
+++ b/extensions/browser/service_worker_task_queue.cc
@@ -170,8 +170,17 @@ void ServiceWorkerTaskQueue::DidStartWorkerFail(
DCHECK(!base::Contains(pending_tasks_, context_id));
return;
}
- // TODO(lazyboy): Handle failure cases.
- DCHECK(false) << "DidStartWorkerFail: " << context_id.first.extension_id();
+
+ if (g_test_observer) {
+ g_test_observer->DidStartWorkerFail(context_id.first.extension_id(),
+ pending_tasks_[context_id].size());
+ }
+
+ pending_tasks_.erase(context_id);
+ // TODO(https://crbug/1062936): Needs more thought: extension would be in
+ // perma-broken state after this as the registration wouldn't be stored if
+ // this happens.
+ LOG(ERROR) << "DidStartWorkerFail " << context_id.first.extension_id();
}
void ServiceWorkerTaskQueue::DidInitializeServiceWorkerContext(
@@ -530,6 +539,16 @@ ServiceWorkerTaskQueue::GetOrCreateWorkerState(const WorkerKey& worker_key) {
return &(iter->second);
}
+size_t ServiceWorkerTaskQueue::GetNumPendingTasksForTest(
+ const LazyContextId& lazy_context_id) {
+ auto current_sequence = GetCurrentSequence(lazy_context_id.extension_id());
+ if (!current_sequence)
+ return 0u;
+ const SequencedContextId context_id(lazy_context_id, *current_sequence);
+ auto iter = pending_tasks_.find(context_id);
+ return iter == pending_tasks_.end() ? 0u : iter->second.size();
+}
+
ServiceWorkerTaskQueue::WorkerState* ServiceWorkerTaskQueue::GetWorkerState(
const WorkerKey& worker_key) {
auto iter = worker_state_map_.find(worker_key);
diff --git a/extensions/browser/service_worker_task_queue.h b/extensions/browser/service_worker_task_queue.h
index 2e5e215bd193098fe4b183a60df5d3c6d1dc8d19..953a72d3c4fe0ce396e0399c890518068f9dbde7 100644
--- a/extensions/browser/service_worker_task_queue.h
+++ b/extensions/browser/service_worker_task_queue.h
@@ -121,7 +121,9 @@ class ServiceWorkerTaskQueue : public KeyedService,
// |will_register_service_worker| is true if a Service Worker will be
// registered.
virtual void OnActivateExtension(const ExtensionId& extension_id,
- bool will_register_service_worker) = 0;
+ bool will_register_service_worker) {}
+ virtual void DidStartWorkerFail(const ExtensionId& extension_id,
+ size_t num_pending_tasks) {}
private:
DISALLOW_COPY_AND_ASSIGN(TestObserver);
@@ -129,6 +131,8 @@ class ServiceWorkerTaskQueue : public KeyedService,
static void SetObserverForTest(TestObserver* observer);
+ size_t GetNumPendingTasksForTest(const LazyContextId& lazy_context_id);
+
private:
// Unique identifier for an extension's activation->deactivation span.
using ActivationSequence = int;
diff --git a/extensions/browser/service_worker_task_queue_factory.cc b/extensions/browser/service_worker_task_queue_factory.cc
index b62d2c1c1e31414a3b26160c95cfcc6996995dff..29ff874ef47be3f7172bda276a7dba519a2f1b9b 100644
--- a/extensions/browser/service_worker_task_queue_factory.cc
+++ b/extensions/browser/service_worker_task_queue_factory.cc
@@ -6,6 +6,7 @@
#include "components/keyed_service/content/browser_context_dependency_manager.h"
#include "extensions/browser/extension_registry_factory.h"
+#include "extensions/browser/process_manager_factory.h"
#include "extensions/browser/service_worker_task_queue.h"
using content::BrowserContext;
@@ -28,6 +29,7 @@ ServiceWorkerTaskQueueFactory::ServiceWorkerTaskQueueFactory()
"ServiceWorkerTaskQueue",
BrowserContextDependencyManager::GetInstance()) {
DependsOn(ExtensionRegistryFactory::GetInstance());
+ DependsOn(ProcessManagerFactory::GetInstance());
}
ServiceWorkerTaskQueueFactory::~ServiceWorkerTaskQueueFactory() {}

View File

@@ -0,0 +1,139 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Andrey Belenko <anbelen@microsoft.com>
Date: Fri, 3 Jul 2020 17:05:10 +0200
Subject: Backport 1063177
(https://chromium-review.googlesource.com/c/chromium/src/+/2111393/)
diff --git a/extensions/browser/api/declarative_net_request/file_sequence_helper.cc b/extensions/browser/api/declarative_net_request/file_sequence_helper.cc
index b4e340f3a865b79a9c8a1aa38fd86eb4db043c3c..2579f39d4b2f10b665f95febe2c69409188529ff 100644
--- a/extensions/browser/api/declarative_net_request/file_sequence_helper.cc
+++ b/extensions/browser/api/declarative_net_request/file_sequence_helper.cc
@@ -7,9 +7,11 @@
#include <set>
#include <utility>
+#include "base/barrier_closure.h"
#include "base/bind.h"
#include "base/files/file_util.h"
#include "base/logging.h"
+#include "base/memory/ref_counted.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/stl_util.h"
@@ -31,49 +33,57 @@ namespace {
namespace dnr_api = extensions::api::declarative_net_request;
// A class to help in re-indexing multiple rulesets.
-class ReindexHelper {
+class ReindexHelper : public base::RefCountedThreadSafe<ReindexHelper> {
public:
- // Starts re-indexing rulesets. Must be called on the extension file task
- // runner.
using ReindexCallback = base::OnceCallback<void(LoadRequestData)>;
- static void Start(LoadRequestData data, ReindexCallback callback) {
- auto* helper = new ReindexHelper(std::move(data), std::move(callback));
- helper->Start();
- }
-
- private:
- // We manage our own lifetime.
ReindexHelper(LoadRequestData data, ReindexCallback callback)
: data_(std::move(data)), callback_(std::move(callback)) {}
- ~ReindexHelper() = default;
-
+
+ // Starts re-indexing rulesets. Must be called on the extension file task
+ // runner.
void Start() {
DCHECK(GetExtensionFileTaskRunner()->RunsTasksInCurrentSequence());
- // Post tasks to reindex individual rulesets.
- bool did_post_task = false;
+ std::vector<RulesetInfo*> rulesets_to_reindex;
+
for (auto& ruleset : data_.rulesets) {
if (ruleset.did_load_successfully())
continue;
- // Using Unretained is safe since this class manages its own lifetime and
- // |this| won't be deleted until the |callback| returns.
- auto callback = base::BindOnce(&ReindexHelper::OnReindexCompleted,
- base::Unretained(this), &ruleset);
- callback_count_++;
- did_post_task = true;
- ruleset.source().IndexAndPersistJSONRuleset(&decoder_,
- std::move(callback));
+ rulesets_to_reindex.push_back(&ruleset);
}
- // It's possible that the callbacks return synchronously and we are deleted
- // at this point. Hence don't use any member variables here. Also, if we
- // don't post any task, we'll leak. Ensure that's not the case.
- DCHECK(did_post_task);
+ // |done_closure| will be invoked once |barrier_closure| is run
+ // |rulesets_to_reindex.size()| times.
+ base::OnceClosure done_closure =
+ base::BindOnce(&ReindexHelper::OnAllRulesetsReindexed, this);
+ base::RepeatingClosure barrier_closure = base::BarrierClosure(
+ rulesets_to_reindex.size(), std::move(done_closure));
+
+ // Post tasks to reindex individual rulesets.
+ for (RulesetInfo* ruleset : rulesets_to_reindex) {
+ auto callback = base::BindOnce(&ReindexHelper::OnReindexCompleted, this,
+ ruleset, barrier_closure);
+ ruleset->source().IndexAndPersistJSONRuleset(&decoder_,
+ std::move(callback));
+ }
+ }
+
+ private:
+ friend class base::RefCountedThreadSafe<ReindexHelper>;
+ ~ReindexHelper() = default;
+
+ // Callback invoked when reindexing of all rulesets is completed.
+ void OnAllRulesetsReindexed() {
+ DCHECK(GetExtensionFileTaskRunner()->RunsTasksInCurrentSequence());
+
+ // Our job is done.
+ std::move(callback_).Run(std::move(data_));
}
// Callback invoked when a single ruleset is re-indexed.
void OnReindexCompleted(RulesetInfo* ruleset,
+ base::OnceClosure done_closure,
IndexAndPersistJSONRulesetResult result) {
DCHECK(ruleset);
@@ -105,19 +115,11 @@ class ReindexHelper {
"Extensions.DeclarativeNetRequest.RulesetReindexSuccessful",
reindexing_success);
- callback_count_--;
- DCHECK_GE(callback_count_, 0);
-
- if (callback_count_ == 0) {
- // Our job is done.
- std::move(callback_).Run(std::move(data_));
- delete this;
- }
+ std::move(done_closure).Run();
}
LoadRequestData data_;
ReindexCallback callback_;
- int callback_count_ = 0;
// We use a single shared Data Decoder service instance to process all of the
// rulesets for this ReindexHelper.
@@ -362,7 +364,10 @@ void FileSequenceHelper::LoadRulesets(
auto reindex_callback =
base::BindOnce(&FileSequenceHelper::OnRulesetsReindexed,
weak_factory_.GetWeakPtr(), std::move(ui_callback));
- ReindexHelper::Start(std::move(load_data), std::move(reindex_callback));
+
+ auto reindex_helper = base::MakeRefCounted<ReindexHelper>(
+ std::move(load_data), std::move(reindex_callback));
+ reindex_helper->Start();
}
void FileSequenceHelper::UpdateDynamicRules(

View File

@@ -0,0 +1,98 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Cheng Zhao <zcbenz@gmail.com>
Date: Thu, 4 Oct 2018 14:57:02 -0700
Subject: fix: add some crash debugging checks
[1065122] [High]: heap-use-after-free : ui::AXTreeSerializerblink::WebAXObject,content::AXContentNodeData,content::AXContentTreeData::LeastCommonAncestor
Backport https://chromium.googlesource.com/chromium/src/+/e0a661af6c2c7346183c47b106afecb01adbfa2e
diff --git a/ui/accessibility/ax_tree_serializer.h b/ui/accessibility/ax_tree_serializer.h
index d0cd8be8dbf3c15ce2a2c84446f5042819686b9a..8791c58789cef10a31799d57287860ba8e60af94 100644
--- a/ui/accessibility/ax_tree_serializer.h
+++ b/ui/accessibility/ax_tree_serializer.h
@@ -180,6 +180,8 @@ class AXTreeSerializer {
// like when Reset() is called.
void InternalReset();
+ ClientTreeNode* GetClientTreeNodeParent(ClientTreeNode* obj);
+
// The tree source.
AXTreeSource<AXSourceNode, AXNodeData, AXTreeData>* tree_;
@@ -269,7 +271,7 @@ AXTreeSerializer<AXSourceNode, AXNodeData, AXTreeData>::LeastCommonAncestor(
std::vector<ClientTreeNode*> client_ancestors;
while (client_node) {
client_ancestors.push_back(client_node);
- client_node = client_node->parent;
+ client_node = GetClientTreeNodeParent(client_node);
}
// Start at the root. Keep going until the source ancestor chain and
@@ -304,9 +306,12 @@ AXTreeSerializer<AXSourceNode, AXNodeData, AXTreeData>::LeastCommonAncestor(
// that we're inside of an invalid subtree that all needs to be
// re-serialized, so the LCA should be higher.
ClientTreeNode* client_node = ClientTreeNodeById(tree_->GetId(node));
- while (
- tree_->IsValid(node) &&
- (!client_node || (client_node->parent && client_node->parent->invalid))) {
+ while (tree_->IsValid(node)) {
+ if (client_node) {
+ ClientTreeNode* parent = GetClientTreeNodeParent(client_node);
+ if (!parent || !parent->invalid)
+ break;
+ }
node = tree_->GetParent(node);
if (tree_->IsValid(node))
client_node = ClientTreeNodeById(tree_->GetId(node));
@@ -326,12 +331,13 @@ bool AXTreeSerializer<AXSourceNode, AXNodeData, AXTreeData>::
int child_id = tree_->GetId(child);
ClientTreeNode* client_child = ClientTreeNodeById(child_id);
if (client_child) {
- if (!client_child->parent) {
+ ClientTreeNode* parent = client_child->parent;
+ if (!parent) {
// If the client child has no parent, it must have been the
// previous root node, so there is no LCA and we can exit early.
*out_lca = tree_->GetNull();
return true;
- } else if (client_child->parent->id != id) {
+ } else if (parent->id != id) {
// If the client child's parent is not this node, update the LCA
// and return true (reparenting was found).
*out_lca = LeastCommonAncestor(*out_lca, client_child);
@@ -362,6 +368,19 @@ AXTreeSerializer<AXSourceNode, AXNodeData, AXTreeData>::ClientTreeNodeById(
return nullptr;
}
+template <typename AXSourceNode, typename AXNodeData, typename AXTreeData>
+ClientTreeNode*
+AXTreeSerializer<AXSourceNode, AXNodeData, AXTreeData>::GetClientTreeNodeParent(
+ ClientTreeNode* obj) {
+ ClientTreeNode* parent = obj->parent;
+#if DCHECK_IS_ON()
+ if (!parent)
+ return nullptr;
+ DCHECK(ClientTreeNodeById(parent->id)) << "Parent not in id map.";
+#endif // DCHECK_IS_ON()
+ return parent;
+}
+
template <typename AXSourceNode, typename AXNodeData, typename AXTreeData>
bool AXTreeSerializer<AXSourceNode, AXNodeData, AXTreeData>::SerializeChanges(
AXSourceNode node,
@@ -545,8 +564,13 @@ bool AXTreeSerializer<AXSourceNode, AXNodeData, AXTreeData>::
// above. If this happens, reset and return an error.
ClientTreeNode* client_child = ClientTreeNodeById(new_child_id);
- if (client_child && client_child->parent != client_node) {
- DVLOG(1) << "Reparenting detected";
+ if (client_child && GetClientTreeNodeParent(client_child) != client_node) {
+ DVLOG(1) << "Illegal reparenting detected";
+#if defined(ADDRESS_SANITIZER)
+ // Wrapping this in ADDRESS_SANITIZER will cause it to run on
+ // clusterfuzz, which should help us narrow down the issue.
+ NOTREACHED() << "Illegal reparenting detected";
+#endif
Reset();
return false;
}

View File

@@ -0,0 +1,52 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Cheng Zhao <zcbenz@gmail.com>
Date: Thu, 4 Oct 2018 14:57:02 -0700
Subject: fix: use parseHTMLSubset() in chrome://histograms.
[1073409] [Low] [CVE-2020-6535]: XSS on chrome://histograms/ with a compromised renderer
Backport https://chromium.googlesource.com/chromium/src/+/9a31a7ea51e0c7548f4ed77f5007e4a924ef0fbb
diff --git a/content/browser/resources/histograms/BUILD.gn b/content/browser/resources/histograms/BUILD.gn
index 9b67dcd52b2599855eb21b86b29a294094b22003..08c7f14373fa097bf540c60301d3802685affe0e 100644
--- a/content/browser/resources/histograms/BUILD.gn
+++ b/content/browser/resources/histograms/BUILD.gn
@@ -13,6 +13,7 @@ js_type_check("closure_compile") {
js_library("histograms_internals") {
deps = [
"//ui/webui/resources/js:cr",
+ "//ui/webui/resources/js:parse_html_subset",
"//ui/webui/resources/js:util",
]
}
diff --git a/content/browser/resources/histograms/histograms_internals.html b/content/browser/resources/histograms/histograms_internals.html
index 37e45404843d70bd2621fffc6f5f4e4e69786005..b997e6d2ff88f86c00bf4e4a099cd4999d66c061 100644
--- a/content/browser/resources/histograms/histograms_internals.html
+++ b/content/browser/resources/histograms/histograms_internals.html
@@ -8,6 +8,7 @@
<script src="chrome://resources/js/cr.js"></script>
<script src="chrome://resources/js/promise_resolver.js"></script>
<script src="chrome://resources/js/util.js"></script>
+ <script src="chrome://resources/js/parse_html_subset.js"></script>
<script src="histograms_internals.js"></script>
<title>Histograms</title>
</head>
diff --git a/content/browser/resources/histograms/histograms_internals.js b/content/browser/resources/histograms/histograms_internals.js
index 24c55fb23c9f390a484572fe098e0cdcc79bc4ac..b70641ed43512391e4b75383b68196ba99590638 100644
--- a/content/browser/resources/histograms/histograms_internals.js
+++ b/content/browser/resources/histograms/histograms_internals.js
@@ -24,9 +24,12 @@ function addHistograms(histograms) {
htmlOutput += histogram;
}
- // NOTE: This is generally unsafe due to XSS attacks. Make sure |htmlOutput|
- // cannot be modified by an external party.
- $('histograms').innerHTML = htmlOutput;
+ // The following HTML tags are coming from
+ // |HistogramsMessageHandler::HandleRequestHistograms|.
+ const sanitizedHTML = parseHtmlSubset(`<span>${htmlOutput}</span>`, [
+ 'PRE', 'H4', 'BR', 'HR'
+ ]).firstChild.innerHTML;
+ $('histograms').innerHTML = sanitizedHTML;
}
/**

View File

@@ -0,0 +1,89 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Cheng Zhao <zcbenz@gmail.com>
Date: Thu, 4 Oct 2018 14:57:02 -0700
Subject: fix: stop leaking cross-origin post-redirect data using StackTrace
[1074317] [High] [CVE-2020-6511]: Security: The CSP reports and stacktraces of errors leaks post-redirect URL for <script>
Backport https://chromium.googlesource.com/chromium/src/+/0b707cbaa2cb806162797be55caf9f8074fbdccf
diff --git a/third_party/blink/renderer/bindings/core/v8/script_source_code.cc b/third_party/blink/renderer/bindings/core/v8/script_source_code.cc
index afd83f83ae79f3ce1d017868144af1d4468d5c53..51efddac8feae2cd53699bd47a65dd11fe8f664f 100644
--- a/third_party/blink/renderer/bindings/core/v8/script_source_code.cc
+++ b/third_party/blink/renderer/bindings/core/v8/script_source_code.cc
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/bindings/core/v8/script_source_code.h"
+#include "base/feature_list.h"
#include "third_party/blink/renderer/core/loader/resource/script_resource.h"
#include "third_party/blink/renderer/platform/loader/fetch/cached_metadata_handler.h"
@@ -47,8 +48,16 @@ String SourceMapUrlFromResponse(const ResourceResponse& response) {
return response.HttpHeaderField(http_names::kXSourceMap);
}
+const base::Feature kUnsafeScriptReportPostRedirectURL{
+ "UnsafeScriptReportPostRedirectURL", base::FEATURE_DISABLED_BY_DEFAULT};
+
} // namespace
+// static
+bool ScriptSourceCode::UsePostRedirectURL() {
+ return base::FeatureList::IsEnabled(kUnsafeScriptReportPostRedirectURL);
+}
+
ScriptSourceCode::ScriptSourceCode(
const ParkableString& source,
ScriptSourceLocationType source_location_type,
@@ -84,8 +93,9 @@ ScriptSourceCode::ScriptSourceCode(ScriptStreamer* streamer,
cache_handler_(resource->CacheHandler()),
streamer_(streamer),
not_streaming_reason_(reason),
- url_(
- StripFragmentIdentifier(resource->GetResponse().CurrentRequestUrl())),
+ url_(StripFragmentIdentifier(
+ UsePostRedirectURL() ? resource->GetResponse().CurrentRequestUrl()
+ : resource->Url())),
source_map_url_(SourceMapUrlFromResponse(resource->GetResponse())),
start_position_(TextPosition::MinimumPosition()),
source_location_type_(ScriptSourceLocationType::kExternalFile) {
diff --git a/third_party/blink/renderer/bindings/core/v8/script_source_code.h b/third_party/blink/renderer/bindings/core/v8/script_source_code.h
index 8fe2bd4e487ff6a67cbe6a3cfb9e00bd5a85da32..41023cec3603a67dba15b71c4b2e3ba12f222f8a 100644
--- a/third_party/blink/renderer/bindings/core/v8/script_source_code.h
+++ b/third_party/blink/renderer/bindings/core/v8/script_source_code.h
@@ -49,6 +49,20 @@ class CORE_EXPORT ScriptSourceCode final {
DISALLOW_NEW();
public:
+ // Return whether chrome should use the request URL or the response URL as the
+ // 'url' of the script. This can be observed in:
+ // 1) The 'source-file' in CSP violations reports.
+ // 2) The URL(s) in javascript stack traces.
+ // 3) How relative source map are resolved.
+ //
+ // This returns false by default. This corresponds to the current
+ // specification and matches Firefox behavior. This also avoids leaking
+ // post-redirect data cross-origin. See https://crbug.com/1074317.
+ //
+ // This can be enabled using the switch:
+ // --enable-features=UnsafeScriptReportPostRedirectURL
+ static bool UsePostRedirectURL();
+
// For inline scripts.
ScriptSourceCode(
const String& source,
diff --git a/third_party/blink/renderer/core/workers/worker_global_scope.cc b/third_party/blink/renderer/core/workers/worker_global_scope.cc
index b476e7490aa0a6192ead83184668c6ae7d254431..3f8c36324ce1801fa7fc41973aa682b45be3c4c0 100644
--- a/third_party/blink/renderer/core/workers/worker_global_scope.cc
+++ b/third_party/blink/renderer/core/workers/worker_global_scope.cc
@@ -266,7 +266,9 @@ void WorkerGlobalScope::ImportScriptsInternal(const Vector<String>& urls,
source_code.length(), handler ? handler->GetCodeCacheSize() : 0);
ScriptController()->Evaluate(
ScriptSourceCode(source_code, ScriptSourceLocationType::kUnknown,
- handler, response_url),
+ handler,
+ ScriptSourceCode::UsePostRedirectURL() ? response_url
+ : complete_url),
sanitize_script_errors, &error_event, GetV8CacheOptions());
if (error_event) {
ScriptController()->RethrowExceptionFromImportedScript(error_event,

View File

@@ -0,0 +1,21 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Cheng Zhao <zcbenz@gmail.com>
Date: Thu, 4 Oct 2018 14:57:02 -0700
Subject: fix: uninitialized frame policy issue in javascript url
[1074340] [Low] [CVE-2020-6526]: Security: javascript URI sandbox flags aren't propagated in a blank string case
Backport https://chromium.googlesource.com/chromium/src/+/45bcb4d547a5efecae80f4c9a48cef854af91d7f
diff --git a/third_party/blink/renderer/bindings/core/v8/script_controller.cc b/third_party/blink/renderer/bindings/core/v8/script_controller.cc
index 363375fe3150b8ab55a3ce8c32b2511b24c34135..6311d5262d994d725078eafbbdeb23c0c186c37f 100644
--- a/third_party/blink/renderer/bindings/core/v8/script_controller.cc
+++ b/third_party/blink/renderer/bindings/core/v8/script_controller.cc
@@ -297,6 +297,8 @@ void ScriptController::ExecuteJavaScriptURL(
WebFeature::kReplaceDocumentViaJavaScriptURL);
auto params = std::make_unique<WebNavigationParams>();
params->url = GetFrame()->GetDocument()->Url();
+ if (auto* owner = GetFrame()->Owner())
+ params->frame_policy = owner->GetFramePolicy();
String result = ToCoreString(v8::Local<v8::String>::Cast(v8_result));
WebNavigationParams::FillStaticResponse(params.get(), "text/html", "UTF-8",

View File

@@ -0,0 +1,30 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Cheng Zhao <zcbenz@gmail.com>
Date: Thu, 4 Oct 2018 14:57:02 -0700
Subject: fix: replace memcopy with memmove for overlapping copies
[1081722] [Medium] [CVE-2020-6524]: Security: memcpy-param-overlap in AudioBuffer::copyFromChannel
Backport https://chromium.googlesource.com/chromium/src/+/2be9b1c27fb97e8a82e068794fc0fba555182c03
diff --git a/third_party/blink/renderer/modules/webaudio/audio_buffer.cc b/third_party/blink/renderer/modules/webaudio/audio_buffer.cc
index f173f1bbf32d5ba09d16b5c3f5e7755a2023f240..45fcdb53d9fe92b7256e7ac915a0fae3f23a58b5 100644
--- a/third_party/blink/renderer/modules/webaudio/audio_buffer.cc
+++ b/third_party/blink/renderer/modules/webaudio/audio_buffer.cc
@@ -255,7 +255,7 @@ void AudioBuffer::copyFromChannel(NotShared<DOMFloat32Array> destination,
DCHECK_LE(count, channel_data->deprecatedLengthAsUnsigned());
DCHECK_LE(buffer_offset + count, channel_data->deprecatedLengthAsUnsigned());
- memcpy(dst, src + buffer_offset, count * sizeof(*src));
+ memmove(dst, src + buffer_offset, count * sizeof(*src));
}
void AudioBuffer::copyToChannel(NotShared<DOMFloat32Array> source,
@@ -299,7 +299,7 @@ void AudioBuffer::copyToChannel(NotShared<DOMFloat32Array> source,
DCHECK_LE(buffer_offset + count, channel_data->deprecatedLengthAsUnsigned());
DCHECK_LE(count, source.View()->deprecatedLengthAsUnsigned());
- memcpy(dst + buffer_offset, src, count * sizeof(*dst));
+ memmove(dst + buffer_offset, src, count * sizeof(*dst));
}
void AudioBuffer::Zero() {

View File

@@ -0,0 +1,32 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Cheng Zhao <zcbenz@gmail.com>
Date: Thu, 4 Oct 2018 14:57:02 -0700
Subject: fix: guard against UaF in NavigationRequest
[1090543] [High]: heap-use-after-free : content::NavigationRequest::OnWillProcessResponseProcessed
Backport https://chromium.googlesource.com/chromium/src/+/8a7c8c1affd3b03a41c6f79afa8ebce4168ded5b
diff --git a/content/browser/frame_host/navigation_request.cc b/content/browser/frame_host/navigation_request.cc
index bba7dc934cd43df41949ed5b2adc70e152b77627..d5290c54ed88e3dd2cd736535d5954316ee663a8 100644
--- a/content/browser/frame_host/navigation_request.cc
+++ b/content/browser/frame_host/navigation_request.cc
@@ -3012,11 +3012,19 @@ void NavigationRequest::OnWillProcessResponseProcessed(
DCHECK(processing_navigation_throttle_);
processing_navigation_throttle_ = false;
if (result.action() == NavigationThrottle::PROCEED) {
+ base::WeakPtr<NavigationRequest> weak_self(weak_factory_.GetWeakPtr());
+
// If the navigation is done processing the response, then it's ready to
// commit. Inform observers that the navigation is now ready to commit,
// unless it is not set to commit (204/205s/downloads).
if (render_frame_host_)
ReadyToCommitNavigation(false);
+
+ // The call above might block on showing a user dialog. The interaction of
+ // the user with this dialog might result in the WebContents owning this
+ // NavigationRequest to be destroyed. Return if this is the case.
+ if (!weak_self)
+ return;
} else {
state_ = CANCELING;
}

View File

@@ -5,10 +5,10 @@ Subject: can_create_window.patch
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc
index bbd42aad3d42311dfff47e725a5deddb4ed04134..797ee4073cfc7b78038d0c007922783a55b89683 100644
index 050531a82b48797012adbf6fe49ab5741a38d989..8a02ff83c8e40d641530211ef944b62b09a03ac8 100644
--- a/content/browser/frame_host/render_frame_host_impl.cc
+++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -4375,6 +4375,7 @@ void RenderFrameHostImpl::CreateNewWindow(
@@ -4379,6 +4379,7 @@ void RenderFrameHostImpl::CreateNewWindow(
last_committed_origin_, params->window_container_type,
params->target_url, params->referrer.To<Referrer>(),
params->frame_name, params->disposition, *params->features,

View File

@@ -0,0 +1,77 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Marijn Kruisselbrink <mek@chromium.org>
Date: Tue, 21 Apr 2020 23:51:25 +0000
Subject: Fix bug when BytesProvider replies with invalid data.
Bug: 1072983
Change-Id: Ideaa0a67680375e770995880a4b8d2014b51d642
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2159583
Reviewed-by: enne <enne@chromium.org>
Commit-Queue: Marijn Kruisselbrink <mek@chromium.org>
Cr-Commit-Position: refs/heads/master@{#761203}
diff --git a/storage/browser/blob/blob_registry_impl.cc b/storage/browser/blob/blob_registry_impl.cc
index 1cc34f91e01530754635a27cd6481e367b0a4d4e..b6a12a5c43d0129f6c1dcfe93fbd684ba4f5dc2e 100644
--- a/storage/browser/blob/blob_registry_impl.cc
+++ b/storage/browser/blob/blob_registry_impl.cc
@@ -432,6 +432,10 @@ void BlobRegistryImpl::BlobUnderConstruction::TransportComplete(
// try to delete |this| again afterwards.
auto weak_this = weak_ptr_factory_.GetWeakPtr();
+ // Store the bad_message_callback_, so we can invoke it if needed, after
+ // notifying about the blob being finished.
+ auto bad_message_callback = std::move(bad_message_callback_);
+
// The blob might no longer have any references, in which case it may no
// longer exist. If that happens just skip calling Complete.
// TODO(mek): Stop building sooner if a blob is no longer referenced.
@@ -445,7 +449,7 @@ void BlobRegistryImpl::BlobUnderConstruction::TransportComplete(
// BlobTransportStrategy might have already reported a BadMessage on the
// BytesProvider binding, but just to be safe, also report one on the
// BlobRegistry binding itself.
- std::move(bad_message_callback_)
+ std::move(bad_message_callback)
.Run("Received invalid data while transporting blob");
}
if (weak_this)
diff --git a/storage/browser/blob/blob_registry_impl_unittest.cc b/storage/browser/blob/blob_registry_impl_unittest.cc
index 8cbcc69ec6dc6bd368fdb59a3797e412b286e342..2060676987e267a0d55878a27f6a1b53fe6790b1 100644
--- a/storage/browser/blob/blob_registry_impl_unittest.cc
+++ b/storage/browser/blob/blob_registry_impl_unittest.cc
@@ -770,6 +770,36 @@ TEST_F(BlobRegistryImplTest, Register_ValidBytesAsReply) {
EXPECT_EQ(0u, BlobsUnderConstruction());
}
+TEST_F(BlobRegistryImplTest, Register_InvalidBytesAsReply) {
+ const std::string kId = "id";
+ const std::string kData = "hello";
+
+ std::vector<blink::mojom::DataElementPtr> elements;
+ elements.push_back(
+ blink::mojom::DataElement::NewBytes(blink::mojom::DataElementBytes::New(
+ kData.size(), base::nullopt, CreateBytesProvider(""))));
+
+ mojo::PendingRemote<blink::mojom::Blob> blob;
+ EXPECT_TRUE(registry_->Register(blob.InitWithNewPipeAndPassReceiver(), kId,
+ "", "", std::move(elements)));
+
+ std::unique_ptr<BlobDataHandle> handle = context_->GetBlobDataFromUUID(kId);
+ WaitForBlobCompletion(handle.get());
+
+ EXPECT_TRUE(handle->IsBroken());
+ ASSERT_EQ(BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS,
+ handle->GetBlobStatus());
+
+ EXPECT_EQ(1u, reply_request_count_);
+ EXPECT_EQ(0u, stream_request_count_);
+ EXPECT_EQ(0u, file_request_count_);
+ EXPECT_EQ(0u, BlobsUnderConstruction());
+
+ // Expect 2 bad messages, one for the bad reply by the bytes provider, and one
+ // for the original register call.
+ EXPECT_EQ(2u, bad_messages_.size());
+}
+
TEST_F(BlobRegistryImplTest, Register_ValidBytesAsStream) {
const std::string kId = "id";
const std::string kData =

View File

@@ -0,0 +1,82 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Daniel Cheng <dcheng@chromium.org>
Date: Fri, 10 Apr 2020 00:43:45 +0000
Subject: Use std::deque to store the stack of currently executing tasks
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The stack of currently executing stacks includes a PendingTask field. A
pointer to this field is stored in TLS. However, std::vector does not
guarantee pointer stability on resize.
(cherry picked from commit c34431a597aba8f4374975217d97a73eaf7d1f18)
Bug: 1064891
Change-Id: I04eb06c9521722f08fd72826f552cedaffe61b53
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2146349
Commit-Queue: Daniel Cheng <dcheng@chromium.org>
Reviewed-by: Sami Kyöstilä <skyostil@chromium.org>
Reviewed-by: François Doray <fdoray@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#759017}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2158048
Cr-Commit-Position: refs/branch-heads/4044@{#970}
Cr-Branched-From: a6d9daf149a473ceea37f629c41d4527bf2055bd-refs/heads/master@{#737173}
diff --git a/base/task/sequence_manager/sequence_manager_impl.cc b/base/task/sequence_manager/sequence_manager_impl.cc
index f719a33fff0c98dc7113b4b094bc46809dc66c00..ed951d323a1c7025d99a04d4481abc1f68dfb017 100644
--- a/base/task/sequence_manager/sequence_manager_impl.cc
+++ b/base/task/sequence_manager/sequence_manager_impl.cc
@@ -50,13 +50,6 @@ const scoped_refptr<SequencedTaskRunner>& GetNullTaskRunner() {
} // namespace
-// This controls how big the the initial for
-// |MainThreadOnly::task_execution_stack| should be. We don't expect to see
-// depths of more than 2 unless cooperative scheduling is used on Blink, where
-// we might get up to 6. Anyway 10 was chosen because it's a round number
-// greater than current anticipated usage.
-static constexpr const size_t kInitialTaskExecutionStackReserveCount = 10;
-
std::unique_ptr<SequenceManager> CreateSequenceManagerOnCurrentThread(
SequenceManager::Settings settings) {
return internal::SequenceManagerImpl::CreateOnCurrentThread(
@@ -267,7 +260,6 @@ SequenceManagerImpl::MainThreadOnly::MainThreadOnly(
random_generator = std::mt19937_64(RandUint64());
uniform_distribution = std::uniform_real_distribution<double>(0.0, 1.0);
}
- task_execution_stack.reserve(kInitialTaskExecutionStackReserveCount);
}
SequenceManagerImpl::MainThreadOnly::~MainThreadOnly() = default;
diff --git a/base/task/sequence_manager/sequence_manager_impl.h b/base/task/sequence_manager/sequence_manager_impl.h
index ddd0a580eb71300f6ec68903ff1467808707ec82..e2819c68fd2f3c19940e0f26248835abd1e55fda 100644
--- a/base/task/sequence_manager/sequence_manager_impl.h
+++ b/base/task/sequence_manager/sequence_manager_impl.h
@@ -5,6 +5,7 @@
#ifndef BASE_TASK_SEQUENCE_MANAGER_SEQUENCE_MANAGER_IMPL_H_
#define BASE_TASK_SEQUENCE_MANAGER_SEQUENCE_MANAGER_IMPL_H_
+#include <deque>
#include <list>
#include <map>
#include <memory>
@@ -12,7 +13,6 @@
#include <set>
#include <unordered_map>
#include <utility>
-#include <vector>
#include "base/atomic_sequence_num.h"
#include "base/cancelable_callback.h"
@@ -308,7 +308,9 @@ class BASE_EXPORT SequenceManagerImpl
bool nesting_observer_registered_ = false;
// Due to nested runloops more than one task can be executing concurrently.
- std::vector<ExecutingTask> task_execution_stack;
+ // Note that this uses std::deque for pointer stability, since pointers to
+ // objects in this container are stored in TLS.
+ std::deque<ExecutingTask> task_execution_stack;
Observer* observer = nullptr; // NOT OWNED

View File

@@ -0,0 +1,144 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Rouslan Solomakhin <rouslan@chromium.org>
Date: Wed, 15 Apr 2020 23:03:07 +0000
Subject: Browser context owned callback.
Before this patch, an unowned function pointer would be invoked
asynchronously with a reference to the possibly freed reference to the
browser context, which could cause use after free in certain
circumstances.
This patch makes the browser context own the callback and binds the
function with a weak pointer, so freeing the browser context invalidates
the weak pointer, which cancels the callback execution.
After this patch, freeing the browser context aborts the asynchronous
callback that dereferences the browser context, so the use after free
is prevented.
TBR=rouslan@chromium.org
(cherry picked from commit 2d0aad1e7602a7076d86772cc159b891cf2cf03b)
Bug: 1065298
Change-Id: Id6de3099a55c4505e94a8a6d21fb25d6d2b34c6c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2144311
Reviewed-by: Danyao Wang <danyao@chromium.org>
Commit-Queue: Rouslan Solomakhin <rouslan@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#758404}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2151474
Reviewed-by: Rouslan Solomakhin <rouslan@chromium.org>
Cr-Commit-Position: refs/branch-heads/4044@{#942}
Cr-Branched-From: a6d9daf149a473ceea37f629c41d4527bf2055bd-refs/heads/master@{#737173}
diff --git a/content/browser/payments/payment_app_provider_impl.cc b/content/browser/payments/payment_app_provider_impl.cc
index 3b813cb22c15e85c9e0da1b0060a4514e6522db5..83c26a3e1801dc780d83ee34136ca1513e343339 100644
--- a/content/browser/payments/payment_app_provider_impl.cc
+++ b/content/browser/payments/payment_app_provider_impl.cc
@@ -15,6 +15,7 @@
#include "base/metrics/histogram_macros.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
+#include "base/supports_user_data.h"
#include "base/task/post_task.h"
#include "base/token.h"
#include "content/browser/payments/payment_app_context_impl.h"
@@ -432,28 +433,65 @@ void OnInstallPaymentApp(
}
}
-void CheckPermissionForPaymentApps(
- BrowserContext* browser_context,
- PaymentAppProvider::GetAllPaymentAppsCallback callback,
- PaymentAppProvider::PaymentApps apps) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
+// Callbacks for checking permissions asynchronously. Owned by the browser
+// context to avoid using the browser context after it has been freed. Deleted
+// after the callback is invoked.
+// Sample usage:
+// PostTask(&PermissionChecker::CheckPermissionForPaymentApps,
+// PermissionChecker::Create(browser_context), std::move(callback));
+class PermissionChecker : public base::SupportsUserData::Data {
+ public:
+ static base::WeakPtr<PermissionChecker> Create(
+ BrowserContext* browser_context) {
+ auto owned = std::make_unique<PermissionChecker>(browser_context);
+ auto weak_pointer_result = owned->weak_ptr_factory_.GetWeakPtr();
+ void* key = owned.get();
+ browser_context->SetUserData(key, std::move(owned));
+ return weak_pointer_result;
+ }
+
+ // Do not use this method directly! Use the static PermissionChecker::Create()
+ // method instead. (The constructor must be public for std::make_unique<> in
+ // the Create() method.)
+ explicit PermissionChecker(BrowserContext* browser_context)
+ : browser_context_(browser_context) {}
+ ~PermissionChecker() override = default;
+
+ // Disallow copy and assign.
+ PermissionChecker(const PermissionChecker& other) = delete;
+ PermissionChecker& operator=(const PermissionChecker& other) = delete;
+
+ void CheckPermissionForPaymentApps(
+ PaymentAppProvider::GetAllPaymentAppsCallback callback,
+ PaymentAppProvider::PaymentApps apps) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
- PermissionController* permission_controller =
- BrowserContext::GetPermissionController(browser_context);
- DCHECK(permission_controller);
-
- PaymentAppProvider::PaymentApps permitted_apps;
- for (auto& app : apps) {
- GURL origin = app.second->scope.GetOrigin();
- if (permission_controller->GetPermissionStatus(
- PermissionType::PAYMENT_HANDLER, origin, origin) ==
- blink::mojom::PermissionStatus::GRANTED) {
- permitted_apps[app.first] = std::move(app.second);
+ PermissionController* permission_controller =
+ BrowserContext::GetPermissionController(browser_context_);
+ DCHECK(permission_controller);
+
+ PaymentAppProvider::PaymentApps permitted_apps;
+ for (auto& app : apps) {
+ GURL origin = app.second->scope.GetOrigin();
+ if (permission_controller->GetPermissionStatus(
+ PermissionType::PAYMENT_HANDLER, origin, origin) ==
+ blink::mojom::PermissionStatus::GRANTED) {
+ permitted_apps[app.first] = std::move(app.second);
+ }
}
+
+ std::move(callback).Run(std::move(permitted_apps));
+
+ // Deletes this PermissionChecker object.
+ browser_context_->RemoveUserData(/*key=*/this);
}
- std::move(callback).Run(std::move(permitted_apps));
-}
+ private:
+ // Owns this PermissionChecker object, so it's always valid.
+ BrowserContext* browser_context_;
+
+ base::WeakPtrFactory<PermissionChecker> weak_ptr_factory_{this};
+};
void AbortInvokePaymentApp(BrowserContext* browser_context,
PaymentEventResponseType reason) {
@@ -606,9 +644,11 @@ void PaymentAppProviderImpl::GetAllPaymentApps(
RunOrPostTaskOnThread(
FROM_HERE, ServiceWorkerContext::GetCoreThreadId(),
- base::BindOnce(&GetAllPaymentAppsOnCoreThread, payment_app_context,
- base::BindOnce(&CheckPermissionForPaymentApps,
- browser_context, std::move(callback))));
+ base::BindOnce(
+ &GetAllPaymentAppsOnCoreThread, payment_app_context,
+ base::BindOnce(&PermissionChecker::CheckPermissionForPaymentApps,
+ PermissionChecker::Create(browser_context),
+ std::move(callback))));
}
void PaymentAppProviderImpl::InvokePaymentApp(

View File

@@ -0,0 +1,191 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Mason Freed <masonfreed@chromium.org>
Date: Mon, 20 Apr 2020 21:57:52 +0000
Subject: Fix customized built-in element constructor behavior
This CL implements two changes:
1. It fixes the implementation to better match the spec for the
"create an element for the token" [1] algorithm. Prior to this CL,
step 7 of that algorithm was skipping directly to step 6 of the
"create an element" [2] algorithm, skipping over step 5 for
customized built-in elements. This is now fixed. This case is
illustrated by the issue and example at [3] and [4]. This becomes
the first test in customized-built-in-constructor-exceptions.html.
2. It updates the comments to match the new behavior discussed in [3]
and the [5] spec PR, which changes the return value in the case
that a customized built-in element constructor throws an exception.
With the change above, that is actually already the behavior. So
this is just a comment change. Two new tests are added to
customized-built-in-constructor-exceptions.html.
[1] https://html.spec.whatwg.org/multipage/parsing.html#create-an-element-for-the-token
[2] https://dom.spec.whatwg.org/#concept-create-element
[3] https://github.com/whatwg/html/issues/5084
[4] https://crbug.com/1024866
[5] https://github.com/whatwg/dom/pull/797
Bug: 1071059, 1024866
Change-Id: I814c81991eb5e83501304bcb3d2da476743aef52
Cq-Do-Not-Cancel-Tryjobs: true
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2152986
Commit-Queue: Mason Freed <masonfreed@chromium.org>
Auto-Submit: Mason Freed <masonfreed@chromium.org>
Reviewed-by: Kent Tamura <tkent@chromium.org>
Cr-Commit-Position: refs/heads/master@{#760705}
diff --git a/third_party/blink/renderer/bindings/core/v8/script_custom_element_definition.cc b/third_party/blink/renderer/bindings/core/v8/script_custom_element_definition.cc
index 075b20837c75f736d4580e2b17b0568e0c36e48c..363ccb5f7c919ee1990b27684bc89c1cd4a805af 100644
--- a/third_party/blink/renderer/bindings/core/v8/script_custom_element_definition.cc
+++ b/third_party/blink/renderer/bindings/core/v8/script_custom_element_definition.cc
@@ -137,6 +137,7 @@ HTMLElement* ScriptCustomElementDefinition::HandleCreateElementSyncException(
HTMLElement* ScriptCustomElementDefinition::CreateAutonomousCustomElementSync(
Document& document,
const QualifiedName& tag_name) {
+ DCHECK(CustomElement::ShouldCreateCustomElement(tag_name)) << tag_name;
if (!script_state_->ContextIsValid())
return CustomElement::CreateFailedElement(document, tag_name);
ScriptState::Scope scope(script_state_);
diff --git a/third_party/blink/renderer/core/html/custom/custom_element.cc b/third_party/blink/renderer/core/html/custom/custom_element.cc
index d21c582052cbf861b792ec6f44e418cc25f3a8cc..1edcd4e60009c9f994c0711a8d373d771b4e8965 100644
--- a/third_party/blink/renderer/core/html/custom/custom_element.cc
+++ b/third_party/blink/renderer/core/html/custom/custom_element.cc
@@ -205,7 +205,8 @@ Element* CustomElement::CreateUncustomizedOrUndefinedElement(
HTMLElement* CustomElement::CreateFailedElement(Document& document,
const QualifiedName& tag_name) {
- DCHECK(ShouldCreateCustomElement(tag_name));
+ CHECK(ShouldCreateCustomElement(tag_name))
+ << "HTMLUnknownElement with built-in tag name: " << tag_name;
// "create an element for a token":
// https://html.spec.whatwg.org/C/#create-an-element-for-the-token
diff --git a/third_party/blink/renderer/core/html/custom/custom_element_definition.cc b/third_party/blink/renderer/core/html/custom/custom_element_definition.cc
index 6126e0d04c48e8f7cebe8dbf39418599fcfcb84e..3341f49f48de367cbe4f736c4acac09c5d59ddbd 100644
--- a/third_party/blink/renderer/core/html/custom/custom_element_definition.cc
+++ b/third_party/blink/renderer/core/html/custom/custom_element_definition.cc
@@ -142,14 +142,19 @@ HTMLElement* CustomElementDefinition::CreateElement(
result->SetCustomElementState(CustomElementState::kUndefined);
result->SetIsValue(Descriptor().GetName());
- // 5.3. If the synchronous custom elements flag is set, upgrade
- // element using definition.
- // 5.4. Otherwise, enqueue a custom element upgrade reaction given
- // result and definition.
- if (!flags.IsAsyncCustomElements())
+ if (!flags.IsAsyncCustomElements()) {
+ // 5.3 If the synchronous custom elements flag is set, then run this step
+ // while catching any exceptions:
+ // 1. Upgrade element using definition.
+ // If this step threw an exception, then:
+ // 1. Report the exception.
+ // 2. Set result's custom element state to "failed".
Upgrade(*result);
- else
+ } else {
+ // 5.4. Otherwise, enqueue a custom element upgrade reaction given
+ // result and definition.
EnqueueUpgradeReaction(*result);
+ }
return To<HTMLElement>(result);
}
diff --git a/third_party/blink/renderer/core/html/parser/html_construction_site.cc b/third_party/blink/renderer/core/html/parser/html_construction_site.cc
index e5b8596cb60c8baf9c6d1a18d0c788985f8790b8..e98bb816eaa6f63b672a69425ea338e9521713d0 100644
--- a/third_party/blink/renderer/core/html/parser/html_construction_site.cc
+++ b/third_party/blink/renderer/core/html/parser/html_construction_site.cc
@@ -919,8 +919,11 @@ Element* HTMLConstructionSite::CreateElement(
// reactions stack."
CEReactionsScope reactions;
- // 7.
- element = definition->CreateAutonomousCustomElementSync(document, tag_name);
+ // 7. Let element be the result of creating an element given document,
+ // localName, given namespace, null, and is. If will execute script is true,
+ // set the synchronous custom elements flag; otherwise, leave it unset.
+ element =
+ definition->CreateElement(document, tag_name, GetCreateElementFlags());
// "8. Append each attribute in the given token to element." We don't use
// setAttributes here because the custom element constructor may have
diff --git a/third_party/blink/web_tests/external/wpt/custom-elements/customized-built-in-constructor-exceptions.html b/third_party/blink/web_tests/external/wpt/custom-elements/customized-built-in-constructor-exceptions.html
new file mode 100644
index 0000000000000000000000000000000000000000..32729bdb6bb2c82f54c074c7609ff5c79883a37a
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/custom-elements/customized-built-in-constructor-exceptions.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<title>Customized built-in element constructor behavior</title>
+<meta name='author' title='Mason Freed' href='mailto:masonfreed@chromium.org'>
+<link rel='help' href='https://dom.spec.whatwg.org/#concept-create-element'>
+<script src='/resources/testharness.js'></script>
+<script src='/resources/testharnessreport.js'></script>
+
+<script>
+setup({allow_uncaught_exception : true});
+
+class MyCustomParagraph extends HTMLParagraphElement {
+ constructor() {
+ super();
+ this.textContent = 'PASS';
+ }
+}
+customElements.define('custom-p', MyCustomParagraph, { extends: 'p' });
+</script>
+<p id=targetp is='custom-p'></p>
+<script>
+test(t => {
+ let target = document.getElementById('targetp');
+ assert_true(!!target);
+ assert_equals(target.localName, 'p');
+ assert_true(target instanceof MyCustomParagraph);
+ assert_true(target instanceof HTMLParagraphElement);
+ assert_equals(target.childNodes.length, 1);
+ assert_equals(target.textContent, 'PASS');
+}, 'Appending children in customized built-in constructor should work');
+</script>
+
+
+<script>
+class MyCustomVideo extends HTMLVideoElement {
+ constructor() {
+ super();
+ throw new Error();
+ }
+}
+customElements.define('custom-video', MyCustomVideo, { extends: 'video' });
+</script>
+<video id=targetvideo is='custom-video'> <source></source> </video>
+<script>
+test(t => {
+ let target = document.getElementById('targetvideo');
+ assert_true(!!target);
+ assert_equals(target.localName, 'video');
+ assert_true(target instanceof MyCustomVideo);
+ assert_true(target instanceof HTMLVideoElement);
+ assert_equals(target.children.length, 1);
+}, 'Throwing exception in customized built-in constructor should not crash and should return correct element type (video)');
+</script>
+
+
+<script>
+class MyCustomForm extends HTMLFormElement {
+ constructor() {
+ super();
+ throw new Error();
+ }
+}
+customElements.define('custom-form', MyCustomForm, { extends: 'form' });
+</script>
+<form id=targetform is='custom-form'> <label></label><input> </form>
+<script>
+test(t => {
+ let target = document.getElementById('targetform');
+ assert_true(!!target);
+ assert_equals(target.localName, 'form');
+ assert_true(target instanceof MyCustomForm);
+ assert_true(target instanceof HTMLFormElement);
+ assert_equals(target.children.length, 2);
+}, 'Throwing exception in customized built-in constructor should not crash and should return correct element type (form)');
+</script>
+

View File

@@ -0,0 +1,50 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Mustafa Emre Acer <meacer@chromium.org>
Date: Fri, 10 Apr 2020 00:43:45 +0000
Subject: Don't decode invalid punycode in URL formatter
TBR=meacer@chromium.org
(cherry picked from commit 50c6e900fc4170a14154cbfea57ade2aa50990b5)
Bug: 1063566
Change-Id: I631ba68718cf69c5972555d7826b089e27fa5150
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2137872
Reviewed-by: Peter Kasting <pkasting@chromium.org>
Commit-Queue: Peter Kasting <pkasting@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#756819}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2144830
Reviewed-by: Mustafa Emre Acer <meacer@chromium.org>
Cr-Commit-Position: refs/branch-heads/4103@{#62}
Cr-Branched-From: 8ad47e8d21f6866e4a37f47d83a860d41debf514-refs/heads/master@{#756066}
diff --git a/components/url_formatter/spoof_checks/idn_spoof_checker_unittest.cc b/components/url_formatter/spoof_checks/idn_spoof_checker_unittest.cc
index f695e5c403cbcb020b2ef8016fb513ba1b8d97d1..ffd06415c9afd54c008d86f817cb0e704de87601 100644
--- a/components/url_formatter/spoof_checks/idn_spoof_checker_unittest.cc
+++ b/components/url_formatter/spoof_checks/idn_spoof_checker_unittest.cc
@@ -55,6 +55,8 @@ const IDNTestCase kIdnCases[] = {
{"www.google.com.", L"www.google.com.", true},
{".", L".", true},
{"", L"", true},
+ // Invalid IDN
+ {"xn--example-.com", L"xn--example-.com", false},
// IDN
// Hanzi (Traditional Chinese)
{"xn--1lq90ic7f1rc.cn", L"\x5317\x4eac\x5927\x5b78.cn", true},
diff --git a/components/url_formatter/url_formatter.cc b/components/url_formatter/url_formatter.cc
index 58cadb980bb877c933e37457b1ab0883357ece47..d7cc2ea441c916fb77a520f8fe440cff042b6aab 100644
--- a/components/url_formatter/url_formatter.cc
+++ b/components/url_formatter/url_formatter.cc
@@ -408,9 +408,11 @@ bool IDNToUnicodeOneComponent(const base::char16* comp,
return false;
// Early return if the input cannot be an IDN component.
+ // Valid punycode must not end with a dash.
static const base::char16 kIdnPrefix[] = {'x', 'n', '-', '-'};
if (comp_len <= base::size(kIdnPrefix) ||
- memcmp(comp, kIdnPrefix, sizeof(kIdnPrefix)) != 0) {
+ memcmp(comp, kIdnPrefix, sizeof(kIdnPrefix)) != 0 ||
+ comp[comp_len - 1] == '-') {
out->append(comp, comp_len);
return false;
}

View File

@@ -0,0 +1,237 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Matthias=20K=C3=B6rber?= <koerber@google.com>
Date: Tue, 14 Apr 2020 16:55:14 +0000
Subject: Fixed requesting invalid country codes from CountryData.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Change-Id: Id0ce647400bdce2eb4cdd358432b7c647f880570
Bug: 1062861
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2122057
Reviewed-by: Matthias Körber <koerber@google.com>
Reviewed-by: Dominic Battré <battre@chromium.org>
Reviewed-by: Vadym Doroshenko <dvadym@chromium.org>
Commit-Queue: Matthias Körber <koerber@google.com>
Cr-Commit-Position: refs/heads/master@{#758887}
diff --git a/components/autofill/core/browser/geo/autofill_country.cc b/components/autofill/core/browser/geo/autofill_country.cc
index 4eb8f2b1a609deb314efd9b37578be9fa803ac67..961b1dc7a19f23c6f2cf9f831f5d544cc19cd211 100644
--- a/components/autofill/core/browser/geo/autofill_country.cc
+++ b/components/autofill/core/browser/geo/autofill_country.cc
@@ -25,13 +25,28 @@ const size_t kLocaleCapacity =
AutofillCountry::AutofillCountry(const std::string& country_code,
const std::string& locale) {
- auto result =
- CountryDataMap::GetInstance()->country_data().find(country_code);
- DCHECK(result != CountryDataMap::GetInstance()->country_data().end());
- const CountryData& data = result->second;
+ CountryDataMap* country_data_map = CountryDataMap::GetInstance();
- country_code_ = country_code;
- name_ = l10n_util::GetDisplayNameForCountry(country_code, locale);
+ // If the country code is an alias (e.g. "GB" for "UK") expand the country
+ // code.
+ country_code_ = country_data_map->HasCountryCodeAlias(country_code)
+ ? country_data_map->GetCountryCodeForAlias(country_code)
+ : country_code;
+
+ // If there is no entry in the |CountryDataMap| for the
+ // |country_code_for_country_data| use the country code derived from the
+ // locale. This reverts to US.
+ country_data_map->HasCountryData(country_code_)
+ ? country_code_
+ : CountryCodeForLocale(locale);
+
+ // Acquire the country address data.
+ const CountryData& data = country_data_map->GetCountryData(country_code_);
+
+ // Translate the country name by the supplied local.
+ name_ = l10n_util::GetDisplayNameForCountry(country_code_, locale);
+
+ // Get the localized strings associate with the address fields.
postal_code_label_ = l10n_util::GetStringUTF16(data.postal_code_label_id);
state_label_ = l10n_util::GetStringUTF16(data.state_label_id);
address_required_fields_ = data.address_required_fields;
diff --git a/components/autofill/core/browser/geo/autofill_country_unittest.cc b/components/autofill/core/browser/geo/autofill_country_unittest.cc
index 8f3994de4f5d8b924cc47a989d86676ed01bd760..94315c13967f1ce640bba01a555f8b418af97ad3 100644
--- a/components/autofill/core/browser/geo/autofill_country_unittest.cc
+++ b/components/autofill/core/browser/geo/autofill_country_unittest.cc
@@ -14,6 +14,7 @@
#include "base/android/build_info.h"
#endif
+using autofill::CountryDataMap;
using base::ASCIIToUTF16;
namespace autofill {
@@ -30,6 +31,11 @@ TEST(AutofillCountryTest, AutofillCountry) {
EXPECT_EQ("US", united_states_es.country_code());
EXPECT_EQ(ASCIIToUTF16("Estados Unidos"), united_states_es.name());
+ AutofillCountry great_britain_uk_alias("UK", "en_GB");
+ EXPECT_EQ("GB", great_britain_uk_alias.country_code());
+ EXPECT_EQ("GB", great_britain_uk_alias.country_code());
+ EXPECT_EQ(ASCIIToUTF16("United Kingdom"), great_britain_uk_alias.name());
+
AutofillCountry canada_en("CA", "en_US");
EXPECT_EQ("CA", canada_en.country_code());
EXPECT_EQ(ASCIIToUTF16("Canada"), canada_en.name());
@@ -74,4 +80,27 @@ TEST(AutofillCountryTest, AllCountryCodesHaveCountryName) {
}
}
+// Test alias mappings for falsely existing country codes.
+TEST(AutofillCountryTest, AliasMappingsForCountryData) {
+ CountryDataMap* country_data_map = CountryDataMap::GetInstance();
+
+ // There should be country data for the "GB".
+ EXPECT_TRUE(country_data_map->HasCountryData("GB"));
+
+ // Check the correctness of the alias definitions.
+ EXPECT_TRUE(country_data_map->HasCountryCodeAlias("UK"));
+ EXPECT_FALSE(country_data_map->HasCountryCodeAlias("does_not_exist"));
+
+ // Query not existing mapping.
+ auto expected_country_code = std::string();
+ auto actual_country_code =
+ country_data_map->GetCountryCodeForAlias("does_not_exist");
+ EXPECT_EQ(expected_country_code, actual_country_code);
+
+ // GB should map the UK.
+ expected_country_code = "GB";
+ actual_country_code = country_data_map->GetCountryCodeForAlias("UK");
+ EXPECT_EQ(expected_country_code, actual_country_code);
+}
+
} // namespace autofill
diff --git a/components/autofill/core/browser/geo/country_data.cc b/components/autofill/core/browser/geo/country_data.cc
index 1fe65ecf65323ce1917cb786b63d10ea4a7ac0b7..ec78e723ca71972d32ba00c2b46de9673fe91f46 100644
--- a/components/autofill/core/browser/geo/country_data.cc
+++ b/components/autofill/core/browser/geo/country_data.cc
@@ -19,6 +19,17 @@ struct StaticCountryData {
CountryData country_data;
};
+// Alias definitions record for CountryData requests. A request for
+// |country_code_alias| is served with the |CountryData| for
+// |country_code_target|.
+struct StaticCountryCodeAliasData {
+ char country_code_alias[3];
+ char country_code_target[3];
+};
+
+// Alias definitions.
+const StaticCountryCodeAliasData kCountryCodeAliases[] = {{"UK", "GB"}};
+
// Maps country codes to localized label string identifiers. Keep this sorted
// by country code.
// This list is comprized of countries appearing in both
@@ -790,7 +801,7 @@ std::vector<std::string> GetCountryCodes() {
return country_codes;
}
-std::map<std::string, CountryData> GetCountryData() {
+std::map<std::string, CountryData> GetCountryDataMap() {
std::map<std::string, CountryData> country_data;
// Add all the countries we have explicit data for.
for (const auto& static_data : kCountryData) {
@@ -813,6 +824,18 @@ std::map<std::string, CountryData> GetCountryData() {
return country_data;
}
+std::map<std::string, std::string> GetCountryCodeAliasMap() {
+ std::map<std::string, std::string> country_code_aliases;
+ // Create mappings for the aliases defined in |kCountryCodeAliases|.
+ for (const auto& static_alias_data : kCountryCodeAliases) {
+ // Insert the alias.
+ country_code_aliases.insert(
+ std::make_pair(std::string(static_alias_data.country_code_alias),
+ std::string(static_alias_data.country_code_target)));
+ }
+ return country_code_aliases;
+}
+
} // namespace
// static
@@ -821,8 +844,38 @@ CountryDataMap* CountryDataMap::GetInstance() {
}
CountryDataMap::CountryDataMap()
- : country_data_(GetCountryData()), country_codes_(GetCountryCodes()) {}
+ : country_data_(GetCountryDataMap()),
+ country_code_aliases_(GetCountryCodeAliasMap()),
+ country_codes_(GetCountryCodes()) {}
CountryDataMap::~CountryDataMap() = default;
+bool CountryDataMap::HasCountryData(const std::string& country_code) const {
+ return country_data_.count(country_code) > 0;
+}
+
+const CountryData& CountryDataMap::GetCountryData(
+ const std::string& country_code) const {
+ auto lookup = country_data_.find(country_code);
+ if (lookup != country_data_.end())
+ return lookup->second;
+ // If there is no entry for country_code return the entry for the US.
+ return country_data_.find("US")->second;
+}
+
+bool CountryDataMap::HasCountryCodeAlias(
+ const std::string& country_code_alias) const {
+ return country_code_aliases_.count(country_code_alias) > 0;
+}
+
+const std::string CountryDataMap::GetCountryCodeForAlias(
+ const std::string& country_code_alias) const {
+ auto lookup = country_code_aliases_.find(country_code_alias);
+ if (lookup != country_code_aliases_.end()) {
+ DCHECK(HasCountryData(lookup->second));
+ return lookup->second;
+ }
+ return std::string();
+}
+
} // namespace autofill
diff --git a/components/autofill/core/browser/geo/country_data.h b/components/autofill/core/browser/geo/country_data.h
index b6a9497594b1c22a5521a9c40fab2decae449c3f..8266102deadd40e5f2b9b24703123f59034a9781 100644
--- a/components/autofill/core/browser/geo/country_data.h
+++ b/components/autofill/core/browser/geo/country_data.h
@@ -58,10 +58,23 @@ class CountryDataMap {
public:
static CountryDataMap* GetInstance();
- const std::map<std::string, CountryData>& country_data() {
- return country_data_;
- }
+ // Returns true if a |CountryData| entry for the supplied |country_code|
+ // exists.
+ bool HasCountryData(const std::string& country_code) const;
+ // Returns true if there is a country code alias for |country_code|.
+ bool HasCountryCodeAlias(const std::string& country_code_alias) const;
+
+ // Returns the country code for a country code alias. If no alias definition
+ // is present return an empty string.
+ const std::string GetCountryCodeForAlias(
+ const std::string& country_code_alias) const;
+
+ // Lookup the |CountryData| for the supplied |country_code|. If no entry
+ // exists, return the data for the US as a best guess.
+ const CountryData& GetCountryData(const std::string& country_code) const;
+
+ // Return a constant reference to a vector of all country codes.
const std::vector<std::string>& country_codes() { return country_codes_; }
private:
@@ -70,6 +83,7 @@ class CountryDataMap {
friend struct base::DefaultSingletonTraits<CountryDataMap>;
const std::map<std::string, CountryData> country_data_;
+ const std::map<std::string, std::string> country_code_aliases_;
const std::vector<std::string> country_codes_;
DISALLOW_COPY_AND_ASSIGN(CountryDataMap);

View File

@@ -0,0 +1,257 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Martin Kreichgauer <martinkr@google.com>
Date: Wed, 3 Jun 2020 21:07:08 +0000
Subject: Revert "fido: add FidoDiscoveryFactory::ResetRequestState()"
This reverts commit 9f151687295d2547bc3d7c1542b80505552f0f87.
Reason for revert: The original change makes an invalid assumptions
about the lifetime of FidoDiscoveryFactory (crbug/1087158). Instances of
FidoDiscoveryFactory generally belong to the
AuthenticatorRequestClientDelegate and as such should outlive the
WebAuthn request. As an exception, instances obtained via
AuthenticatorEnvironmentImpl::GetDiscoveryFactoryOverride() may be
unregistered and freed before the request finishes.
This revert is safe because the caBLE data reset by ResetRequestState
(a) only gets set in the first place if the
WebAuthenticationPhoneSupport flag is on (which is default-off); and (b)
gets set anew for every single request, so it will never be reused
across requests.
Bug: 1087158
Original change's description:
> fido: add FidoDiscoveryFactory::ResetRequestState()
>
> FidoDiscoveryFactory instances generally outlive a WebAuthn request, but
> some of the state is specific to a single request (caBLE pairing and QR
> code generation keys). This is currently not an issue, because
> AuthenticatorCommon explicitly resets all that state at the beginning of
> the request. But I worry that we accidentally break that and leak state
> between requests. To mitigate, introduce an explicit ResetRequestState
> function and call it in AuthenticatorCommon::Cleanup().
>
> Change-Id: I8333a3b14d189d7977cde17cbfe44b4b8dcf6ee2
> Reviewed-on:
> https://chromium-review.googlesource.com/c/chromium/src/+/1793792
> Commit-Queue: Martin Kreichgauer <martinkr@chromium.org>
> Reviewed-by: Nina Satragno <nsatragno@chromium.org>
> Reviewed-by: Adam Langley <agl@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#696593}
Change-Id: I3b1ea46b9b1d5912cbc7ab9a82851e5132335ea8
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2228136
Reviewed-by: Nina Satragno <nsatragno@chromium.org>
Reviewed-by: Adam Langley <agl@chromium.org>
Commit-Queue: Martin Kreichgauer <martinkr@google.com>
Cr-Commit-Position: refs/heads/master@{#774784}
diff --git a/content/browser/webauth/authenticator_common.cc b/content/browser/webauth/authenticator_common.cc
index cea81abea6f8059ff09de9c9a55c305446a0b661..7721eac960bd69351bd6963871f9f1bb96756915 100644
--- a/content/browser/webauth/authenticator_common.cc
+++ b/content/browser/webauth/authenticator_common.cc
@@ -579,13 +579,12 @@ AuthenticatorCommon::CreateRequestDelegate(std::string relying_party_id) {
void AuthenticatorCommon::StartMakeCredentialRequest(
bool allow_skipping_pin_touch) {
- discovery_factory_ =
+ device::FidoDiscoveryFactory* discovery_factory =
AuthenticatorEnvironmentImpl::GetInstance()->GetDiscoveryFactoryOverride(
static_cast<RenderFrameHostImpl*>(render_frame_host_)
->frame_tree_node());
- if (!discovery_factory_) {
- discovery_factory_ = request_delegate_->GetDiscoveryFactory();
- }
+ if (!discovery_factory)
+ discovery_factory = request_delegate_->GetDiscoveryFactory();
if (base::FeatureList::IsEnabled(device::kWebAuthPhoneSupport)) {
std::vector<device::CableDiscoveryData> cable_pairings =
@@ -597,13 +596,13 @@ void AuthenticatorCommon::StartMakeCredentialRequest(
if (request_delegate_->SetCableTransportInfo(
/*cable_extension_provided=*/false, have_paired_phones,
qr_generator_key)) {
- discovery_factory_->set_cable_data(cable_pairings,
- std::move(qr_generator_key));
+ discovery_factory->set_cable_data(cable_pairings,
+ std::move(qr_generator_key));
}
}
request_ = std::make_unique<device::MakeCredentialRequestHandler>(
- connector_, discovery_factory_,
+ connector_, discovery_factory,
GetTransports(caller_origin_, transports_),
*ctap_make_credential_request_, *authenticator_selection_criteria_,
allow_skipping_pin_touch,
@@ -634,13 +633,12 @@ void AuthenticatorCommon::StartMakeCredentialRequest(
void AuthenticatorCommon::StartGetAssertionRequest(
bool allow_skipping_pin_touch) {
- discovery_factory_ =
+ device::FidoDiscoveryFactory* discovery_factory =
AuthenticatorEnvironmentImpl::GetInstance()->GetDiscoveryFactoryOverride(
static_cast<RenderFrameHostImpl*>(render_frame_host_)
->frame_tree_node());
- if (!discovery_factory_) {
- discovery_factory_ = request_delegate_->GetDiscoveryFactory();
- }
+ if (!discovery_factory)
+ discovery_factory = request_delegate_->GetDiscoveryFactory();
std::vector<device::CableDiscoveryData> cable_pairings;
bool have_cable_extension = false;
@@ -664,12 +662,12 @@ void AuthenticatorCommon::StartGetAssertionRequest(
if ((!cable_pairings.empty() || qr_generator_key.has_value()) &&
request_delegate_->SetCableTransportInfo(
have_cable_extension, have_paired_phones, qr_generator_key)) {
- discovery_factory_->set_cable_data(std::move(cable_pairings),
- std::move(qr_generator_key));
+ discovery_factory->set_cable_data(std::move(cable_pairings),
+ std::move(qr_generator_key));
}
request_ = std::make_unique<device::GetAssertionRequestHandler>(
- connector_, discovery_factory_,
+ connector_, discovery_factory,
GetTransports(caller_origin_, transports_), *ctap_get_assertion_request_,
allow_skipping_pin_touch,
base::BindOnce(&AuthenticatorCommon::OnSignResponse,
@@ -1528,15 +1526,6 @@ void AuthenticatorCommon::Cleanup() {
timer_->Stop();
request_.reset();
- if (discovery_factory_) {
- // The FidoDiscoveryFactory instance may have been obtained via
- // AuthenticatorEnvironmentImpl::GetDiscoveryFactoryOverride() (in unit
- // tests or when WebDriver injected a virtual authenticator), in which case
- // it may be long-lived and handle more than one request. Hence, we need to
- // reset all per-request state before deleting its pointer.
- discovery_factory_->ResetRequestState();
- discovery_factory_ = nullptr;
- }
request_delegate_.reset();
make_credential_response_callback_.Reset();
get_assertion_response_callback_.Reset();
diff --git a/content/browser/webauth/authenticator_common.h b/content/browser/webauth/authenticator_common.h
index a7879a77f337e9d31afb954c2fc397cedb74256f..bd241cc8fc34ce9d831ce5fcfb97fbd6997237f0 100644
--- a/content/browser/webauth/authenticator_common.h
+++ b/content/browser/webauth/authenticator_common.h
@@ -194,7 +194,6 @@ class CONTENT_EXPORT AuthenticatorCommon {
RenderFrameHost* const render_frame_host_;
service_manager::Connector* connector_ = nullptr;
base::flat_set<device::FidoTransportProtocol> transports_;
- device::FidoDiscoveryFactory* discovery_factory_ = nullptr;
std::unique_ptr<device::FidoRequestHandlerBase> request_;
blink::mojom::Authenticator::MakeCredentialCallback
make_credential_response_callback_;
diff --git a/device/fido/fido_discovery_factory.cc b/device/fido/fido_discovery_factory.cc
index 05d5f211b17021ac3397fd79b7f210bdf6681def..dc404ba31c2158887c3f946aecba33fb672189f0 100644
--- a/device/fido/fido_discovery_factory.cc
+++ b/device/fido/fido_discovery_factory.cc
@@ -46,10 +46,6 @@ std::unique_ptr<FidoDiscoveryBase> CreateUsbFidoDiscovery(
FidoDiscoveryFactory::FidoDiscoveryFactory() = default;
FidoDiscoveryFactory::~FidoDiscoveryFactory() = default;
-void FidoDiscoveryFactory::ResetRequestState() {
- request_state_ = {};
-}
-
std::unique_ptr<FidoDiscoveryBase> FidoDiscoveryFactory::Create(
FidoTransportProtocol transport,
service_manager::Connector* connector) {
@@ -59,13 +55,10 @@ std::unique_ptr<FidoDiscoveryBase> FidoDiscoveryFactory::Create(
case FidoTransportProtocol::kBluetoothLowEnergy:
return std::make_unique<FidoBleDiscovery>();
case FidoTransportProtocol::kCloudAssistedBluetoothLowEnergy:
- if (request_state_.cable_data_.has_value() ||
- request_state_.qr_generator_key_.has_value()) {
+ if (cable_data_.has_value() || qr_generator_key_.has_value()) {
return std::make_unique<FidoCableDiscovery>(
- request_state_.cable_data_.value_or(
- std::vector<CableDiscoveryData>()),
- request_state_.qr_generator_key_,
- request_state_.cable_pairing_callback_);
+ cable_data_.value_or(std::vector<CableDiscoveryData>()),
+ qr_generator_key_, cable_pairing_callback_);
}
return nullptr;
case FidoTransportProtocol::kNearFieldCommunication:
@@ -88,14 +81,14 @@ std::unique_ptr<FidoDiscoveryBase> FidoDiscoveryFactory::Create(
void FidoDiscoveryFactory::set_cable_data(
std::vector<CableDiscoveryData> cable_data,
base::Optional<QRGeneratorKey> qr_generator_key) {
- request_state_.cable_data_ = std::move(cable_data);
- request_state_.qr_generator_key_ = std::move(qr_generator_key);
+ cable_data_ = std::move(cable_data);
+ qr_generator_key_ = std::move(qr_generator_key);
}
void FidoDiscoveryFactory::set_cable_pairing_callback(
base::RepeatingCallback<void(std::unique_ptr<CableDiscoveryData>)>
pairing_callback) {
- request_state_.cable_pairing_callback_.emplace(std::move(pairing_callback));
+ cable_pairing_callback_.emplace(std::move(pairing_callback));
}
#if defined(OS_WIN)
@@ -121,7 +114,4 @@ FidoDiscoveryFactory::MaybeCreateWinWebAuthnApiDiscovery() {
}
#endif // defined(OS_WIN)
-FidoDiscoveryFactory::RequestState::RequestState() = default;
-FidoDiscoveryFactory::RequestState::~RequestState() = default;
-
} // namespace device
diff --git a/device/fido/fido_discovery_factory.h b/device/fido/fido_discovery_factory.h
index 63133e7dc2bca9dc763881d74ca1e017f5799df7..3723225f316e4766d96b24f135980321bb0e5308 100644
--- a/device/fido/fido_discovery_factory.h
+++ b/device/fido/fido_discovery_factory.h
@@ -38,18 +38,6 @@ class COMPONENT_EXPORT(DEVICE_FIDO) FidoDiscoveryFactory {
FidoDiscoveryFactory();
virtual ~FidoDiscoveryFactory();
- // Resets all fields that are only meaningful for the duration of a single
- // request to a safe default.
- //
- // The "regular" FidoDiscoveryFactory is owned by the
- // AuthenticatorClientRequestDelegate and lives only for a single request.
- // Instances returned from
- // AuthenticatorEnvironmentImpl::GetDiscoveryFactoryOverride(), which are
- // used in unit tests or by the WebDriver virtual authenticators, are
- // long-lived and may handle multiple WebAuthn requests. Hence, they will be
- // reset at the beginning of each new request.
- void ResetRequestState();
-
// Instantiates a FidoDiscoveryBase for the given transport.
//
// FidoTransportProtocol::kUsbHumanInterfaceDevice requires specifying a
@@ -89,22 +77,14 @@ class COMPONENT_EXPORT(DEVICE_FIDO) FidoDiscoveryFactory {
#endif // defined(OS_WIN)
private:
- // RequestState holds configuration data that is only meaningful for a
- // single WebAuthn request.
- struct RequestState {
- RequestState();
- ~RequestState();
- base::Optional<std::vector<CableDiscoveryData>> cable_data_;
- base::Optional<QRGeneratorKey> qr_generator_key_;
- base::Optional<
- base::RepeatingCallback<void(std::unique_ptr<CableDiscoveryData>)>>
- cable_pairing_callback_;
- };
-
- RequestState request_state_;
#if defined(OS_MACOSX)
base::Optional<fido::mac::AuthenticatorConfig> mac_touch_id_config_;
#endif // defined(OS_MACOSX)
+ base::Optional<std::vector<CableDiscoveryData>> cable_data_;
+ base::Optional<QRGeneratorKey> qr_generator_key_;
+ base::Optional<
+ base::RepeatingCallback<void(std::unique_ptr<CableDiscoveryData>)>>
+ cable_pairing_callback_;
#if defined(OS_WIN)
WinWebAuthnApi* win_webauthn_api_ = nullptr;
#endif // defined(OS_WIN)

View File

@@ -3,17 +3,8 @@ From: Jeremy Apthorp <jeremya@chromium.org>
Date: Wed, 10 Oct 2018 15:07:34 -0700
Subject: command-ismediakey.patch
Override MediaKeysListener::IsMediaKeycode to also listen for Volume Up, Volume Down,
and Mute. We also need to patch out Chromium's usage of RemoteCommandCenterDelegate, as
it uses MPRemoteCommandCenter. MPRemoteCommandCenter makes it such that GlobalShortcuts
in Electron will not work as intended, because by design an app does not receive remote
control events until it begins playing audio. This means that a media shortcut would not kick
into effect until you, for example, began playing a YouTube video which sort of defeats the
purpose of GlobalShortcuts.
At the moment there is no upstream possibility for this; but perhaps Chromium may
consider some kind of switch, enabled by default, which would conditionally choose to avoid usage of
RemoteCommandCenterDelegate on macOS.
Override MediaKeysListener::IsMediaKeycode and associated functions to also listen for
Volume Up, Volume Down, and Mute.
diff --git a/chrome/browser/extensions/global_shortcut_listener_win.cc b/chrome/browser/extensions/global_shortcut_listener_win.cc
index c5125495b4d178ffb18be4d2d9670f7556412cbd..cddb321abb938c667a4a2089f87eab999510e9b1 100644
@@ -73,18 +64,10 @@ index 1145e1f3d79482b5bb468c3128431ac674310e5f..e319e7a3e34e05b0e96d4a2dbb456355
} // namespace ui
diff --git a/ui/base/accelerators/media_keys_listener_mac.mm b/ui/base/accelerators/media_keys_listener_mac.mm
index 85378bb565de617b1bd611d28c8714361747a357..d67d558b91b49835dfa927893093948093c54f7a 100644
index 85378bb565de617b1bd611d28c8714361747a357..36de4c0b0353be2418dacd388e92d7c38a7ee139 100644
--- a/ui/base/accelerators/media_keys_listener_mac.mm
+++ b/ui/base/accelerators/media_keys_listener_mac.mm
@@ -11,6 +11,7 @@
#include <IOKit/hidsystem/ev_keymap.h>
#include "base/containers/flat_set.h"
+#include "electron/buildflags/buildflags.h"
#include "ui/base/accelerators/accelerator.h"
#include "ui/base/accelerators/system_media_controls_media_keys_listener.h"
@@ -32,6 +33,12 @@ KeyboardCode MediaKeyCodeToKeyboardCode(int key_code) {
@@ -32,6 +32,12 @@ KeyboardCode MediaKeyCodeToKeyboardCode(int key_code) {
case NX_KEYTYPE_NEXT:
case NX_KEYTYPE_FAST:
return VKEY_MEDIA_NEXT_TRACK;
@@ -97,7 +80,7 @@ index 85378bb565de617b1bd611d28c8714361747a357..d67d558b91b49835dfa9278930939480
}
return VKEY_UNKNOWN;
}
@@ -192,7 +199,10 @@ static CGEventRef EventTapCallback(CGEventTapProxy proxy,
@@ -192,7 +198,10 @@ CGEventRef MediaKeysListenerImpl::EventTapCallback(CGEventTapProxy proxy,
int key_code = (data1 & 0xFFFF0000) >> 16;
if (key_code != NX_KEYTYPE_PLAY && key_code != NX_KEYTYPE_NEXT &&
key_code != NX_KEYTYPE_PREVIOUS && key_code != NX_KEYTYPE_FAST &&
@@ -109,3 +92,31 @@ index 85378bb565de617b1bd611d28c8714361747a357..d67d558b91b49835dfa9278930939480
return event;
}
diff --git a/ui/base/accelerators/system_media_controls_media_keys_listener.cc b/ui/base/accelerators/system_media_controls_media_keys_listener.cc
index 9d6084ceaccfd071549e63e3015f55ef292312ec..846210b04d6e2e193413c643296938ec550f6d25 100644
--- a/ui/base/accelerators/system_media_controls_media_keys_listener.cc
+++ b/ui/base/accelerators/system_media_controls_media_keys_listener.cc
@@ -65,6 +65,11 @@ bool SystemMediaControlsMediaKeysListener::StartWatchingMediaKey(
case VKEY_MEDIA_STOP:
service_->SetIsStopEnabled(true);
break;
+ case VKEY_VOLUME_DOWN:
+ case VKEY_VOLUME_UP:
+ case VKEY_VOLUME_MUTE:
+ // Do nothing.
+ break;
default:
NOTREACHED();
}
@@ -97,6 +102,11 @@ void SystemMediaControlsMediaKeysListener::StopWatchingMediaKey(
case VKEY_MEDIA_STOP:
service_->SetIsStopEnabled(false);
break;
+ case VKEY_VOLUME_DOWN:
+ case VKEY_VOLUME_UP:
+ case VKEY_VOLUME_MUTE:
+ // Do nothing.
+ break;
default:
NOTREACHED();
}

View File

@@ -310,7 +310,7 @@ index a947db5fb562fb4ccbfb94df88f460f1da9451f4..77c816b2c5e98a4546c74d9358dfcf3f
gfx::ColorSpace::TransferID transfer_id =
diff --git a/ui/gfx/mac/io_surface.cc b/ui/gfx/mac/io_surface.cc
index c383d42c986aa29fcdfc2009901ed452ef480b55..1b8d0818155a407eb42c3f785e9609fe7bfa3dc7 100644
index c383d42c986aa29fcdfc2009901ed452ef480b55..cdc87912b7d646a95796c84b76d583033c64c4dc 100644
--- a/ui/gfx/mac/io_surface.cc
+++ b/ui/gfx/mac/io_surface.cc
@@ -16,6 +16,7 @@
@@ -321,33 +321,37 @@ index c383d42c986aa29fcdfc2009901ed452ef480b55..1b8d0818155a407eb42c3f785e9609fe
namespace gfx {
@@ -261,6 +262,11 @@ IOSurfaceRef CreateIOSurface(const gfx::Size& size,
IOSurfaceSetValue(surface, CFSTR("IOSurfaceColorSpace"), kCGColorSpaceSRGB);
} else {
CGColorSpaceRef color_space = base::mac::GetSRGBColorSpace();
+ auto* cmd_line = base::CommandLine::ForCurrentProcess();
+ if (cmd_line->HasSwitch(switches::kDisableColorCorrectRendering)) {
+ color_space = base::mac::GetSystemColorSpace();
+ }
+
base::ScopedCFTypeRef<CFDataRef> color_space_icc(
CGColorSpaceCopyICCProfile(color_space));
IOSurfaceSetValue(surface, CFSTR("IOSurfaceColorSpace"), color_space_icc);
@@ -277,6 +283,14 @@ bool IOSurfaceCanSetColorSpace(const ColorSpace& color_space) {
void IOSurfaceSetColorSpace(IOSurfaceRef io_surface,
@@ -126,6 +127,14 @@ void IOSurfaceMachPortTraits::Release(mach_port_t port) {
// Common method used by IOSurfaceSetColorSpace and IOSurfaceCanSetColorSpace.
bool IOSurfaceSetColorSpace(IOSurfaceRef io_surface,
const ColorSpace& color_space) {
+ auto* cmd_line = base::CommandLine::ForCurrentProcess();
+ if (cmd_line->HasSwitch(switches::kDisableColorCorrectRendering)) {
+ base::ScopedCFTypeRef<CFDataRef> system_icc(
+ CGColorSpaceCopyICCProfile(base::mac::GetSystemColorSpace()));
+ IOSurfaceSetValue(io_surface, CFSTR("IOSurfaceColorSpace"), system_icc);
+ return;
+ return true;
+ }
+
if (!internal::IOSurfaceSetColorSpace(io_surface, color_space)) {
DLOG(ERROR) << "Failed to set color space for IOSurface: "
<< color_space.ToString();
// Allow but ignore invalid color spaces.
if (!color_space.IsValid())
return true;
@@ -256,6 +265,15 @@ IOSurfaceRef CreateIOSurface(const gfx::Size& size,
DCHECK_EQ(kIOReturnSuccess, r);
}
+ auto* cmd_line = base::CommandLine::ForCurrentProcess();
+ if (cmd_line->HasSwitch(switches::kDisableColorCorrectRendering)) {
+ CGColorSpaceRef color_space = base::mac::GetSystemColorSpace();
+ base::ScopedCFTypeRef<CFDataRef> color_space_icc(
+ CGColorSpaceCopyICCProfile(color_space));
+ IOSurfaceSetValue(surface, CFSTR("IOSurfaceColorSpace"), color_space_icc);
+ return surface;
+ }
+
// Ensure that all IOSurfaces start as sRGB.
if (__builtin_available(macos 10.12, *)) {
IOSurfaceSetValue(surface, CFSTR("IOSurfaceColorSpace"), kCGColorSpaceSRGB);
diff --git a/ui/gfx/switches.cc b/ui/gfx/switches.cc
index ba3dbf23d1df7a3b0cc199054f36a88014daa0e7..f8a563a78cee2856da0f2ad556beba19b01a2e59 100644
--- a/ui/gfx/switches.cc

View File

@@ -9,7 +9,7 @@ diff --git a/content/browser/renderer_host/render_widget_host_view_mac.mm b/cont
index 5bec9c5d258c06fe338c8abe3e233e0b9b937234..92d2fa2343d1272dcadfa37c07ed368d18488ef8 100644
--- a/content/browser/renderer_host/render_widget_host_view_mac.mm
+++ b/content/browser/renderer_host/render_widget_host_view_mac.mm
@@ -477,7 +477,11 @@
@@ -477,7 +477,11 @@ void RenderWidgetHostViewMac::WasOccluded() {
return;
host()->WasHidden();

View File

@@ -26,10 +26,10 @@ index d9175ae9661218b58e9b587ad3a9dbd540bfd384..ed178ea7b3d7f8039f47402bc08cae20
}
diff --git a/ui/native_theme/native_theme.h b/ui/native_theme/native_theme.h
index 205181053803813b64497884bc93cfd857254866..bb9e6fba1cb0dd734c7aeb8dcd2eeadcd4b5d2da 100644
index 205181053803813b64497884bc93cfd857254866..7b14086b43eeb86baa0f8471e15e7f6f19193889 100644
--- a/ui/native_theme/native_theme.h
+++ b/ui/native_theme/native_theme.h
@@ -431,6 +431,22 @@ class NATIVE_THEME_EXPORT NativeTheme {
@@ -431,6 +431,38 @@ class NATIVE_THEME_EXPORT NativeTheme {
ColorId color_id,
ColorScheme color_scheme = ColorScheme::kDefault) const = 0;
@@ -44,15 +44,31 @@ index 205181053803813b64497884bc93cfd857254866..bb9e6fba1cb0dd734c7aeb8dcd2eeadc
+ }
+
+ void set_theme_source(ThemeSource theme_source) {
+ bool original = ShouldUseDarkColors();
+ bool original_dark_colors = ShouldUseDarkColors();
+ PreferredColorScheme original_color_scheme = GetPreferredColorScheme();
+
+ theme_source_ = theme_source;
+ if (ShouldUseDarkColors() != original) NotifyObservers();
+
+ bool changed = false;
+ if (ShouldUseDarkColors() != original_dark_colors) {
+ changed = true;
+ }
+
+ PreferredColorScheme new_color_scheme = CalculatePreferredColorScheme();
+ if (new_color_scheme != original_color_scheme) {
+ set_preferred_color_scheme(new_color_scheme);
+ changed = true;
+ }
+
+ if (changed) {
+ NotifyObservers();
+ }
+ }
+
// Returns a shared instance of the native theme that should be used for web
// rendering. Do not use it in a normal application context (i.e. browser).
// The returned object should not be deleted by the caller. This function is
@@ -555,6 +571,8 @@ class NATIVE_THEME_EXPORT NativeTheme {
@@ -555,6 +587,8 @@ class NATIVE_THEME_EXPORT NativeTheme {
PreferredColorScheme preferred_color_scheme_ =
PreferredColorScheme::kNoPreference;
@@ -62,10 +78,10 @@ index 205181053803813b64497884bc93cfd857254866..bb9e6fba1cb0dd734c7aeb8dcd2eeadc
};
diff --git a/ui/native_theme/native_theme_dark_aura.cc b/ui/native_theme/native_theme_dark_aura.cc
index a8fbfee3b13672902aac05fd5a65fa8ee81f9f7e..1be6369acf0b7c02a6f862636c2b2de1fbf8cb5a 100644
index a8fbfee3b13672902aac05fd5a65fa8ee81f9f7e..80770f0e46641f0d4ea81c6fa6602a68c1f9b9a8 100644
--- a/ui/native_theme/native_theme_dark_aura.cc
+++ b/ui/native_theme/native_theme_dark_aura.cc
@@ -20,6 +20,8 @@ SkColor NativeThemeDarkAura::GetSystemColor(ColorId color_id,
@@ -20,12 +20,14 @@ SkColor NativeThemeDarkAura::GetSystemColor(ColorId color_id,
}
bool NativeThemeDarkAura::ShouldUseDarkColors() const {
@@ -74,6 +90,13 @@ index a8fbfee3b13672902aac05fd5a65fa8ee81f9f7e..1be6369acf0b7c02a6f862636c2b2de1
return true;
}
NativeTheme::PreferredColorScheme NativeThemeDarkAura::GetPreferredColorScheme()
const {
- return NativeTheme::PreferredColorScheme::kDark;
+ return ShouldUseDarkColors() ? NativeTheme::PreferredColorScheme::kDark : NativeTheme::PreferredColorScheme::kLight;
}
NativeThemeDarkAura::NativeThemeDarkAura() : NativeThemeAura(false) {}
diff --git a/ui/native_theme/native_theme_win.cc b/ui/native_theme/native_theme_win.cc
index cff7681a4e0023a67edda37bf9865ab073b32549..83507081e0734b53fd37133014256243dda6864d 100644
--- a/ui/native_theme/native_theme_win.cc

View File

@@ -4,12 +4,11 @@ Date: Sun, 1 Mar 2020 16:33:55 -0800
Subject: feat: allow embedders to add observers on created hunspell
dictionaries
diff --git a/chrome/browser/spellchecker/spellcheck_service.cc b/chrome/browser/spellchecker/spellcheck_service.cc
index 0dc509bafcfab2637aab4ea55769cd06ad3492c9..3b1f02e354c5c5a85e9193859ca8e7497f02cf86 100644
index 6a508168067b70822fabee5d50a5be7ac2ed15a5..5afbef4fb24441a850c45703b2d7a66b8f92abb1 100644
--- a/chrome/browser/spellchecker/spellcheck_service.cc
+++ b/chrome/browser/spellchecker/spellcheck_service.cc
@@ -284,6 +284,9 @@ void SpellcheckService::LoadHunspellDictionaries() {
@@ -266,6 +266,9 @@ void SpellcheckService::LoadHunspellDictionaries() {
std::make_unique<SpellcheckHunspellDictionary>(dictionary, context_,
this));
hunspell_dictionaries_.back()->AddObserver(this);
@@ -19,7 +18,7 @@ index 0dc509bafcfab2637aab4ea55769cd06ad3492c9..3b1f02e354c5c5a85e9193859ca8e749
hunspell_dictionaries_.back()->Load();
}
@@ -297,6 +300,20 @@ SpellcheckService::GetHunspellDictionaries() {
@@ -279,6 +282,20 @@ SpellcheckService::GetHunspellDictionaries() {
return hunspell_dictionaries_;
}
@@ -41,10 +40,10 @@ index 0dc509bafcfab2637aab4ea55769cd06ad3492c9..3b1f02e354c5c5a85e9193859ca8e749
std::string locale,
std::string path,
diff --git a/chrome/browser/spellchecker/spellcheck_service.h b/chrome/browser/spellchecker/spellcheck_service.h
index 557a0a2a91821a595181481f92b2a2a06dcb1f50..59e24da4be927303df8c4aac87f50778c1c208b0 100644
index d5af9d5829c362743e64a9f2fefdf58a340c4b9f..8c00b16996192a4b65f4794e0018b50559bbe1c1 100644
--- a/chrome/browser/spellchecker/spellcheck_service.h
+++ b/chrome/browser/spellchecker/spellcheck_service.h
@@ -116,6 +116,8 @@ class SpellcheckService : public KeyedService,
@@ -114,6 +114,8 @@ class SpellcheckService : public KeyedService,
const std::vector<std::unique_ptr<SpellcheckHunspellDictionary>>&
GetHunspellDictionaries();
@@ -53,7 +52,7 @@ index 557a0a2a91821a595181481f92b2a2a06dcb1f50..59e24da4be927303df8c4aac87f50778
// Load a dictionary from a given path. Format specifies how the dictionary
// is stored. Return value is true if successful.
bool LoadExternalDictionary(std::string language,
@@ -213,6 +215,8 @@ class SpellcheckService : public KeyedService,
@@ -195,6 +197,8 @@ class SpellcheckService : public KeyedService,
// A pointer to the BrowserContext which this service refers to.
content::BrowserContext* context_;

View File

@@ -0,0 +1,636 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Andy Dill <andy.dill@gmail.com>
Date: Thu, 30 Jan 2020 09:36:07 -0800
Subject: feat: enable off-screen rendering with viz compositor
This patch adds hooks in the relevant places that allow for off-screen
rendering with the viz compositor by way of a custom HostDisplayClient
and LayeredWindowUpdater.
diff --git a/components/viz/host/host_display_client.cc b/components/viz/host/host_display_client.cc
index 3547ee865c220731a6b4be4c1b32ec899b3dd11f..715bfa4b5db5fc4beb83c26b1eedda82c87a245b 100644
--- a/components/viz/host/host_display_client.cc
+++ b/components/viz/host/host_display_client.cc
@@ -43,9 +43,13 @@ void HostDisplayClient::OnDisplayReceivedCALayerParams(
}
#endif
-#if defined(OS_WIN)
+void HostDisplayClient::IsOffscreen(IsOffscreenCallback callback) {
+ std::move(callback).Run(false);
+}
+
void HostDisplayClient::CreateLayeredWindowUpdater(
mojo::PendingReceiver<mojom::LayeredWindowUpdater> receiver) {
+#if defined(OS_WIN)
if (!NeedsToUseLayerWindow(widget_)) {
DLOG(ERROR) << "HWND shouldn't be using a layered window";
return;
@@ -53,8 +57,12 @@ void HostDisplayClient::CreateLayeredWindowUpdater(
layered_window_updater_ =
std::make_unique<LayeredWindowUpdaterImpl>(widget_, std::move(receiver));
-}
+#else
+ CHECK(false) << "Chromium is calling CreateLayeredWindowUpdater for non-OSR "
+ "windows on POSIX platforms, something is wrong with "
+ "Electron's OSR implementation.";
#endif
+}
#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
void HostDisplayClient::DidCompleteSwapWithNewSize(const gfx::Size& size) {
diff --git a/components/viz/host/host_display_client.h b/components/viz/host/host_display_client.h
index cedf833d23589dc3157168cfc7e6d3bb12939f7a..4437a7875076ef5a99ddcd767036ec37c2d48d44 100644
--- a/components/viz/host/host_display_client.h
+++ b/components/viz/host/host_display_client.h
@@ -31,17 +31,17 @@ class VIZ_HOST_EXPORT HostDisplayClient : public mojom::DisplayClient {
mojo::PendingRemote<mojom::DisplayClient> GetBoundRemote(
scoped_refptr<base::SingleThreadTaskRunner> task_runner);
- private:
+ protected:
// mojom::DisplayClient implementation:
+ void IsOffscreen(IsOffscreenCallback callback) override;
+
#if defined(OS_MACOSX)
void OnDisplayReceivedCALayerParams(
const gfx::CALayerParams& ca_layer_params) override;
#endif
-#if defined(OS_WIN)
void CreateLayeredWindowUpdater(
mojo::PendingReceiver<mojom::LayeredWindowUpdater> receiver) override;
-#endif
#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
void DidCompleteSwapWithNewSize(const gfx::Size& size) override;
diff --git a/components/viz/host/layered_window_updater_impl.cc b/components/viz/host/layered_window_updater_impl.cc
index b04f654fe820f821b18e059cdd40085fc2384c4e..ee22012b01ef92bb3b32b5b1081609a7bdfb0d93 100644
--- a/components/viz/host/layered_window_updater_impl.cc
+++ b/components/viz/host/layered_window_updater_impl.cc
@@ -44,7 +44,9 @@ void LayeredWindowUpdaterImpl::OnAllocatedSharedMemory(
// |region|'s handle will close when it goes out of scope.
}
-void LayeredWindowUpdaterImpl::Draw(DrawCallback draw_callback) {
+void LayeredWindowUpdaterImpl::Draw(
+ const gfx::Rect& damage_rect,
+ DrawCallback draw_callback) {
TRACE_EVENT0("viz", "LayeredWindowUpdaterImpl::Draw");
if (!canvas_) {
diff --git a/components/viz/host/layered_window_updater_impl.h b/components/viz/host/layered_window_updater_impl.h
index 1026b739d283f0fc252fa2af83a6d4cf51bc8553..fe562ab60ce98b8bb0c5080a6428deb319a4dd04 100644
--- a/components/viz/host/layered_window_updater_impl.h
+++ b/components/viz/host/layered_window_updater_impl.h
@@ -35,7 +35,7 @@ class VIZ_HOST_EXPORT LayeredWindowUpdaterImpl
// mojom::LayeredWindowUpdater implementation.
void OnAllocatedSharedMemory(const gfx::Size& pixel_size,
base::UnsafeSharedMemoryRegion region) override;
- void Draw(DrawCallback draw_callback) override;
+ void Draw(const gfx::Rect& damage_rect, DrawCallback draw_callback) override;
private:
const HWND hwnd_;
diff --git a/components/viz/service/BUILD.gn b/components/viz/service/BUILD.gn
index ca67f58b73cc13b1e0895b17d69c9781c567afa1..cddf6d35eaa8fbe36844211dd9798605452d9e9a 100644
--- a/components/viz/service/BUILD.gn
+++ b/components/viz/service/BUILD.gn
@@ -121,6 +121,8 @@ viz_component("service") {
"display_embedder/output_surface_provider_impl.h",
"display_embedder/server_shared_bitmap_manager.cc",
"display_embedder/server_shared_bitmap_manager.h",
+ "display_embedder/software_output_device_proxy.cc",
+ "display_embedder/software_output_device_proxy.h",
"display_embedder/software_output_surface.cc",
"display_embedder/software_output_surface.h",
"display_embedder/viz_process_context_provider.cc",
diff --git a/components/viz/service/display_embedder/output_surface_provider_impl.cc b/components/viz/service/display_embedder/output_surface_provider_impl.cc
index 6f2eac863d1b82ea1739b369861ada2e626627de..1011080626807dd6baf6c08f9b704905cba4e3c8 100644
--- a/components/viz/service/display_embedder/output_surface_provider_impl.cc
+++ b/components/viz/service/display_embedder/output_surface_provider_impl.cc
@@ -20,6 +20,7 @@
#include "components/viz/service/display_embedder/server_shared_bitmap_manager.h"
#include "components/viz/service/display_embedder/skia_output_surface_dependency_impl.h"
#include "components/viz/service/display_embedder/skia_output_surface_impl.h"
+#include "components/viz/service/display_embedder/software_output_device_proxy.h"
#include "components/viz/service/display_embedder/software_output_surface.h"
#include "components/viz/service/display_embedder/viz_process_context_provider.h"
#include "components/viz/service/gl/gpu_service_impl.h"
@@ -33,6 +34,7 @@
#include "gpu/ipc/scheduler_sequence.h"
#include "gpu/ipc/service/gpu_channel_manager_delegate.h"
#include "gpu/ipc/service/image_transport_surface.h"
+#include "services/viz/privileged/mojom/compositing/layered_window_updater.mojom.h"
#include "ui/base/ui_base_switches.h"
#include "ui/gl/gl_context.h"
#include "ui/gl/init/gl_factory.h"
@@ -227,6 +229,22 @@ OutputSurfaceProviderImpl::CreateSoftwareOutputDeviceForPlatform(
if (headless_)
return std::make_unique<SoftwareOutputDevice>();
+#if !defined(OS_MACOSX)
+ {
+ mojo::ScopedAllowSyncCallForTesting allow_sync;
+ DCHECK(display_client);
+ bool offscreen = false;
+ if (display_client->IsOffscreen(&offscreen) && offscreen) {
+ mojom::LayeredWindowUpdaterPtr layered_window_updater;
+ display_client->CreateLayeredWindowUpdater(
+ mojo::MakeRequest(&layered_window_updater));
+
+ return std::make_unique<SoftwareOutputDeviceProxy>(
+ std::move(layered_window_updater));
+ }
+ }
+#endif
+
#if defined(OS_WIN)
return CreateSoftwareOutputDeviceWin(surface_handle, &output_device_backing_,
display_client);
diff --git a/components/viz/service/display_embedder/software_output_device_mac.cc b/components/viz/service/display_embedder/software_output_device_mac.cc
index b9357082293cc55650144ccbc8bada8fe6d1cac4..b4cb07e26d1504719f80e5835c1cb5f138b9f1ab 100644
--- a/components/viz/service/display_embedder/software_output_device_mac.cc
+++ b/components/viz/service/display_embedder/software_output_device_mac.cc
@@ -102,6 +102,8 @@ void SoftwareOutputDeviceMac::UpdateAndCopyBufferDamage(
SkCanvas* SoftwareOutputDeviceMac::BeginPaint(
const gfx::Rect& new_damage_rect) {
+ last_damage = new_damage_rect;
+
// Record the previous paint buffer.
Buffer* previous_paint_buffer =
buffer_queue_.empty() ? nullptr : buffer_queue_.back().get();
@@ -184,6 +186,7 @@ void SoftwareOutputDeviceMac::EndPaint() {
ca_layer_params.is_empty = false;
ca_layer_params.scale_factor = scale_factor_;
ca_layer_params.pixel_size = pixel_size_;
+ ca_layer_params.damage = last_damage;
ca_layer_params.io_surface_mach_port.reset(
IOSurfaceCreateMachPort(current_paint_buffer_->io_surface));
client_->SoftwareDeviceUpdatedCALayerParams(ca_layer_params);
diff --git a/components/viz/service/display_embedder/software_output_device_mac.h b/components/viz/service/display_embedder/software_output_device_mac.h
index f3867356e3d641416e00e6d115ae9ae2a0be90ab..b1d192d2b20ccb63fba07093101d745e5ffe86dd 100644
--- a/components/viz/service/display_embedder/software_output_device_mac.h
+++ b/components/viz/service/display_embedder/software_output_device_mac.h
@@ -56,6 +56,7 @@ class VIZ_SERVICE_EXPORT SoftwareOutputDeviceMac : public SoftwareOutputDevice {
void UpdateAndCopyBufferDamage(Buffer* previous_paint_buffer,
const SkRegion& new_damage_rect);
+ gfx::Rect last_damage;
gfx::Size pixel_size_;
float scale_factor_ = 1;
diff --git a/components/viz/service/display_embedder/software_output_device_proxy.cc b/components/viz/service/display_embedder/software_output_device_proxy.cc
new file mode 100644
index 0000000000000000000000000000000000000000..4efea02f80f8b6818291321a7c63f0f4815a5b98
--- /dev/null
+++ b/components/viz/service/display_embedder/software_output_device_proxy.cc
@@ -0,0 +1,157 @@
+// 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 "components/viz/service/display_embedder/software_output_device_proxy.h"
+
+#include "base/memory/unsafe_shared_memory_region.h"
+#include "base/threading/thread_checker.h"
+#include "base/trace_event/trace_event.h"
+#include "components/viz/common/resources/resource_sizes.h"
+#include "components/viz/service/display_embedder/output_device_backing.h"
+#include "mojo/public/cpp/system/platform_handle.h"
+#include "services/viz/privileged/mojom/compositing/layered_window_updater.mojom.h"
+#include "skia/ext/platform_canvas.h"
+#include "third_party/skia/include/core/SkCanvas.h"
+#include "ui/gfx/skia_util.h"
+
+#if defined(OS_WIN)
+#include "skia/ext/skia_utils_win.h"
+#include "ui/gfx/gdi_util.h"
+#include "ui/gfx/win/hwnd_util.h"
+#else
+#include "mojo/public/cpp/base/shared_memory_utils.h"
+#endif
+
+namespace viz {
+
+SoftwareOutputDeviceBase::~SoftwareOutputDeviceBase() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK(!in_paint_);
+}
+
+void SoftwareOutputDeviceBase::Resize(const gfx::Size& viewport_pixel_size,
+ float scale_factor) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK(!in_paint_);
+
+ if (viewport_pixel_size_ == viewport_pixel_size)
+ return;
+
+ viewport_pixel_size_ = viewport_pixel_size;
+ ResizeDelegated();
+}
+
+SkCanvas* SoftwareOutputDeviceBase::BeginPaint(
+ const gfx::Rect& damage_rect) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK(!in_paint_);
+
+ damage_rect_ = damage_rect;
+ in_paint_ = true;
+ return BeginPaintDelegated();
+}
+
+void SoftwareOutputDeviceBase::EndPaint() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK(in_paint_);
+
+ in_paint_ = false;
+
+ gfx::Rect intersected_damage_rect = damage_rect_;
+ intersected_damage_rect.Intersect(gfx::Rect(viewport_pixel_size_));
+ if (intersected_damage_rect.IsEmpty())
+ return;
+
+ EndPaintDelegated(intersected_damage_rect);
+}
+
+SoftwareOutputDeviceProxy::~SoftwareOutputDeviceProxy() = default;
+
+SoftwareOutputDeviceProxy::SoftwareOutputDeviceProxy(
+ mojom::LayeredWindowUpdaterPtr layered_window_updater)
+ : layered_window_updater_(std::move(layered_window_updater)) {
+ DCHECK(layered_window_updater_.is_bound());
+}
+
+void SoftwareOutputDeviceProxy::OnSwapBuffers(
+ SoftwareOutputDevice::SwapBuffersCallback swap_ack_callback) {
+ DCHECK(swap_ack_callback_.is_null());
+
+ // We aren't waiting on DrawAck() and can immediately run the callback.
+ if (!waiting_on_draw_ack_) {
+ task_runner_->PostTask(FROM_HERE,
+ base::BindOnce(std::move(swap_ack_callback), viewport_pixel_size_));
+ return;
+ }
+
+ swap_ack_callback_ = std::move(swap_ack_callback);
+}
+
+void SoftwareOutputDeviceProxy::ResizeDelegated() {
+ canvas_.reset();
+
+ size_t required_bytes;
+ if (!ResourceSizes::MaybeSizeInBytes(
+ viewport_pixel_size_, ResourceFormat::RGBA_8888, &required_bytes)) {
+ DLOG(ERROR) << "Invalid viewport size " << viewport_pixel_size_.ToString();
+ return;
+ }
+
+ base::UnsafeSharedMemoryRegion region =
+ base::UnsafeSharedMemoryRegion::Create(required_bytes);
+ if (!region.IsValid()) {
+ DLOG(ERROR) << "Failed to allocate " << required_bytes << " bytes";
+ return;
+ }
+
+ #if defined(WIN32)
+ canvas_ = skia::CreatePlatformCanvasWithSharedSection(
+ viewport_pixel_size_.width(), viewport_pixel_size_.height(), false,
+ region.GetPlatformHandle(), skia::CRASH_ON_FAILURE);
+ #else
+ shm_mapping_ = region.Map();
+ if (!shm_mapping_.IsValid()) {
+ DLOG(ERROR) << "Failed to map " << required_bytes << " bytes";
+ return;
+ }
+
+ canvas_ = skia::CreatePlatformCanvasWithPixels(
+ viewport_pixel_size_.width(), viewport_pixel_size_.height(), false,
+ static_cast<uint8_t*>(shm_mapping_.memory()), skia::CRASH_ON_FAILURE);
+ #endif
+
+ // Transfer region ownership to the browser process.
+ layered_window_updater_->OnAllocatedSharedMemory(viewport_pixel_size_,
+ std::move(region));
+}
+
+SkCanvas* SoftwareOutputDeviceProxy::BeginPaintDelegated() {
+ return canvas_.get();
+}
+
+void SoftwareOutputDeviceProxy::EndPaintDelegated(
+ const gfx::Rect& damage_rect) {
+ DCHECK(!waiting_on_draw_ack_);
+
+ if (!canvas_)
+ return;
+
+ layered_window_updater_->Draw(damage_rect, base::BindOnce(
+ &SoftwareOutputDeviceProxy::DrawAck, base::Unretained(this)));
+ waiting_on_draw_ack_ = true;
+
+ TRACE_EVENT_ASYNC_BEGIN0("viz", "SoftwareOutputDeviceProxy::Draw", this);
+}
+
+void SoftwareOutputDeviceProxy::DrawAck() {
+ DCHECK(waiting_on_draw_ack_);
+ DCHECK(!swap_ack_callback_.is_null());
+
+ TRACE_EVENT_ASYNC_END0("viz", "SoftwareOutputDeviceProxy::Draw", this);
+
+ waiting_on_draw_ack_ = false;
+ std::move(swap_ack_callback_).Run(viewport_pixel_size_);
+}
+
+} // namespace viz
diff --git a/components/viz/service/display_embedder/software_output_device_proxy.h b/components/viz/service/display_embedder/software_output_device_proxy.h
new file mode 100644
index 0000000000000000000000000000000000000000..48fa86caaab3c15764f105eb7ad2aecf2b89bf36
--- /dev/null
+++ b/components/viz/service/display_embedder/software_output_device_proxy.h
@@ -0,0 +1,90 @@
+// 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 COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_SOFTWARE_OUTPUT_DEVICE_PROXY_H_
+#define COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_SOFTWARE_OUTPUT_DEVICE_PROXY_H_
+
+#if defined(OS_WIN)
+#include <windows.h>
+#endif
+
+#include <memory>
+
+#include "base/memory/shared_memory_mapping.h"
+#include "base/threading/thread_checker.h"
+#include "components/viz/host/host_display_client.h"
+#include "components/viz/service/display/software_output_device.h"
+#include "components/viz/service/viz_service_export.h"
+#include "services/viz/privileged/mojom/compositing/display_private.mojom.h"
+#include "services/viz/privileged/mojom/compositing/layered_window_updater.mojom.h"
+
+namespace viz {
+
+// Shared base class for SoftwareOutputDevice implementations.
+class SoftwareOutputDeviceBase : public SoftwareOutputDevice {
+ public:
+ SoftwareOutputDeviceBase() = default;
+ ~SoftwareOutputDeviceBase() override;
+
+ // SoftwareOutputDevice implementation.
+ void Resize(const gfx::Size& viewport_pixel_size,
+ float scale_factor) override;
+ SkCanvas* BeginPaint(const gfx::Rect& damage_rect) override;
+ void EndPaint() override;
+
+ // Called from Resize() if |viewport_pixel_size_| has changed.
+ virtual void ResizeDelegated() = 0;
+
+ // Called from BeginPaint() and should return an SkCanvas.
+ virtual SkCanvas* BeginPaintDelegated() = 0;
+
+ // Called from EndPaint() if there is damage.
+ virtual void EndPaintDelegated(const gfx::Rect& damage_rect) = 0;
+
+ private:
+ bool in_paint_ = false;
+
+ THREAD_CHECKER(thread_checker_);
+
+ DISALLOW_COPY_AND_ASSIGN(SoftwareOutputDeviceBase);
+};
+
+// SoftwareOutputDevice implementation that draws indirectly. An implementation
+// of mojom::LayeredWindowUpdater in the browser process handles the actual
+// drawing. Pixel backing is in SharedMemory so no copying between processes
+// is required.
+class SoftwareOutputDeviceProxy : public SoftwareOutputDeviceBase {
+ public:
+ explicit SoftwareOutputDeviceProxy(
+ mojom::LayeredWindowUpdaterPtr layered_window_updater);
+ ~SoftwareOutputDeviceProxy() override;
+
+ // SoftwareOutputDevice implementation.
+ void OnSwapBuffers(SoftwareOutputDevice::SwapBuffersCallback swap_ack_callback) override;
+
+ // SoftwareOutputDeviceBase implementation.
+ void ResizeDelegated() override;
+ SkCanvas* BeginPaintDelegated() override;
+ void EndPaintDelegated(const gfx::Rect& rect) override;
+
+ private:
+ // Runs |swap_ack_callback_| after draw has happened.
+ void DrawAck();
+
+ mojom::LayeredWindowUpdaterPtr layered_window_updater_;
+
+ std::unique_ptr<SkCanvas> canvas_;
+ bool waiting_on_draw_ack_ = false;
+ SoftwareOutputDevice::SwapBuffersCallback swap_ack_callback_;
+
+#if !defined(WIN32)
+ base::WritableSharedMemoryMapping shm_mapping_;
+#endif
+
+ DISALLOW_COPY_AND_ASSIGN(SoftwareOutputDeviceProxy);
+};
+
+} // namespace viz
+
+#endif // COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_SOFTWARE_OUTPUT_DEVICE_PROXY_H_
diff --git a/components/viz/service/display_embedder/software_output_device_win.cc b/components/viz/service/display_embedder/software_output_device_win.cc
index bb07c338fac5251d62f52083b0cdf29f913c0426..e0ebb98d9a020dec059b9eae65d0e39c62b8dc57 100644
--- a/components/viz/service/display_embedder/software_output_device_win.cc
+++ b/components/viz/service/display_embedder/software_output_device_win.cc
@@ -268,7 +268,7 @@ void SoftwareOutputDeviceWinProxy::EndPaintDelegated(
if (!canvas_)
return;
- layered_window_updater_->Draw(base::BindOnce(
+ layered_window_updater_->Draw(damage_rect, base::BindOnce(
&SoftwareOutputDeviceWinProxy::DrawAck, base::Unretained(this)));
waiting_on_draw_ack_ = true;
diff --git a/mojo/public/cpp/bindings/sync_call_restrictions.h b/mojo/public/cpp/bindings/sync_call_restrictions.h
index ac94eab98fd0f89de12db387c4718f2351ff4a92..b89d52a0c869c22147eb78f623a435920a6d34ec 100644
--- a/mojo/public/cpp/bindings/sync_call_restrictions.h
+++ b/mojo/public/cpp/bindings/sync_call_restrictions.h
@@ -29,6 +29,7 @@ class HostContextFactoryPrivate;
namespace viz {
class HostFrameSinkManager;
+class GpuDisplayProvider;
}
namespace mojo {
@@ -82,6 +83,8 @@ class COMPONENT_EXPORT(MOJO_CPP_BINDINGS) SyncCallRestrictions {
// For preventing frame swaps of wrong size during resize on Windows.
// (https://crbug.com/811945)
friend class ui::HostContextFactoryPrivate;
+ // For query of whether to use SoftwareOutputDevice or not
+ friend class viz::GpuDisplayProvider;
// END ALLOWED USAGE.
#if ENABLE_SYNC_CALL_RESTRICTIONS
diff --git a/services/viz/privileged/mojom/compositing/display_private.mojom b/services/viz/privileged/mojom/compositing/display_private.mojom
index be56099d186fce2ea867d83bcae642dafc5cf400..0c6c0d20edf8dad26d9737ca1120e9a66ea27e92 100644
--- a/services/viz/privileged/mojom/compositing/display_private.mojom
+++ b/services/viz/privileged/mojom/compositing/display_private.mojom
@@ -76,12 +76,14 @@ interface DisplayPrivate {
};
interface DisplayClient {
+ [Sync]
+ IsOffscreen() => (bool success);
+
[EnableIf=is_mac]
OnDisplayReceivedCALayerParams(gfx.mojom.CALayerParams ca_layer_params);
// Creates a LayeredWindowUpdater implementation to draw into a layered
// window.
- [EnableIf=is_win]
CreateLayeredWindowUpdater(pending_receiver<LayeredWindowUpdater> receiver);
// Notifies that a swap has occurred and provides information about the pixel
diff --git a/services/viz/privileged/mojom/compositing/layered_window_updater.mojom b/services/viz/privileged/mojom/compositing/layered_window_updater.mojom
index 6b7fbb6cf13dc8ee6ade0878a9a2c1efc5d4d3f1..e2af75168cb914a7b3b4a6c9b6a285498c3f8e72 100644
--- a/services/viz/privileged/mojom/compositing/layered_window_updater.mojom
+++ b/services/viz/privileged/mojom/compositing/layered_window_updater.mojom
@@ -26,5 +26,5 @@ interface LayeredWindowUpdater {
// Draws to the HWND by copying pixels from shared memory. Callback must be
// called after draw operation is complete to signal shared memory can be
// modified.
- Draw() => ();
+ Draw(gfx.mojom.Rect damage_rect) => ();
};
diff --git a/ui/compositor/compositor.h b/ui/compositor/compositor.h
index 5410ee7a65abc9888d9061e37daf2928a909a272..3faeea7bc605dd5ee71b1ad463255b078d9d18a6 100644
--- a/ui/compositor/compositor.h
+++ b/ui/compositor/compositor.h
@@ -66,6 +66,7 @@ class GpuMemoryBufferManager;
namespace viz {
class ContextProvider;
+class HostDisplayClient;
class HostFrameSinkManager;
class LocalSurfaceIdAllocation;
class RasterContextProvider;
@@ -197,6 +198,15 @@ class COMPOSITOR_EXPORT ContextFactory {
virtual bool SyncTokensRequiredForDisplayCompositor() = 0;
};
+class COMPOSITOR_EXPORT CompositorDelegate {
+ public:
+ virtual std::unique_ptr<viz::HostDisplayClient> CreateHostDisplayClient(
+ ui::Compositor* compositor) = 0;
+
+ protected:
+ virtual ~CompositorDelegate() {}
+};
+
// Compositor object to take care of GPU painting.
// A Browser compositor object is responsible for generating the final
// displayable form of pixels comprising a single widget's contents. It draws an
@@ -236,6 +246,9 @@ class COMPOSITOR_EXPORT Compositor : public cc::LayerTreeHostClient,
// Schedules a redraw of the layer tree associated with this compositor.
void ScheduleDraw();
+ CompositorDelegate* delegate() const { return delegate_; }
+ void SetDelegate(CompositorDelegate* delegate) { delegate_ = delegate; }
+
// Sets the root of the layer tree drawn by this Compositor. The root layer
// must have no parent. The compositor's root layer is reset if the root layer
// is destroyed. NULL can be passed to reset the root layer, in which case the
@@ -459,6 +472,8 @@ class COMPOSITOR_EXPORT Compositor : public cc::LayerTreeHostClient,
ui::ContextFactory* context_factory_;
ui::ContextFactoryPrivate* context_factory_private_;
+ CompositorDelegate* delegate_ = nullptr;
+
// The root of the Layer tree drawn by this compositor.
Layer* root_layer_ = nullptr;
diff --git a/ui/compositor/host/host_context_factory_private.cc b/ui/compositor/host/host_context_factory_private.cc
index d8c278b99d09e663bba21da0e94b00ea77665349..6c2cd4e3e94df594b0aa2b91484dafea3a01fe65 100644
--- a/ui/compositor/host/host_context_factory_private.cc
+++ b/ui/compositor/host/host_context_factory_private.cc
@@ -113,8 +113,13 @@ void HostContextFactoryPrivate::ConfigureCompositor(
compositor_data.display_private.reset();
root_params->display_private =
compositor_data.display_private.BindNewEndpointAndPassReceiver();
- compositor_data.display_client =
- std::make_unique<HostDisplayClient>(compositor);
+ if (compositor->delegate()) {
+ compositor_data.display_client = compositor->delegate()->CreateHostDisplayClient(
+ compositor);
+ } else {
+ compositor_data.display_client =
+ std::make_unique<HostDisplayClient>(compositor);
+ }
root_params->display_client =
compositor_data.display_client->GetBoundRemote(resize_task_runner_);
diff --git a/ui/gfx/ca_layer_params.h b/ui/gfx/ca_layer_params.h
index 4014e64a75da88cf66c02e8adb71171c2666cab7..25e57784e1a1ffc546b003daa4cd0059c468432f 100644
--- a/ui/gfx/ca_layer_params.h
+++ b/ui/gfx/ca_layer_params.h
@@ -6,6 +6,7 @@
#define UI_GFX_CA_LAYER_PARAMS_H_
#include "build/build_config.h"
+#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/gfx_export.h"
@@ -41,6 +42,8 @@ struct GFX_EXPORT CALayerParams {
gfx::ScopedRefCountedIOSurfaceMachPort io_surface_mach_port;
#endif
+ gfx::Rect damage;
+
// The geometry of the frame.
gfx::Size pixel_size;
float scale_factor = 1.f;
diff --git a/ui/gfx/mojom/ca_layer_params.mojom b/ui/gfx/mojom/ca_layer_params.mojom
index a73b2e678ffe0a682d0aa5409724fb441768bec5..6c36626d204c77ef51278b9e8f6fc6ee24a7a9ab 100644
--- a/ui/gfx/mojom/ca_layer_params.mojom
+++ b/ui/gfx/mojom/ca_layer_params.mojom
@@ -18,5 +18,6 @@ struct CALayerParams {
bool is_empty;
CALayerContent content;
gfx.mojom.Size pixel_size;
+ gfx.mojom.Rect damage;
float scale_factor;
};
diff --git a/ui/gfx/mojom/ca_layer_params_mojom_traits.cc b/ui/gfx/mojom/ca_layer_params_mojom_traits.cc
index 843d5c24ec33de07c12d4417eb111f91dbcd42fe..0ea594950fcd2686f1b07248dbc8ceb257d89dca 100644
--- a/ui/gfx/mojom/ca_layer_params_mojom_traits.cc
+++ b/ui/gfx/mojom/ca_layer_params_mojom_traits.cc
@@ -52,6 +52,9 @@ bool StructTraits<gfx::mojom::CALayerParamsDataView, gfx::CALayerParams>::Read(
if (!data.ReadPixelSize(&out->pixel_size))
return false;
+ if (!data.ReadDamage(&out->damage))
+ return false;
+
out->scale_factor = data.scale_factor();
return true;
}
diff --git a/ui/gfx/mojom/ca_layer_params_mojom_traits.h b/ui/gfx/mojom/ca_layer_params_mojom_traits.h
index 4cac766eae3161baedac4202f694129cd90c80de..0821495ad22944d8856bb750cac8912a2f8328c3 100644
--- a/ui/gfx/mojom/ca_layer_params_mojom_traits.h
+++ b/ui/gfx/mojom/ca_layer_params_mojom_traits.h
@@ -20,6 +20,10 @@ struct StructTraits<gfx::mojom::CALayerParamsDataView, gfx::CALayerParams> {
return ca_layer_params.pixel_size;
}
+ static gfx::Rect damage(const gfx::CALayerParams& ca_layer_params) {
+ return ca_layer_params.damage;
+ }
+
static float scale_factor(const gfx::CALayerParams& ca_layer_params) {
return ca_layer_params.scale_factor;
}

View File

@@ -0,0 +1,28 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: deepak1556 <hop2deep@gmail.com>
Date: Mon, 1 Jun 2020 20:36:16 +0000
Subject: fix: default to NTLM v2 in network service for POSIX platforms
NTLM always defaults to NTLM v2 at the //net layer for quite
sometime now https://crbug.com/22532.
Change-Id: I4ea2dedc10c63a7c4e00101c0acc6d8a713c5054
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2222116
Auto-Submit: Deepak Mohan <hop2deep@gmail.com>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Cr-Commit-Position: refs/heads/master@{#773809}
diff --git a/services/network/public/mojom/network_service.mojom b/services/network/public/mojom/network_service.mojom
index 1cafd4440108ccb8fe7f4f7c3d43a661dd626f15..8fdb75f76f5d9f207265c316e03818f36bcafbaa 100644
--- a/services/network/public/mojom/network_service.mojom
+++ b/services/network/public/mojom/network_service.mojom
@@ -113,7 +113,7 @@ struct HttpAuthDynamicParams {
bool enable_negotiate_port = true;
// Whether NTLM V2 is enabled on POSIX platforms. No effect elsewhere.
- bool ntlm_v2_enabled = false;
+ bool ntlm_v2_enabled = true;
// The AccountManager AccountManagerget.AccountsByTypeAndFeatures on Android
// when using Negotiate authentication.

View File

@@ -0,0 +1,28 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Cheng Zhao <zcbenz@gmail.com>
Date: Thu, 4 Oct 2018 14:57:02 -0700
Subject: fix: handle non client pointer events from pen on Windows 10
Refs: https://github.com/electron/electron/issues/21440
Refs: https://chromium-review.googlesource.com/c/chromium/src/+/2237535
diff --git a/ui/views/win/hwnd_message_handler.cc b/ui/views/win/hwnd_message_handler.cc
index 1fd8da727592fec91056021ea9616996a8f54b92..8c069f0ca4d3a0702a254f766c93d4c6830a911d 100644
--- a/ui/views/win/hwnd_message_handler.cc
+++ b/ui/views/win/hwnd_message_handler.cc
@@ -2005,6 +2005,15 @@ LRESULT HWNDMessageHandler::OnPointerEvent(UINT message,
return -1;
}
+ // Pen may also send non client pointer messages, treat them as normal
+ // touch events so they can be properly handled.
+ if (pointer_type == PT_PEN &&
+ (message == WM_NCPOINTERDOWN ||
+ message == WM_NCPOINTERUP ||
+ message == WM_NCPOINTERUPDATE)) {
+ pointer_type = PT_TOUCH;
+ }
+
switch (pointer_type) {
case PT_PEN:
return HandlePointerEventTypePen(message, w_param, l_param);

View File

@@ -0,0 +1,148 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Cheng Zhao <zcbenz@gmail.com>
Date: Thu, 4 Oct 2018 14:57:02 -0700
Subject: Make sure hunspell file is not destroyed in UI thread
Submitted to Chromium at:
https://chromium-review.googlesource.com/c/chromium/src/+/2206199/1
diff --git a/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.cc b/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.cc
index 67ec4e285d9bf6b9de300845b2c53bda435e5784..74d403aeb1739d0424874a702e64cfd8c3fe4fcb 100644
--- a/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.cc
+++ b/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.cc
@@ -91,21 +91,28 @@ bool SaveDictionaryData(std::unique_ptr<std::string> data,
} // namespace
-SpellcheckHunspellDictionary::DictionaryFile::DictionaryFile() {
-}
+SpellcheckHunspellDictionary::DictionaryFile::DictionaryFile(
+ base::TaskRunner* task_runner) : task_runner_(task_runner) {}
SpellcheckHunspellDictionary::DictionaryFile::~DictionaryFile() {
+ if (file.IsValid()) {
+ task_runner_->PostTask(FROM_HERE,
+ base::BindOnce(&CloseDictionary, std::move(file)));
+ }
}
SpellcheckHunspellDictionary::DictionaryFile::DictionaryFile(
DictionaryFile&& other)
- : path(other.path), file(std::move(other.file)) {}
+ : path(other.path),
+ file(std::move(other.file)),
+ task_runner_(std::move(other.task_runner_)) {}
SpellcheckHunspellDictionary::DictionaryFile&
SpellcheckHunspellDictionary::DictionaryFile::operator=(
DictionaryFile&& other) {
path = other.path;
file = std::move(other.file);
+ task_runner_ = std::move(other.task_runner_);
return *this;
}
@@ -121,16 +128,10 @@ SpellcheckHunspellDictionary::SpellcheckHunspellDictionary(
#if !defined(OS_ANDROID)
spellcheck_service_(spellcheck_service),
#endif
- download_status_(DOWNLOAD_NONE) {
-}
+ download_status_(DOWNLOAD_NONE),
+ dictionary_file_(task_runner_.get()) {}
SpellcheckHunspellDictionary::~SpellcheckHunspellDictionary() {
- if (dictionary_file_.file.IsValid()) {
- task_runner_->PostTask(
- FROM_HERE,
- base::BindOnce(&CloseDictionary, std::move(dictionary_file_.file)));
- }
-
#if BUILDFLAG(USE_BROWSER_SPELLCHECKER)
// Disable the language from platform spellchecker.
if (spellcheck::UseBrowserSpellChecker())
@@ -324,7 +325,8 @@ void SpellcheckHunspellDictionary::DownloadDictionary(GURL url) {
#if !defined(OS_ANDROID)
// static
SpellcheckHunspellDictionary::DictionaryFile
-SpellcheckHunspellDictionary::OpenDictionaryFile(const base::FilePath& path) {
+SpellcheckHunspellDictionary::OpenDictionaryFile(base::TaskRunner* task_runner,
+ const base::FilePath& path) {
base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
base::BlockingType::MAY_BLOCK);
@@ -335,7 +337,7 @@ SpellcheckHunspellDictionary::OpenDictionaryFile(const base::FilePath& path) {
// For systemwide installations on Windows, the default directory may not
// have permissions for download. In that case, the alternate directory for
// download is chrome::DIR_USER_DATA.
- DictionaryFile dictionary;
+ DictionaryFile dictionary(task_runner);
#if defined(OS_WIN)
// Check if the dictionary exists in the fallback location. If so, use it
@@ -377,7 +379,7 @@ SpellcheckHunspellDictionary::OpenDictionaryFile(const base::FilePath& path) {
// static
SpellcheckHunspellDictionary::DictionaryFile
SpellcheckHunspellDictionary::InitializeDictionaryLocation(
- const std::string& language) {
+ base::TaskRunner* task_runner, const std::string& language) {
base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
base::BlockingType::MAY_BLOCK);
@@ -392,7 +394,7 @@ SpellcheckHunspellDictionary::InitializeDictionaryLocation(
base::FilePath dict_path =
spellcheck::GetVersionedFileName(language, dict_dir);
- return OpenDictionaryFile(dict_path);
+ return OpenDictionaryFile(task_runner, dict_path);
}
void SpellcheckHunspellDictionary::InitializeDictionaryLocationComplete(
@@ -480,7 +482,8 @@ void SpellcheckHunspellDictionary::PlatformSupportsLanguageComplete(
#if !defined(OS_ANDROID) && BUILDFLAG(USE_RENDERER_SPELLCHECKER)
base::PostTaskAndReplyWithResult(
task_runner_.get(), FROM_HERE,
- base::BindOnce(&InitializeDictionaryLocation, language_),
+ base::BindOnce(&InitializeDictionaryLocation,
+ base::RetainedRef(task_runner_.get()), language_),
base::BindOnce(
&SpellcheckHunspellDictionary::InitializeDictionaryLocationComplete,
weak_ptr_factory_.GetWeakPtr()));
diff --git a/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.h b/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.h
index 633ec3a96b39824fc9bcf374e59eb80148a2ae27..bfb90905ee045d8f08dbd0b348204b41fd185f41 100644
--- a/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.h
+++ b/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.h
@@ -99,7 +99,7 @@ class SpellcheckHunspellDictionary
// blocking sequence.
struct DictionaryFile {
public:
- DictionaryFile();
+ explicit DictionaryFile(base::TaskRunner* task_runner);
~DictionaryFile();
DictionaryFile(DictionaryFile&& other);
@@ -112,6 +112,9 @@ class SpellcheckHunspellDictionary
base::File file;
private:
+ // Task runner where the file is created.
+ scoped_refptr<base::TaskRunner> task_runner_;
+
DISALLOW_COPY_AND_ASSIGN(DictionaryFile);
};
@@ -126,11 +129,12 @@ class SpellcheckHunspellDictionary
#if !defined(OS_ANDROID)
// Figures out the location for the dictionary, verifies its contents, and
// opens it.
- static DictionaryFile OpenDictionaryFile(const base::FilePath& path);
+ static DictionaryFile OpenDictionaryFile(base::TaskRunner* task_runner,
+ const base::FilePath& path);
// Gets the default location for the dictionary file.
static DictionaryFile InitializeDictionaryLocation(
- const std::string& language);
+ base::TaskRunner* task_runner, const std::string& language);
// The reply point for PostTaskAndReplyWithResult, called after the dictionary
// file has been initialized.

View File

@@ -0,0 +1,79 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Attard <samuel.r.attard@gmail.com>
Date: Wed, 20 May 2020 13:48:51 -0700
Subject: fix: swap global proxies before initializing the windows proxies
Electron's Context Isolation implementation has a side-effect of initializing
the isolated worlds WindowProxy during the initialization of the main world
WindowProxy as a result of creating the isolated world inside the DidCreateScriptContext
hook. This results in an assertion failing in Chromium during a frame
swap where it expects to be able to set a new global_proxy in the WindowProxy
of the isolated world BEFORE it is initialized.
To meet this assumption this patch splits SetGlobalProxy into two calls,
SetGlobalProxyWithoutInitializing and InitializeIfNeeded which has the same
resultant effect but means that all of the global_proxy objects are set
BEFORE any WindowProxy's are initialized.
This could probably be upstreamed as it doesn't affect the way Chromium works
but also it has no benefit for them at this time.
diff --git a/third_party/blink/renderer/bindings/core/v8/window_proxy.cc b/third_party/blink/renderer/bindings/core/v8/window_proxy.cc
index 86076cb3f39cdca7dbf31c668b8aaafb44e42d39..e7108f9548e0f01863339b12f6bd5e51b951b3fc 100644
--- a/third_party/blink/renderer/bindings/core/v8/window_proxy.cc
+++ b/third_party/blink/renderer/bindings/core/v8/window_proxy.cc
@@ -109,10 +109,7 @@ v8::Local<v8::Object> WindowProxy::ReleaseGlobalProxy() {
}
void WindowProxy::SetGlobalProxy(v8::Local<v8::Object> global_proxy) {
- DCHECK_EQ(lifecycle_, Lifecycle::kContextIsUninitialized);
-
- CHECK(global_proxy_.IsEmpty());
- global_proxy_.Set(isolate_, global_proxy);
+ SetGlobalProxyWithoutInitializing(global_proxy);
// Initialize the window proxy now, to re-establish the connection between
// the global object and the v8::Context. This is really only needed for a
@@ -123,6 +120,13 @@ void WindowProxy::SetGlobalProxy(v8::Local<v8::Object> global_proxy) {
Initialize();
}
+void WindowProxy::SetGlobalProxyWithoutInitializing(v8::Local<v8::Object> global_proxy) {
+ DCHECK_EQ(lifecycle_, Lifecycle::kContextIsUninitialized);
+
+ CHECK(global_proxy_.IsEmpty());
+ global_proxy_.Set(isolate_, global_proxy);
+}
+
// Create a new environment and setup the global object.
//
// The global object corresponds to a DOMWindow instance. However, to
diff --git a/third_party/blink/renderer/bindings/core/v8/window_proxy.h b/third_party/blink/renderer/bindings/core/v8/window_proxy.h
index 777bb67e5f7a1eb42438f91023a53c82fd041af2..3735f9b49899b4d36f005a3c2b741e3791ba0709 100644
--- a/third_party/blink/renderer/bindings/core/v8/window_proxy.h
+++ b/third_party/blink/renderer/bindings/core/v8/window_proxy.h
@@ -157,6 +157,7 @@ class WindowProxy : public GarbageCollected<WindowProxy> {
CORE_EXPORT v8::Local<v8::Object> GlobalProxyIfNotDetached();
v8::Local<v8::Object> ReleaseGlobalProxy();
void SetGlobalProxy(v8::Local<v8::Object>);
+ void SetGlobalProxyWithoutInitializing(v8::Local<v8::Object>);
// TODO(dcheng): Temporarily exposed to avoid include cycles. Remove the need
// for this and remove this getter.
diff --git a/third_party/blink/renderer/bindings/core/v8/window_proxy_manager.cc b/third_party/blink/renderer/bindings/core/v8/window_proxy_manager.cc
index b8054889808b39f216bd85b019e2b05660c828de..5306426d84209c428a59fec6b468f57fbddd1fed 100644
--- a/third_party/blink/renderer/bindings/core/v8/window_proxy_manager.cc
+++ b/third_party/blink/renderer/bindings/core/v8/window_proxy_manager.cc
@@ -55,8 +55,11 @@ void WindowProxyManager::ReleaseGlobalProxies(
void WindowProxyManager::SetGlobalProxies(
const GlobalProxyVector& global_proxies) {
+ for (const auto& entry : global_proxies) {
+ WindowProxyMaybeUninitialized(*entry.first)->SetGlobalProxyWithoutInitializing(entry.second);
+ }
for (const auto& entry : global_proxies)
- WindowProxyMaybeUninitialized(*entry.first)->SetGlobalProxy(entry.second);
+ WindowProxyMaybeUninitialized(*entry.first)->InitializeIfNeeded();
}
WindowProxyManager::WindowProxyManager(Frame& frame, FrameType frame_type)

View File

@@ -12,7 +12,7 @@ diff --git a/chrome/browser/extensions/global_shortcut_listener_mac.mm b/chrome/
index befe726af9c10b1563a7fc0bb77cc55f65943d5c..bac51f33f35f96fe4ecc764cf5ca887176642f74 100644
--- a/chrome/browser/extensions/global_shortcut_listener_mac.mm
+++ b/chrome/browser/extensions/global_shortcut_listener_mac.mm
@@ -39,7 +39,7 @@
@@ -39,7 +39,7 @@ GlobalShortcutListenerMac::GlobalShortcutListenerMac()
// global MediaKeysListener to receive media keys.
if (!content::MediaKeysListenerManager::IsMediaKeysListenerManagerEnabled()) {
media_keys_listener_ = ui::MediaKeysListener::Create(

View File

@@ -9,7 +9,7 @@ diff --git a/base/mac/foundation_util.mm b/base/mac/foundation_util.mm
index 2a83d4d8158422c1056725679309c6ced1e531bd..f52934712f8de78193127c426d02982b36e9d422 100644
--- a/base/mac/foundation_util.mm
+++ b/base/mac/foundation_util.mm
@@ -27,7 +27,6 @@
@@ -27,7 +27,6 @@ CFTypeID SecKeyGetTypeID();
#if !defined(OS_IOS)
CFTypeID SecACLGetTypeID();
CFTypeID SecTrustedApplicationGetTypeID();
@@ -17,7 +17,7 @@ index 2a83d4d8158422c1056725679309c6ced1e531bd..f52934712f8de78193127c426d02982b
#endif
} // extern "C"
@@ -316,8 +315,7 @@ void SetBaseBundleID(const char* new_base_bundle_id) {
@@ -316,8 +315,7 @@ NSFont* CFToNSCast(CTFontRef cf_val) {
const_cast<NSFont*>(reinterpret_cast<const NSFont*>(cf_val));
DCHECK(!cf_val ||
CTFontGetTypeID() == CFGetTypeID(cf_val) ||
@@ -27,7 +27,7 @@ index 2a83d4d8158422c1056725679309c6ced1e531bd..f52934712f8de78193127c426d02982b
return ns_val;
}
@@ -385,9 +383,6 @@ CTFontRef NSToCFCast(NSFont* ns_val) {
@@ -385,9 +383,6 @@ CFCast<CTFontRef>(const CFTypeRef& cf_val) {
return (CTFontRef)(cf_val);
}

View File

@@ -18,7 +18,7 @@ index 94afefcee81b87c05bf9b1199d90d3d4b5ea84a6..2ec7f04c71824b47de1ddbf1f0e8625d
extern "C" {
// Kill ring calls. Would be better to use NSKillRing.h, but that's not
@@ -39,38 +40,53 @@
@@ -39,38 +40,53 @@ NSString* _NSYankFromKillRing();
void _NSNewKillRingSequence();
void _NSSetKillRingToYankedState();
}
@@ -92,7 +92,7 @@ index 8f4ae94bc1d8188d041654c50511f3346eee79de..fa06f47abbff3dcda937bf0b794f616e
namespace blink {
@@ -95,10 +97,12 @@ void _NSDrawCarbonThemeListBox(NSRect frame,
@@ -95,10 +97,12 @@ bool ThemePainterMac::PaintTextField(const Node* node,
// behavior change while remaining a fragile solution.
// https://bugs.chromium.org/p/chromium/issues/detail?id=658085#c3
if (!use_ns_text_field_cell) {
@@ -105,7 +105,7 @@ index 8f4ae94bc1d8188d041654c50511f3346eee79de..fa06f47abbff3dcda937bf0b794f616e
return false;
}
@@ -186,10 +190,12 @@ void _NSDrawCarbonThemeListBox(NSRect frame,
@@ -186,10 +190,12 @@ bool ThemePainterMac::PaintTextArea(const Node* node,
const IntRect& r) {
ScopedColorSchemeAppearance appearance(style.UsedColorScheme());
LocalCurrentGraphicsContext local_context(paint_info.context, r);

View File

@@ -18,7 +18,7 @@ index 1ffb647e85e00ff60d84234e47f5d7d385f65245..439cc6df5e0cc1ec3732d6f2a2e00d54
@interface NSWindow (PrivateBrowserNativeWidgetAPI)
+ (Class)frameViewClassForStyleMask:(NSUInteger)windowStyle;
@end
@@ -69,10 +70,13 @@ - (NSRect)_draggableFrame NS_DEPRECATED_MAC(10_10, 10_11) {
@@ -69,10 +70,13 @@
@end
@@ -32,7 +32,7 @@ index 1ffb647e85e00ff60d84234e47f5d7d385f65245..439cc6df5e0cc1ec3732d6f2a2e00d54
+ (Class)frameViewClassForStyleMask:(NSUInteger)windowStyle {
// - NSThemeFrame and its subclasses will be nil if it's missing at runtime.
if ([BrowserWindowFrame class])
@@ -87,6 +91,8 @@ - (BOOL)_usesCustomDrawing {
@@ -87,6 +91,8 @@
return NO;
}
@@ -54,7 +54,7 @@ index 8416c7c6e052dafb2aad61c0bd3224c36e945d23..cd356beda023ab2409b16d58ca38c70b
@interface NSWindow (PrivateAPI)
+ (Class)frameViewClassForStyleMask:(NSUInteger)windowStyle;
@end
@@ -18,8 +20,12 @@ - (CGFloat)_titlebarHeight {
@@ -18,8 +20,12 @@
}
@end
@@ -67,7 +67,7 @@ index 8416c7c6e052dafb2aad61c0bd3224c36e945d23..cd356beda023ab2409b16d58ca38c70b
+ (Class)frameViewClassForStyleMask:(NSUInteger)windowStyle {
if ([NativeWidgetMacFramelessNSWindowFrame class]) {
return [NativeWidgetMacFramelessNSWindowFrame class];
@@ -27,4 +33,6 @@ + (Class)frameViewClassForStyleMask:(NSUInteger)windowStyle {
@@ -27,4 +33,6 @@
return [super frameViewClassForStyleMask:windowStyle];
}
@@ -108,7 +108,7 @@ index 576ef14c1d67ce7f4a1b2095124d1d302440635c..dd068fc339b80c3e99d89e6d7cc73db8
- (BOOL)hasKeyAppearance;
- (long long)_resizeDirectionForMouseLocation:(CGPoint)location;
- (BOOL)_isConsideredOpenForPersistentState;
@@ -57,6 +59,8 @@ - (void)cr_mouseDownOnFrameView:(NSEvent*)event {
@@ -57,6 +59,8 @@
}
@end
@@ -117,7 +117,7 @@ index 576ef14c1d67ce7f4a1b2095124d1d302440635c..dd068fc339b80c3e99d89e6d7cc73db8
@implementation NativeWidgetMacNSWindowTitledFrame
- (void)mouseDown:(NSEvent*)event {
if (self.window.isMovable)
@@ -78,6 +82,8 @@ - (BOOL)usesCustomDrawing {
@@ -78,6 +82,8 @@
}
@end
@@ -126,7 +126,7 @@ index 576ef14c1d67ce7f4a1b2095124d1d302440635c..dd068fc339b80c3e99d89e6d7cc73db8
@implementation NativeWidgetMacNSWindow {
@private
base::scoped_nsobject<CommandDispatcher> commandDispatcher_;
@@ -159,6 +165,8 @@ - (BOOL)hasViewsMenuActive {
@@ -159,6 +165,8 @@
// NSWindow overrides.
@@ -135,7 +135,7 @@ index 576ef14c1d67ce7f4a1b2095124d1d302440635c..dd068fc339b80c3e99d89e6d7cc73db8
+ (Class)frameViewClassForStyleMask:(NSWindowStyleMask)windowStyle {
if (windowStyle & NSWindowStyleMaskTitled) {
if (Class customFrame = [NativeWidgetMacNSWindowTitledFrame class])
@@ -170,6 +178,8 @@ + (Class)frameViewClassForStyleMask:(NSWindowStyleMask)windowStyle {
@@ -170,6 +178,8 @@
return [super frameViewClassForStyleMask:windowStyle];
}

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