mirror of
https://github.com/electron/electron.git
synced 2026-02-19 03:14:51 -05:00
Compare commits
86 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f8c521d795 | ||
|
|
45e14a5ef5 | ||
|
|
f0fa9b5f56 | ||
|
|
d6ef6c368a | ||
|
|
b5de806b42 | ||
|
|
e6859b8ef3 | ||
|
|
4a28bb2010 | ||
|
|
1c6b450f1e | ||
|
|
d76743fd1c | ||
|
|
df6f78950d | ||
|
|
75191f812f | ||
|
|
679c979f40 | ||
|
|
2b5c403e48 | ||
|
|
a3d4c4e84d | ||
|
|
f75bd998fa | ||
|
|
e0fe73521d | ||
|
|
5a4bdde636 | ||
|
|
cbf5a75572 | ||
|
|
7205c97421 | ||
|
|
f9fb8abe59 | ||
|
|
013b38c964 | ||
|
|
b11b40e640 | ||
|
|
079ec9d9c0 | ||
|
|
8608b785db | ||
|
|
e08c317065 | ||
|
|
b9f4112209 | ||
|
|
32d5cc03ef | ||
|
|
a29a04afaf | ||
|
|
f92f97972a | ||
|
|
23d22d7a5b | ||
|
|
a9fe62cc8f | ||
|
|
8391e5226d | ||
|
|
1082e6c764 | ||
|
|
5bf4483f3b | ||
|
|
d4942d0760 | ||
|
|
88074b0ef7 | ||
|
|
a8a200f4c9 | ||
|
|
d58765681c | ||
|
|
def17fe6f9 | ||
|
|
fc1c566613 | ||
|
|
3c57345f82 | ||
|
|
c2e6903a33 | ||
|
|
1587fbd4c3 | ||
|
|
c190c2120e | ||
|
|
26e4da36e4 | ||
|
|
187dc7b8c0 | ||
|
|
48e78496ce | ||
|
|
984e24ee16 | ||
|
|
33055eb1e0 | ||
|
|
4a7b5aa45b | ||
|
|
77451d2cf3 | ||
|
|
e8f90e57d8 | ||
|
|
0b5c5d97bd | ||
|
|
70c0f06890 | ||
|
|
1413e815ec | ||
|
|
c899294a12 | ||
|
|
736f9f21f1 | ||
|
|
2045d85d54 | ||
|
|
fe842f52b6 | ||
|
|
c5f16f36f0 | ||
|
|
7d5d1a1e1b | ||
|
|
476447c6ea | ||
|
|
0e71144a8f | ||
|
|
d62b02af05 | ||
|
|
f998093fad | ||
|
|
b1ffac5969 | ||
|
|
0bb5f136f4 | ||
|
|
0027bd5979 | ||
|
|
41926c1773 | ||
|
|
bce34419b6 | ||
|
|
702645d84b | ||
|
|
facee77287 | ||
|
|
37ca29a27e | ||
|
|
03381c0281 | ||
|
|
71c8dd7028 | ||
|
|
0294075751 | ||
|
|
39bb2a4cbf | ||
|
|
d8ad2afcad | ||
|
|
9ef4825b77 | ||
|
|
6b0479b556 | ||
|
|
891374e794 | ||
|
|
de8623db8a | ||
|
|
ada1e9137b | ||
|
|
b6492686e4 | ||
|
|
0b57386492 | ||
|
|
ad1101e610 |
@@ -240,6 +240,12 @@ step-depot-tools-get: &step-depot-tools-get
|
||||
name: Get depot tools
|
||||
command: |
|
||||
git clone --depth=1 https://chromium.googlesource.com/chromium/tools/depot_tools.git
|
||||
# remove ninjalog_uploader_wrapper.py from autoninja since we don't use it and it causes problems
|
||||
if [ "`uname`" == "Darwin" ]; then
|
||||
sed -i '' '/ninjalog_uploader_wrapper.py/d' ./depot_tools/autoninja
|
||||
else
|
||||
sed -i '/ninjalog_uploader_wrapper.py/d' ./depot_tools/autoninja
|
||||
fi
|
||||
|
||||
step-depot-tools-add-to-path: &step-depot-tools-add-to-path
|
||||
run:
|
||||
@@ -1537,6 +1543,7 @@ jobs:
|
||||
environment:
|
||||
<<: *env-linux-medium
|
||||
<<: *env-testing-build
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
|
||||
<<: *steps-electron-ts-compile-for-doc-change
|
||||
|
||||
# Layer 1: Checkout.
|
||||
|
||||
2
.github/CODEOWNERS
vendored
2
.github/CODEOWNERS
vendored
@@ -4,7 +4,7 @@
|
||||
# https://git-scm.com/docs/gitignore
|
||||
|
||||
# Upgrades WG
|
||||
/patches/ @electron/wg-upgrades
|
||||
/patches/ @electron/wg-upgrades @electron/wg-security
|
||||
DEPS @electron/wg-upgrades
|
||||
|
||||
# Releases WG
|
||||
|
||||
7
BUILD.gn
7
BUILD.gn
@@ -1386,11 +1386,13 @@ dist_zip("electron_dist_zip") {
|
||||
if (is_linux) {
|
||||
data_deps += [ "//sandbox/linux:chrome_sandbox" ]
|
||||
}
|
||||
deps = data_deps
|
||||
outputs = [ "$root_build_dir/dist.zip" ]
|
||||
}
|
||||
|
||||
dist_zip("electron_ffmpeg_zip") {
|
||||
data_deps = [ "//third_party/ffmpeg" ]
|
||||
deps = data_deps
|
||||
outputs = [ "$root_build_dir/ffmpeg.zip" ]
|
||||
}
|
||||
|
||||
@@ -1408,6 +1410,7 @@ group("electron_chromedriver") {
|
||||
dist_zip("electron_chromedriver_zip") {
|
||||
testonly = true
|
||||
data_deps = electron_chromedriver_deps
|
||||
deps = data_deps
|
||||
outputs = [ "$root_build_dir/chromedriver.zip" ]
|
||||
}
|
||||
|
||||
@@ -1426,6 +1429,7 @@ group("electron_mksnapshot") {
|
||||
|
||||
dist_zip("electron_mksnapshot_zip") {
|
||||
data_deps = mksnapshot_deps
|
||||
deps = data_deps
|
||||
outputs = [ "$root_build_dir/mksnapshot.zip" ]
|
||||
}
|
||||
|
||||
@@ -1436,6 +1440,7 @@ copy("hunspell_dictionaries") {
|
||||
|
||||
dist_zip("hunspell_dictionaries_zip") {
|
||||
data_deps = [ ":hunspell_dictionaries" ]
|
||||
deps = data_deps
|
||||
flatten = true
|
||||
|
||||
outputs = [ "$root_build_dir/hunspell_dictionaries.zip" ]
|
||||
@@ -1449,6 +1454,7 @@ copy("libcxx_headers") {
|
||||
|
||||
dist_zip("libcxx_headers_zip") {
|
||||
data_deps = [ ":libcxx_headers" ]
|
||||
deps = data_deps
|
||||
flatten = true
|
||||
flatten_relative_to = rebase_path(
|
||||
"$target_gen_dir/electron_libcxx_include/buildtools/third_party/libc++/trunk",
|
||||
@@ -1464,6 +1470,7 @@ copy("libcxxabi_headers") {
|
||||
|
||||
dist_zip("libcxxabi_headers_zip") {
|
||||
data_deps = [ ":libcxxabi_headers" ]
|
||||
deps = data_deps
|
||||
flatten = true
|
||||
flatten_relative_to = rebase_path(
|
||||
"$target_gen_dir/electron_libcxxabi_include/buildtools/third_party/libc++abi/trunk",
|
||||
|
||||
2
DEPS
2
DEPS
@@ -15,7 +15,7 @@ gclient_gn_args = [
|
||||
|
||||
vars = {
|
||||
'chromium_version':
|
||||
'96.0.4664.110',
|
||||
'96.0.4664.174',
|
||||
'node_version':
|
||||
'v16.9.1',
|
||||
'nan_version':
|
||||
|
||||
@@ -1 +1 @@
|
||||
16.0.7
|
||||
16.1.1
|
||||
@@ -1,9 +1,12 @@
|
||||
from __future__ import with_statement
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import contextlib
|
||||
import sys
|
||||
import os
|
||||
import optparse
|
||||
import json
|
||||
import re
|
||||
import subprocess
|
||||
|
||||
sys.path.append("%s/../../build" % os.path.dirname(os.path.realpath(__file__)))
|
||||
|
||||
@@ -33,36 +36,56 @@ def calculate_hash(root):
|
||||
return CalculateHash('.', None)
|
||||
|
||||
def windows_installed_software():
|
||||
import win32com.client
|
||||
strComputer = "."
|
||||
objWMIService = win32com.client.Dispatch("WbemScripting.SWbemLocator")
|
||||
objSWbemServices = objWMIService.ConnectServer(strComputer, "root\cimv2")
|
||||
colItems = objSWbemServices.ExecQuery("Select * from Win32_Product")
|
||||
items = []
|
||||
powershell_command = [
|
||||
"Get-CimInstance",
|
||||
"-Namespace",
|
||||
"root\cimv2",
|
||||
"-Class",
|
||||
"Win32_product",
|
||||
"|",
|
||||
"Select",
|
||||
"vendor,",
|
||||
"description,",
|
||||
"@{l='install_location';e='InstallLocation'},",
|
||||
"@{l='install_date';e='InstallDate'},",
|
||||
"@{l='install_date_2';e='InstallDate2'},",
|
||||
"caption,",
|
||||
"version,",
|
||||
"name,",
|
||||
"@{l='sku_number';e='SKUNumber'}",
|
||||
"|",
|
||||
"ConvertTo-Json",
|
||||
]
|
||||
|
||||
for objItem in colItems:
|
||||
item = {}
|
||||
if objItem.Caption:
|
||||
item['caption'] = objItem.Caption
|
||||
if objItem.Caption:
|
||||
item['description'] = objItem.Description
|
||||
if objItem.InstallDate:
|
||||
item['install_date'] = objItem.InstallDate
|
||||
if objItem.InstallDate2:
|
||||
item['install_date_2'] = objItem.InstallDate2
|
||||
if objItem.InstallLocation:
|
||||
item['install_location'] = objItem.InstallLocation
|
||||
if objItem.Name:
|
||||
item['name'] = objItem.Name
|
||||
if objItem.SKUNumber:
|
||||
item['sku_number'] = objItem.SKUNumber
|
||||
if objItem.Vendor:
|
||||
item['vendor'] = objItem.Vendor
|
||||
if objItem.Version:
|
||||
item['version'] = objItem.Version
|
||||
items.append(item)
|
||||
proc = subprocess.Popen(
|
||||
["powershell.exe", "-Command", "-"],
|
||||
stdin=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE,
|
||||
)
|
||||
|
||||
return items
|
||||
stdout, _ = proc.communicate(" ".join(powershell_command).encode("utf-8"))
|
||||
|
||||
if proc.returncode != 0:
|
||||
raise RuntimeError("Failed to get list of installed software")
|
||||
|
||||
# On AppVeyor there's other output related to PSReadline,
|
||||
# so grab only the JSON output and ignore everything else
|
||||
json_match = re.match(
|
||||
r".*(\[.*{.*}.*\]).*", stdout.decode("utf-8"), re.DOTALL
|
||||
)
|
||||
|
||||
if not json_match:
|
||||
raise RuntimeError(
|
||||
"Couldn't find JSON output for list of installed software"
|
||||
)
|
||||
|
||||
# Filter out missing keys
|
||||
return list(
|
||||
map(
|
||||
lambda info: {k: info[k] for k in info if info[k]},
|
||||
json.loads(json_match.group(1)),
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def windows_profile():
|
||||
@@ -89,7 +112,7 @@ def windows_profile():
|
||||
|
||||
def main(options):
|
||||
if sys.platform == 'win32':
|
||||
with open(options.output_json, 'wb') as f:
|
||||
with open(options.output_json, 'w') as f:
|
||||
json.dump(windows_profile(), f)
|
||||
else:
|
||||
raise OSError("Unsupported OS")
|
||||
|
||||
@@ -940,9 +940,9 @@ app.setJumpList([
|
||||
])
|
||||
```
|
||||
|
||||
### `app.requestSingleInstanceLock()`
|
||||
### `app.requestSingleInstanceLock([additionalData])`
|
||||
|
||||
* `additionalData` unknown (optional) - A JSON object containing additional data to send to the first instance.
|
||||
* `additionalData` Record<any, any> (optional) - A JSON object containing additional data to send to the first instance.
|
||||
|
||||
Returns `Boolean`
|
||||
|
||||
|
||||
@@ -394,6 +394,7 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
|
||||
* `titleBarOverlay` Object | Boolean (optional) - When using a frameless window in conjuction with `win.setWindowButtonVisibility(true)` on macOS or using a `titleBarStyle` so that the standard window controls ("traffic lights" on macOS) are visible, this property enables the Window Controls Overlay [JavaScript APIs][overlay-javascript-apis] and [CSS Environment Variables][overlay-css-env-vars]. Specifying `true` will result in an overlay with default system colors. Default is `false`.
|
||||
* `color` String (optional) _Windows_ - The CSS color of the Window Controls Overlay when enabled. Default is the system color.
|
||||
* `symbolColor` String (optional) _Windows_ - The CSS color of the symbols on the Window Controls Overlay when enabled. Default is the system color.
|
||||
* `height` Integer (optional) _macOS_ _Windows_ - The height of the title bar and Window Controls Overlay in pixels. Default is system height.
|
||||
|
||||
When setting minimum or maximum window size with `minWidth`/`maxWidth`/
|
||||
`minHeight`/`maxHeight`, it only constrains the users. It won't prevent you from
|
||||
@@ -999,7 +1000,7 @@ APIs like `win.setSize`.
|
||||
is `true`). Default is `#FFF` (white).
|
||||
|
||||
Sets the background color of the window. See [Setting
|
||||
`backgroundColor`](#setting-backgroundcolor).
|
||||
`backgroundColor`](#setting-the-backgroundcolor-property).
|
||||
|
||||
#### `win.previewFile(path[, displayName])` _macOS_
|
||||
|
||||
@@ -1044,7 +1045,7 @@ Returns [`Rectangle`](structures/rectangle.md) - The `bounds` of the window as `
|
||||
#### `win.getBackgroundColor()`
|
||||
|
||||
Returns `String` - Gets the background color of the window. See [Setting
|
||||
`backgroundColor`](#setting-backgroundcolor).
|
||||
`backgroundColor`](#setting-the-backgroundcolor-property).
|
||||
|
||||
#### `win.setContentBounds(bounds[, animate])`
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@ Writes `markup` to the clipboard.
|
||||
```js
|
||||
const { clipboard } = require('electron')
|
||||
|
||||
clipboard.writeHTML('<b>Hi</b')
|
||||
clipboard.writeHTML('<b>Hi</b>')
|
||||
```
|
||||
|
||||
### `clipboard.readImage([type])`
|
||||
|
||||
@@ -102,8 +102,8 @@ has been included below for completeness:
|
||||
| `Boolean` | Simple | ✅ | ✅ | N/A |
|
||||
| `Object` | Complex | ✅ | ✅ | Keys must be supported using only "Simple" types in this table. Values must be supported in this table. Prototype modifications are dropped. Sending custom classes will copy values but not the prototype. |
|
||||
| `Array` | Complex | ✅ | ✅ | Same limitations as the `Object` type |
|
||||
| `Error` | Complex | ✅ | ✅ | Errors that are thrown are also copied, this can result in the message and stack trace of the error changing slightly due to being thrown in a different context |
|
||||
| `Promise` | Complex | ✅ | ✅ | Promises are only proxied if they are the return value or exact parameter. Promises nested in arrays or objects will be dropped. |
|
||||
| `Error` | Complex | ✅ | ✅ | Errors that are thrown are also copied, this can result in the message and stack trace of the error changing slightly due to being thrown in a different context, and any custom properties on the Error object [will be lost](https://github.com/electron/electron/issues/25596) |
|
||||
| `Promise` | Complex | ✅ | ✅ | N/A
|
||||
| `Function` | Complex | ✅ | ✅ | Prototype modifications are dropped. Sending classes or constructors will not work. |
|
||||
| [Cloneable Types](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm) | Simple | ✅ | ✅ | See the linked document on cloneable types |
|
||||
| `Element` | Complex | ✅ | ✅ | Prototype modifications are dropped. Sending custom elements will not work. |
|
||||
|
||||
@@ -122,7 +122,7 @@ Prints Chromium's internal logging to the console.
|
||||
|
||||
Setting this variable is the same as passing `--enable-logging`
|
||||
on the command line. For more info, see `--enable-logging` in [command-line
|
||||
switches](./command-line-switches.md#enable-loggingfile).
|
||||
switches](./command-line-switches.md#--enable-loggingfile).
|
||||
|
||||
### `ELECTRON_LOG_FILE`
|
||||
|
||||
@@ -130,7 +130,7 @@ Sets the file destination for Chromium's internal logging.
|
||||
|
||||
Setting this variable is the same as passing `--log-file`
|
||||
on the command line. For more info, see `--log-file` in [command-line
|
||||
switches](./command-line-switches.md#log-filepath).
|
||||
switches](./command-line-switches.md#--log-filepath).
|
||||
|
||||
### `ELECTRON_DEBUG_DRAG_REGIONS`
|
||||
|
||||
|
||||
@@ -178,7 +178,6 @@ Returns an object with V8 heap statistics. Note that all statistics are reported
|
||||
Returns `Object`:
|
||||
|
||||
* `allocated` Integer - Size of all allocated objects in Kilobytes.
|
||||
* `marked` Integer - Size of all marked objects in Kilobytes.
|
||||
* `total` Integer - Total allocated space in Kilobytes.
|
||||
|
||||
Returns an object with Blink memory information.
|
||||
|
||||
@@ -1840,7 +1840,7 @@ the cursor when dragging.
|
||||
|
||||
#### `contents.savePage(fullPath, saveType)`
|
||||
|
||||
* `fullPath` String - The full file path.
|
||||
* `fullPath` String - The absolute file path.
|
||||
* `saveType` String - Specify the save type.
|
||||
* `HTMLOnly` - Save only the HTML of the page.
|
||||
* `HTMLComplete` - Save complete-html page.
|
||||
|
||||
@@ -85,42 +85,37 @@ $ gclient sync -f
|
||||
|
||||
## Building
|
||||
|
||||
**Set the environment variable for chromium build tools**
|
||||
|
||||
On Linux & MacOS
|
||||
|
||||
```sh
|
||||
$ cd src
|
||||
$ export CHROMIUM_BUILDTOOLS_PATH=`pwd`/buildtools
|
||||
$ gn gen out/Testing --args="import(\"//electron/build/args/testing.gn\") $GN_EXTRA_ARGS"
|
||||
```
|
||||
|
||||
Or on Windows (without the optional argument):
|
||||
On Windows:
|
||||
|
||||
```sh
|
||||
$ cd src
|
||||
$ set CHROMIUM_BUILDTOOLS_PATH=%cd%\buildtools
|
||||
```
|
||||
|
||||
**To generate Testing build config of Electron:**
|
||||
|
||||
```sh
|
||||
$ gn gen out/Testing --args="import(\"//electron/build/args/testing.gn\")"
|
||||
```
|
||||
|
||||
This will generate a build directory `out/Testing` under `src/` with
|
||||
the testing build configuration. You can replace `Testing` with another name,
|
||||
but it should be a subdirectory of `out`.
|
||||
Also you shouldn't have to run `gn gen` again—if you want to change the
|
||||
build arguments, you can run `gn args out/Testing` to bring up an editor.
|
||||
|
||||
To see the list of available build configuration options, run `gn args
|
||||
out/Testing --list`.
|
||||
|
||||
**For generating Testing build config of
|
||||
Electron:**
|
||||
**To generate Release build config of Electron:**
|
||||
|
||||
```sh
|
||||
$ gn gen out/Testing --args="import(\"//electron/build/args/testing.gn\") $GN_EXTRA_ARGS"
|
||||
$ gn gen out/Release --args="import(\"//electron/build/args/release.gn\")"
|
||||
```
|
||||
|
||||
**For generating Release (aka "non-component" or "static") build config of
|
||||
Electron:**
|
||||
**Note:** This will generate a `out/Testing` or `out/Release` build directory under `src/` with the testing or release build depending upon the configuration passed above. You can replace `Testing|Release` with another names, but it should be a subdirectory of `out`.
|
||||
|
||||
```sh
|
||||
$ gn gen out/Release --args="import(\"//electron/build/args/release.gn\") $GN_EXTRA_ARGS"
|
||||
```
|
||||
Also you shouldn't have to run `gn gen` again—if you want to change the build arguments, you can run `gn args out/Testing` to bring up an editor. To see the list of available build configuration options, run `gn args out/Testing --list`.
|
||||
|
||||
**To build, run `ninja` with the `electron` target:**
|
||||
Nota Bene: This will also take a while and probably heat up your lap.
|
||||
@@ -156,13 +151,13 @@ $ ./out/Testing/electron
|
||||
On linux, first strip the debugging and symbol information:
|
||||
|
||||
```sh
|
||||
electron/script/strip-binaries.py -d out/Release
|
||||
$ electron/script/strip-binaries.py -d out/Release
|
||||
```
|
||||
|
||||
To package the electron build as a distributable zip file:
|
||||
|
||||
```sh
|
||||
ninja -C out/Release electron:electron_dist_zip
|
||||
$ ninja -C out/Release electron:electron_dist_zip
|
||||
```
|
||||
|
||||
### Cross-compiling
|
||||
|
||||
@@ -43,8 +43,9 @@ SRV*c:\code\symbols\*https://msdl.microsoft.com/download/symbols;SRV*c:\code\sym
|
||||
|
||||
## Using the symbol server in Visual Studio
|
||||
|
||||

|
||||

|
||||

|
||||
|
||||

|
||||
|
||||
## Troubleshooting: Symbols will not load
|
||||
|
||||
|
||||
BIN
docs/images/vs-options-debugging-symbols.png
Normal file
BIN
docs/images/vs-options-debugging-symbols.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 32 KiB |
BIN
docs/images/vs-tools-options.png
Normal file
BIN
docs/images/vs-tools-options.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
@@ -146,7 +146,7 @@ desktop environment that follows [Desktop Notifications
|
||||
Specification][notification-spec], including Cinnamon, Enlightenment, Unity,
|
||||
GNOME, KDE.
|
||||
|
||||
[notification-spec]: https://developer.gnome.org/notification-spec/
|
||||
[notification-spec]: https://developer-old.gnome.org/notification-spec/
|
||||
[app-user-model-id]: https://msdn.microsoft.com/en-us/library/windows/desktop/dd378459(v=vs.85).aspx
|
||||
[set-app-user-model-id]: ../api/app.md#appsetappusermodelidid-windows
|
||||
[squirrel-events]: https://github.com/electron/windows-installer/blob/master/README.md#handling-squirrel-events
|
||||
|
||||
@@ -73,7 +73,7 @@ until the maintainers feel the maintenance burden is too high to continue doing
|
||||
* 16.x.y
|
||||
* 15.x.y
|
||||
* 14.x.y
|
||||
* 13
|
||||
* 13.x.y
|
||||
|
||||
### End-of-life
|
||||
|
||||
|
||||
@@ -74,6 +74,17 @@ function makeWebPreferences (embedder: Electron.WebContents, params: Record<stri
|
||||
return webPreferences;
|
||||
}
|
||||
|
||||
function makeLoadURLOptions (params: Record<string, any>) {
|
||||
const opts: Electron.LoadURLOptions = {};
|
||||
if (params.httpreferrer) {
|
||||
opts.httpReferrer = params.httpreferrer;
|
||||
}
|
||||
if (params.useragent) {
|
||||
opts.userAgent = params.useragent;
|
||||
}
|
||||
return opts;
|
||||
}
|
||||
|
||||
// Create a new guest instance.
|
||||
const createGuest = function (embedder: Electron.WebContents, embedderFrameId: number, elementInstanceId: number, params: Record<string, any>) {
|
||||
// eslint-disable-next-line no-undef
|
||||
@@ -97,7 +108,7 @@ const createGuest = function (embedder: Electron.WebContents, embedderFrameId: n
|
||||
|
||||
// Init guest web view after attached.
|
||||
guest.once('did-attach' as any, function (this: Electron.WebContents, event: Electron.Event) {
|
||||
params = this.attachParams!;
|
||||
const params = this.attachParams!;
|
||||
delete this.attachParams;
|
||||
|
||||
const previouslyAttached = this.viewInstanceId != null;
|
||||
@@ -109,14 +120,7 @@ const createGuest = function (embedder: Electron.WebContents, embedderFrameId: n
|
||||
}
|
||||
|
||||
if (params.src) {
|
||||
const opts: Electron.LoadURLOptions = {};
|
||||
if (params.httpreferrer) {
|
||||
opts.httpReferrer = params.httpreferrer;
|
||||
}
|
||||
if (params.useragent) {
|
||||
opts.userAgent = params.useragent;
|
||||
}
|
||||
this.loadURL(params.src, opts);
|
||||
this.loadURL(params.src, params.opts);
|
||||
}
|
||||
embedder.emit('did-attach-webview', event, guest);
|
||||
});
|
||||
@@ -205,13 +209,15 @@ const attachGuest = function (embedder: Electron.WebContents, embedderFrameId: n
|
||||
return false;
|
||||
}
|
||||
|
||||
const { instanceId } = params;
|
||||
|
||||
// If this guest is already attached to an element then remove it
|
||||
if (guestInstance.elementInstanceId) {
|
||||
const oldKey = `${guestInstance.embedder.id}-${guestInstance.elementInstanceId}`;
|
||||
embedderElementsMap.delete(oldKey);
|
||||
|
||||
// Remove guest from embedder if moving across web views
|
||||
if (guest.viewInstanceId !== params.instanceId) {
|
||||
if (guest.viewInstanceId !== instanceId) {
|
||||
webViewManager.removeGuest(guestInstance.embedder, guestInstanceId);
|
||||
guestInstance.embedder._sendInternal(`${IPC_MESSAGES.GUEST_VIEW_INTERNAL_DESTROY_GUEST}-${guest.viewInstanceId}`);
|
||||
}
|
||||
@@ -222,12 +228,12 @@ const attachGuest = function (embedder: Electron.WebContents, embedderFrameId: n
|
||||
const event = eventBinding.createWithSender(embedder);
|
||||
embedder.emit('will-attach-webview', event, webPreferences, params);
|
||||
if (event.defaultPrevented) {
|
||||
if (guest.viewInstanceId == null) guest.viewInstanceId = params.instanceId;
|
||||
if (guest.viewInstanceId == null) guest.viewInstanceId = instanceId;
|
||||
guest.destroy();
|
||||
return false;
|
||||
}
|
||||
|
||||
guest.attachParams = params;
|
||||
guest.attachParams = { instanceId, src: params.src, opts: makeLoadURLOptions(params) };
|
||||
embedderElementsMap.set(key, guestInstanceId);
|
||||
|
||||
guest.setEmbedder(embedder);
|
||||
|
||||
@@ -25,7 +25,6 @@ export class WebViewImpl {
|
||||
public hasFocus = false
|
||||
public internalInstanceId?: number;
|
||||
public resizeObserver?: ResizeObserver;
|
||||
public userAgentOverride?: string;
|
||||
public viewInstanceId: number
|
||||
|
||||
// on* Event handlers.
|
||||
@@ -180,8 +179,7 @@ export class WebViewImpl {
|
||||
|
||||
buildParams () {
|
||||
const params: Record<string, any> = {
|
||||
instanceId: this.viewInstanceId,
|
||||
userAgentOverride: this.userAgentOverride
|
||||
instanceId: this.viewInstanceId
|
||||
};
|
||||
|
||||
for (const [attributeName, attribute] of this.attributes) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "electron",
|
||||
"version": "16.0.7",
|
||||
"version": "16.1.1",
|
||||
"repository": "https://github.com/electron/electron",
|
||||
"description": "Build cross platform desktop apps with JavaScript, HTML, and CSS",
|
||||
"devDependencies": {
|
||||
@@ -33,7 +33,7 @@
|
||||
"asar": "^3.1.0",
|
||||
"aws-sdk": "^2.727.1",
|
||||
"check-for-leaks": "^1.2.1",
|
||||
"colors": "^1.4.0",
|
||||
"colors": "1.4.0",
|
||||
"dotenv-safe": "^4.0.4",
|
||||
"dugite": "^1.103.0",
|
||||
"eslint": "^7.4.0",
|
||||
|
||||
6
patches/angle/.patches
Normal file
6
patches/angle/.patches
Normal file
@@ -0,0 +1,6 @@
|
||||
vangle_change_the_default_vulkan_device_choose_logic.patch
|
||||
m98_vulkan_fix_vkcmdresolveimage_extents.patch
|
||||
m98_vulkan_fix_vkcmdresolveimage_offsets.patch
|
||||
cherry-pick-49e8ff16f1fe.patch
|
||||
m99_vulkan_prevent_out_of_bounds_read_in_divisor_emulation_path.patch
|
||||
m99_vulkan_streamvertexdatawithdivisor_write_beyond_buffer_boundary.patch
|
||||
381
patches/angle/cherry-pick-49e8ff16f1fe.patch
Normal file
381
patches/angle/cherry-pick-49e8ff16f1fe.patch
Normal file
@@ -0,0 +1,381 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shahbaz Youssefi <syoussefi@chromium.org>
|
||||
Date: Tue, 25 Jan 2022 12:15:16 -0500
|
||||
Subject: M99: Vulkan: Fix texture array level redefinition
|
||||
|
||||
When a level of a texture is redefined, all staged updates to that level
|
||||
should be removed, not the ones specific to the new layers. The bug
|
||||
fixed was that if the texture was redefined to have its number of layers
|
||||
changed, the staged higher-layer-count update to the image was not
|
||||
removed.
|
||||
|
||||
Bug: chromium:1289383
|
||||
Change-Id: Iab79c38d846d1abbdd92e11b1b60a3adf0fbde4c
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3441309
|
||||
Reviewed-by: Lingfeng Yang <lfy@google.com>
|
||||
Reviewed-by: Jamie Madill <jmadill@chromium.org>
|
||||
|
||||
diff --git a/src/libANGLE/renderer/vulkan/TextureVk.cpp b/src/libANGLE/renderer/vulkan/TextureVk.cpp
|
||||
index 4c28358fad590350577177d9997f7731c3ea398f..75cd69adc7839fc05650fc7cc30680ca92102a7f 100644
|
||||
--- a/src/libANGLE/renderer/vulkan/TextureVk.cpp
|
||||
+++ b/src/libANGLE/renderer/vulkan/TextureVk.cpp
|
||||
@@ -1602,12 +1602,25 @@ angle::Result TextureVk::redefineLevel(const gl::Context *context,
|
||||
|
||||
if (mImage != nullptr)
|
||||
{
|
||||
- // If there is any staged changes for this index, we can remove them since we're going to
|
||||
+ // If there are any staged changes for this index, we can remove them since we're going to
|
||||
// override them with this call.
|
||||
gl::LevelIndex levelIndexGL(index.getLevelIndex());
|
||||
uint32_t layerIndex = index.hasLayer() ? index.getLayerIndex() : 0;
|
||||
- mImage->removeSingleSubresourceStagedUpdates(contextVk, levelIndexGL, layerIndex,
|
||||
- index.getLayerCount());
|
||||
+ if (gl::IsArrayTextureType(index.getType()))
|
||||
+ {
|
||||
+ // A multi-layer texture is being redefined, remove all updates to this level; the
|
||||
+ // number of layers may have changed.
|
||||
+ mImage->removeStagedUpdates(contextVk, levelIndexGL, levelIndexGL);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ // Otherwise remove only updates to this layer. For example, cube map updates can be
|
||||
+ // done through glTexImage2D, one per cube face (i.e. layer) and so should not remove
|
||||
+ // updates to the other layers.
|
||||
+ ASSERT(index.getLayerCount() == 1);
|
||||
+ mImage->removeSingleSubresourceStagedUpdates(contextVk, levelIndexGL, layerIndex,
|
||||
+ index.getLayerCount());
|
||||
+ }
|
||||
|
||||
if (mImage->valid())
|
||||
{
|
||||
diff --git a/src/tests/gl_tests/MipmapTest.cpp b/src/tests/gl_tests/MipmapTest.cpp
|
||||
index 8a6d01ca36a84a9e294de3f6f0114ee7a54e1d9a..957a52304edc9aa245f9f21e5557cc105cbad789 100644
|
||||
--- a/src/tests/gl_tests/MipmapTest.cpp
|
||||
+++ b/src/tests/gl_tests/MipmapTest.cpp
|
||||
@@ -1686,6 +1686,106 @@ TEST_P(MipmapTestES3, MipmapsForTexture3D)
|
||||
EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::red);
|
||||
}
|
||||
|
||||
+// Create a 2D array, then immediately redefine it to have fewer layers. Regression test for a bug
|
||||
+// in the Vulkan backend where the old higher-layer-count data upload was not removed.
|
||||
+TEST_P(MipmapTestES3, TextureArrayRedefineThenGenerateMipmap)
|
||||
+{
|
||||
+ int px = getWindowWidth() / 2;
|
||||
+ int py = getWindowHeight() / 2;
|
||||
+
|
||||
+ glBindTexture(GL_TEXTURE_2D_ARRAY, mTexture);
|
||||
+
|
||||
+ // Fill the whole texture with red, then redefine it and fill with green
|
||||
+ std::vector<GLColor> pixelsRed(2 * 2 * 4, GLColor::red);
|
||||
+ std::vector<GLColor> pixelsGreen(2 * 2 * 2, GLColor::green);
|
||||
+ glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 2, 2, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
|
||||
+ pixelsRed.data());
|
||||
+ glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
|
||||
+ pixelsGreen.data());
|
||||
+
|
||||
+ glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
|
||||
+ glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
+ EXPECT_GL_NO_ERROR();
|
||||
+
|
||||
+ // Generate mipmaps
|
||||
+ glGenerateMipmap(GL_TEXTURE_2D_ARRAY);
|
||||
+ EXPECT_GL_NO_ERROR();
|
||||
+
|
||||
+ glUseProgram(mArrayProgram);
|
||||
+ EXPECT_GL_NO_ERROR();
|
||||
+
|
||||
+ // Draw the first slice
|
||||
+ glUniform1i(mTextureArraySliceUniformLocation, 0);
|
||||
+ drawQuad(mArrayProgram, "position", 0.5f);
|
||||
+ EXPECT_GL_NO_ERROR();
|
||||
+ EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::green);
|
||||
+
|
||||
+ // Draw the second slice
|
||||
+ glUniform1i(mTextureArraySliceUniformLocation, 1);
|
||||
+ drawQuad(mArrayProgram, "position", 0.5f);
|
||||
+ EXPECT_GL_NO_ERROR();
|
||||
+ EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::green);
|
||||
+}
|
||||
+
|
||||
+// Create a 2D array, use it, then redefine it to have fewer layers. Regression test for a bug in
|
||||
+// the Vulkan backend where the old higher-layer-count data upload was not removed.
|
||||
+TEST_P(MipmapTestES3, TextureArrayUseThenRedefineThenGenerateMipmap)
|
||||
+{
|
||||
+ int px = getWindowWidth() / 2;
|
||||
+ int py = getWindowHeight() / 2;
|
||||
+
|
||||
+ glBindTexture(GL_TEXTURE_2D_ARRAY, mTexture);
|
||||
+
|
||||
+ // Fill the whole texture with red.
|
||||
+ std::vector<GLColor> pixelsRed(2 * 2 * 4, GLColor::red);
|
||||
+ glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 2, 2, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
|
||||
+ pixelsRed.data());
|
||||
+
|
||||
+ glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
|
||||
+ glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
+ EXPECT_GL_NO_ERROR();
|
||||
+
|
||||
+ // Generate mipmap
|
||||
+ glGenerateMipmap(GL_TEXTURE_2D_ARRAY);
|
||||
+ EXPECT_GL_NO_ERROR();
|
||||
+
|
||||
+ glUseProgram(mArrayProgram);
|
||||
+ EXPECT_GL_NO_ERROR();
|
||||
+
|
||||
+ // Draw the first slice
|
||||
+ glUniform1i(mTextureArraySliceUniformLocation, 0);
|
||||
+ drawQuad(mArrayProgram, "position", 0.5f);
|
||||
+ EXPECT_GL_NO_ERROR();
|
||||
+ EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::red);
|
||||
+
|
||||
+ // Draw the fourth slice
|
||||
+ glUniform1i(mTextureArraySliceUniformLocation, 3);
|
||||
+ drawQuad(mArrayProgram, "position", 0.5f);
|
||||
+ EXPECT_GL_NO_ERROR();
|
||||
+ EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::red);
|
||||
+
|
||||
+ // Redefine the image and fill with green
|
||||
+ std::vector<GLColor> pixelsGreen(2 * 2 * 2, GLColor::green);
|
||||
+ glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
|
||||
+ pixelsGreen.data());
|
||||
+
|
||||
+ // Generate mipmap
|
||||
+ glGenerateMipmap(GL_TEXTURE_2D_ARRAY);
|
||||
+ EXPECT_GL_NO_ERROR();
|
||||
+
|
||||
+ // Draw the first slice
|
||||
+ glUniform1i(mTextureArraySliceUniformLocation, 0);
|
||||
+ drawQuad(mArrayProgram, "position", 0.5f);
|
||||
+ EXPECT_GL_NO_ERROR();
|
||||
+ EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::green);
|
||||
+
|
||||
+ // Draw the second slice
|
||||
+ glUniform1i(mTextureArraySliceUniformLocation, 1);
|
||||
+ drawQuad(mArrayProgram, "position", 0.5f);
|
||||
+ EXPECT_GL_NO_ERROR();
|
||||
+ EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::green);
|
||||
+}
|
||||
+
|
||||
// Create a 2D texture with levels 0-2, call GenerateMipmap with base level 1 so that level 0 stays
|
||||
// the same, and then sample levels 0 and 2.
|
||||
// GLES 3.0.4 section 3.8.10:
|
||||
diff --git a/src/tests/gl_tests/TextureTest.cpp b/src/tests/gl_tests/TextureTest.cpp
|
||||
index 9ee0203153304080608a597ddbf1513d3a95616c..a46429331b3b272a89bdb8b31f7be75a4a82360c 100644
|
||||
--- a/src/tests/gl_tests/TextureTest.cpp
|
||||
+++ b/src/tests/gl_tests/TextureTest.cpp
|
||||
@@ -1030,31 +1030,37 @@ class SamplerArrayAsFunctionParameterTest : public SamplerArrayTest
|
||||
class Texture2DArrayTestES3 : public TexCoordDrawTest
|
||||
{
|
||||
protected:
|
||||
- Texture2DArrayTestES3() : TexCoordDrawTest(), m2DArrayTexture(0), mTextureArrayLocation(-1) {}
|
||||
+ Texture2DArrayTestES3()
|
||||
+ : TexCoordDrawTest(),
|
||||
+ m2DArrayTexture(0),
|
||||
+ mTextureArrayLocation(-1),
|
||||
+ mTextureArraySliceUniformLocation(-1)
|
||||
+ {}
|
||||
|
||||
const char *getVertexShaderSource() override
|
||||
{
|
||||
- return "#version 300 es\n"
|
||||
- "out vec2 texcoord;\n"
|
||||
- "in vec4 position;\n"
|
||||
- "void main()\n"
|
||||
- "{\n"
|
||||
- " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
|
||||
- " texcoord = (position.xy * 0.5) + 0.5;\n"
|
||||
- "}\n";
|
||||
+ return R"(#version 300 es
|
||||
+out vec2 texcoord;
|
||||
+in vec4 position;
|
||||
+void main()
|
||||
+{
|
||||
+ gl_Position = vec4(position.xy, 0.0, 1.0);
|
||||
+ texcoord = (position.xy * 0.5) + 0.5;
|
||||
+})";
|
||||
}
|
||||
|
||||
const char *getFragmentShaderSource() override
|
||||
{
|
||||
- return "#version 300 es\n"
|
||||
- "precision highp float;\n"
|
||||
- "uniform highp sampler2DArray tex2DArray;\n"
|
||||
- "in vec2 texcoord;\n"
|
||||
- "out vec4 fragColor;\n"
|
||||
- "void main()\n"
|
||||
- "{\n"
|
||||
- " fragColor = texture(tex2DArray, vec3(texcoord.x, texcoord.y, 0.0));\n"
|
||||
- "}\n";
|
||||
+ return R"(#version 300 es
|
||||
+precision highp float;
|
||||
+uniform highp sampler2DArray tex2DArray;
|
||||
+uniform int slice;
|
||||
+in vec2 texcoord;
|
||||
+out vec4 fragColor;
|
||||
+void main()
|
||||
+{
|
||||
+ fragColor = texture(tex2DArray, vec3(texcoord, float(slice)));
|
||||
+})";
|
||||
}
|
||||
|
||||
void testSetUp() override
|
||||
@@ -1066,6 +1072,9 @@ class Texture2DArrayTestES3 : public TexCoordDrawTest
|
||||
mTextureArrayLocation = glGetUniformLocation(mProgram, "tex2DArray");
|
||||
ASSERT_NE(-1, mTextureArrayLocation);
|
||||
|
||||
+ mTextureArraySliceUniformLocation = glGetUniformLocation(mProgram, "slice");
|
||||
+ ASSERT_NE(-1, mTextureArraySliceUniformLocation);
|
||||
+
|
||||
glGenTextures(1, &m2DArrayTexture);
|
||||
ASSERT_GL_NO_ERROR();
|
||||
}
|
||||
@@ -1078,6 +1087,7 @@ class Texture2DArrayTestES3 : public TexCoordDrawTest
|
||||
|
||||
GLuint m2DArrayTexture;
|
||||
GLint mTextureArrayLocation;
|
||||
+ GLint mTextureArraySliceUniformLocation;
|
||||
};
|
||||
|
||||
class TextureSizeTextureArrayTest : public TexCoordDrawTest
|
||||
@@ -1720,28 +1730,28 @@ class Texture2DArrayIntegerTestES3 : public Texture2DArrayTestES3
|
||||
|
||||
const char *getVertexShaderSource() override
|
||||
{
|
||||
- return "#version 300 es\n"
|
||||
- "out vec2 texcoord;\n"
|
||||
- "in vec4 position;\n"
|
||||
- "void main()\n"
|
||||
- "{\n"
|
||||
- " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
|
||||
- " texcoord = (position.xy * 0.5) + 0.5;\n"
|
||||
- "}\n";
|
||||
+ return R"(#version 300 es
|
||||
+out vec2 texcoord;
|
||||
+in vec4 position;
|
||||
+void main()
|
||||
+{
|
||||
+ gl_Position = vec4(position.xy, 0.0, 1.0);
|
||||
+ texcoord = (position.xy * 0.5) + 0.5;
|
||||
+})";
|
||||
}
|
||||
|
||||
const char *getFragmentShaderSource() override
|
||||
{
|
||||
- return "#version 300 es\n"
|
||||
- "precision highp float;\n"
|
||||
- "uniform highp usampler2DArray tex2DArray;\n"
|
||||
- "in vec2 texcoord;\n"
|
||||
- "out vec4 fragColor;\n"
|
||||
- "void main()\n"
|
||||
- "{\n"
|
||||
- " fragColor = vec4(texture(tex2DArray, vec3(texcoord.x, texcoord.y, "
|
||||
- "0.0)))/255.0;\n"
|
||||
- "}\n";
|
||||
+ return R"(#version 300 es
|
||||
+precision highp float;
|
||||
+uniform highp usampler2DArray tex2DArray;
|
||||
+uniform int slice;
|
||||
+in vec2 texcoord;
|
||||
+out vec4 fragColor;
|
||||
+void main()
|
||||
+{
|
||||
+ fragColor = vec4(texture(tex2DArray, vec3(texcoord, slice)))/255.0;
|
||||
+})";
|
||||
}
|
||||
};
|
||||
|
||||
@@ -5162,6 +5172,94 @@ TEST_P(Texture2DArrayTestES3, DrawWithLevelsOutsideRangeWithInconsistentDimensio
|
||||
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
|
||||
}
|
||||
|
||||
+// Create a 2D array, then immediately redefine it to have fewer layers. Regression test for a bug
|
||||
+// in the Vulkan backend where the old higher-layer-count data upload was not removed.
|
||||
+TEST_P(Texture2DArrayTestES3, TextureArrayRedefineThenUse)
|
||||
+{
|
||||
+ int px = getWindowWidth() / 2;
|
||||
+ int py = getWindowHeight() / 2;
|
||||
+
|
||||
+ glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
|
||||
+
|
||||
+ // Fill the whole texture with red, then redefine it and fill with green
|
||||
+ std::vector<GLColor> pixelsRed(2 * 2 * 4, GLColor::red);
|
||||
+ std::vector<GLColor> pixelsGreen(2 * 2 * 2, GLColor::green);
|
||||
+ glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 2, 2, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
|
||||
+ pixelsRed.data());
|
||||
+ glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
|
||||
+ pixelsGreen.data());
|
||||
+
|
||||
+ glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
+ glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
+ EXPECT_GL_NO_ERROR();
|
||||
+
|
||||
+ glUseProgram(mProgram);
|
||||
+ EXPECT_GL_NO_ERROR();
|
||||
+
|
||||
+ // Draw the first slice
|
||||
+ glUniform1i(mTextureArraySliceUniformLocation, 0);
|
||||
+ drawQuad(mProgram, "position", 0.5f);
|
||||
+ EXPECT_GL_NO_ERROR();
|
||||
+ EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::green);
|
||||
+
|
||||
+ // Draw the second slice
|
||||
+ glUniform1i(mTextureArraySliceUniformLocation, 1);
|
||||
+ drawQuad(mProgram, "position", 0.5f);
|
||||
+ EXPECT_GL_NO_ERROR();
|
||||
+ EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::green);
|
||||
+}
|
||||
+
|
||||
+// Create a 2D array, use it, then redefine it to have fewer layers. Regression test for a bug in
|
||||
+// the Vulkan backend where the old higher-layer-count data upload was not removed.
|
||||
+TEST_P(Texture2DArrayTestES3, TextureArrayUseThenRedefineThenUse)
|
||||
+{
|
||||
+ int px = getWindowWidth() / 2;
|
||||
+ int py = getWindowHeight() / 2;
|
||||
+
|
||||
+ glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
|
||||
+
|
||||
+ // Fill the whole texture with red.
|
||||
+ std::vector<GLColor> pixelsRed(2 * 2 * 4, GLColor::red);
|
||||
+ glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 2, 2, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
|
||||
+ pixelsRed.data());
|
||||
+
|
||||
+ glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
+ glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
+ EXPECT_GL_NO_ERROR();
|
||||
+
|
||||
+ glUseProgram(mProgram);
|
||||
+ EXPECT_GL_NO_ERROR();
|
||||
+
|
||||
+ // Draw the first slice
|
||||
+ glUniform1i(mTextureArraySliceUniformLocation, 0);
|
||||
+ drawQuad(mProgram, "position", 0.5f);
|
||||
+ EXPECT_GL_NO_ERROR();
|
||||
+ EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::red);
|
||||
+
|
||||
+ // Draw the fourth slice
|
||||
+ glUniform1i(mTextureArraySliceUniformLocation, 3);
|
||||
+ drawQuad(mProgram, "position", 0.5f);
|
||||
+ EXPECT_GL_NO_ERROR();
|
||||
+ EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::red);
|
||||
+
|
||||
+ // Redefine the image and fill with green
|
||||
+ std::vector<GLColor> pixelsGreen(2 * 2 * 2, GLColor::green);
|
||||
+ glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
|
||||
+ pixelsGreen.data());
|
||||
+
|
||||
+ // Draw the first slice
|
||||
+ glUniform1i(mTextureArraySliceUniformLocation, 0);
|
||||
+ drawQuad(mProgram, "position", 0.5f);
|
||||
+ EXPECT_GL_NO_ERROR();
|
||||
+ EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::green);
|
||||
+
|
||||
+ // Draw the second slice
|
||||
+ glUniform1i(mTextureArraySliceUniformLocation, 1);
|
||||
+ drawQuad(mProgram, "position", 0.5f);
|
||||
+ EXPECT_GL_NO_ERROR();
|
||||
+ EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::green);
|
||||
+}
|
||||
+
|
||||
// Test that texture completeness is updated if texture max level changes.
|
||||
// GLES 3.0.4 section 3.8.13 Texture completeness
|
||||
TEST_P(Texture2DTestES3, TextureCompletenessChangesWithMaxLevel)
|
||||
112
patches/angle/m98_vulkan_fix_vkcmdresolveimage_extents.patch
Normal file
112
patches/angle/m98_vulkan_fix_vkcmdresolveimage_extents.patch
Normal file
@@ -0,0 +1,112 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shahbaz Youssefi <syoussefi@chromium.org>
|
||||
Date: Mon, 31 Jan 2022 12:07:43 -0500
|
||||
Subject: M98: Vulkan: Fix vkCmdResolveImage extents
|
||||
|
||||
The source framebuffer's extents were accidentally used instead of the
|
||||
blit area extents.
|
||||
|
||||
Bug: chromium:1288020
|
||||
Change-Id: I5c6128a191deeea2f972dc7f010be9d40c674ce6
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3457022
|
||||
Reviewed-by: Tim Van Patten <timvp@google.com>
|
||||
|
||||
diff --git a/src/libANGLE/renderer/vulkan/FramebufferVk.cpp b/src/libANGLE/renderer/vulkan/FramebufferVk.cpp
|
||||
index 2eeaa66d2692fe7631591377f32b89cdd90aaf05..4ece465efb683c40027dfee083dd2ed567a0bfc4 100644
|
||||
--- a/src/libANGLE/renderer/vulkan/FramebufferVk.cpp
|
||||
+++ b/src/libANGLE/renderer/vulkan/FramebufferVk.cpp
|
||||
@@ -1464,8 +1464,8 @@ angle::Result FramebufferVk::resolveColorWithCommand(ContextVk *contextVk,
|
||||
resolveRegion.dstOffset.x = params.destOffset[0];
|
||||
resolveRegion.dstOffset.y = params.destOffset[1];
|
||||
resolveRegion.dstOffset.z = 0;
|
||||
- resolveRegion.extent.width = params.srcExtents[0];
|
||||
- resolveRegion.extent.height = params.srcExtents[1];
|
||||
+ resolveRegion.extent.width = params.blitArea.width;
|
||||
+ resolveRegion.extent.height = params.blitArea.height;
|
||||
resolveRegion.extent.depth = 1;
|
||||
|
||||
vk::PerfCounters &perfCounters = contextVk->getPerfCounters();
|
||||
diff --git a/src/tests/angle_end2end_tests_expectations.txt b/src/tests/angle_end2end_tests_expectations.txt
|
||||
index 18b80da7f6f30f7e8e8e1df2b05c13be6c5b85de..844d38a75ad054c6ed5cd95cb20a49dadbae267b 100644
|
||||
--- a/src/tests/angle_end2end_tests_expectations.txt
|
||||
+++ b/src/tests/angle_end2end_tests_expectations.txt
|
||||
@@ -81,6 +81,7 @@
|
||||
// the test says. The test also fails on Intel/Vulkan/Windows.
|
||||
6068 INTEL VULKAN : MultiviewRenderPrimitiveTest.LineLoop/* = SKIP
|
||||
6068 INTEL VULKAN : MultiviewRenderPrimitiveTest.LineStrip/* = SKIP
|
||||
+6962 WIN INTEL VULKAN : BlitFramebufferTestES31.PartialResolve/* = SKIP
|
||||
|
||||
// Mac
|
||||
|
||||
diff --git a/src/tests/gl_tests/BlitFramebufferANGLETest.cpp b/src/tests/gl_tests/BlitFramebufferANGLETest.cpp
|
||||
index 6fd3f08ef20e315d10c593868d94f6653fa5cdf4..e4d82a511b77ac3b379ec088703d21ce480fafa9 100644
|
||||
--- a/src/tests/gl_tests/BlitFramebufferANGLETest.cpp
|
||||
+++ b/src/tests/gl_tests/BlitFramebufferANGLETest.cpp
|
||||
@@ -2603,6 +2603,67 @@ TEST_P(BlitFramebufferTest, BlitDepthStencilPixelByPixel)
|
||||
EXPECT_PIXEL_RECT_EQ(64, 0, 128, 1, GLColor::blue);
|
||||
}
|
||||
|
||||
+// Regression test for a bug in the Vulkan backend where vkCmdResolveImage was using the src extents
|
||||
+// as the resolve area instead of the area passed to glBlitFramebuffer.
|
||||
+TEST_P(BlitFramebufferTestES31, PartialResolve)
|
||||
+{
|
||||
+ constexpr GLint kWidth = 16;
|
||||
+ constexpr GLint kHeight = 32;
|
||||
+
|
||||
+ // Read framebuffer is multisampled.
|
||||
+ GLTexture readTexture;
|
||||
+ glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, readTexture);
|
||||
+ glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, kWidth, kHeight, GL_TRUE);
|
||||
+
|
||||
+ GLFramebuffer readFbo;
|
||||
+ glBindFramebuffer(GL_FRAMEBUFFER, readFbo);
|
||||
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
|
||||
+ readTexture, 0);
|
||||
+ ASSERT_GL_NO_ERROR();
|
||||
+ ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
|
||||
+
|
||||
+ glClearColor(1, 0, 0, 1);
|
||||
+ glClear(GL_COLOR_BUFFER_BIT);
|
||||
+
|
||||
+ // Draw framebuffer is single sampled. It's bound to a texture with base level the same size as
|
||||
+ // the read framebuffer, but it's bound to mip 1.
|
||||
+ GLTexture drawTexture;
|
||||
+ glBindTexture(GL_TEXTURE_2D, drawTexture);
|
||||
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
|
||||
+ nullptr);
|
||||
+ glGenerateMipmap(GL_TEXTURE_2D);
|
||||
+
|
||||
+ GLFramebuffer drawFbo;
|
||||
+ glBindFramebuffer(GL_FRAMEBUFFER, drawFbo);
|
||||
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, drawTexture, 1);
|
||||
+ ASSERT_GL_NO_ERROR();
|
||||
+ ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
|
||||
+
|
||||
+ glClearColor(0, 1, 0, 1);
|
||||
+ glClear(GL_COLOR_BUFFER_BIT);
|
||||
+ EXPECT_PIXEL_RECT_EQ(0, 0, kWidth / 2, kHeight / 2, GLColor::green);
|
||||
+
|
||||
+ constexpr GLint kResolveX0 = 1;
|
||||
+ constexpr GLint kResolveY0 = 2;
|
||||
+ constexpr GLint kResolveX1 = 4;
|
||||
+ constexpr GLint kResolveY1 = 6;
|
||||
+
|
||||
+ // Resolve only a portion of the read framebuffer.
|
||||
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, readFbo);
|
||||
+ glBlitFramebuffer(kResolveX0, kResolveY0, kResolveX1, kResolveY1, kResolveX0, kResolveY0,
|
||||
+ kResolveX1, kResolveY1, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
+ ASSERT_GL_NO_ERROR();
|
||||
+
|
||||
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, drawFbo);
|
||||
+ EXPECT_PIXEL_RECT_EQ(0, 0, kWidth / 2, kResolveY0, GLColor::green);
|
||||
+ EXPECT_PIXEL_RECT_EQ(0, 0, kResolveX0, kHeight / 2, GLColor::green);
|
||||
+ EXPECT_PIXEL_RECT_EQ(kResolveX1, 0, kWidth / 2 - kResolveX1, kHeight / 2, GLColor::green);
|
||||
+ EXPECT_PIXEL_RECT_EQ(0, kResolveY1, kWidth / 2, kHeight / 2 - kResolveY1, GLColor::green);
|
||||
+
|
||||
+ EXPECT_PIXEL_RECT_EQ(kResolveX0, kResolveY0, kResolveX1 - kResolveX0, kResolveY1 - kResolveY0,
|
||||
+ GLColor::red);
|
||||
+}
|
||||
+
|
||||
// Test that a draw call to a small FBO followed by a resolve of a large FBO works.
|
||||
TEST_P(BlitFramebufferTestES31, DrawToSmallFBOThenResolveLargeFBO)
|
||||
{
|
||||
109
patches/angle/m98_vulkan_fix_vkcmdresolveimage_offsets.patch
Normal file
109
patches/angle/m98_vulkan_fix_vkcmdresolveimage_offsets.patch
Normal file
@@ -0,0 +1,109 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shahbaz Youssefi <syoussefi@chromium.org>
|
||||
Date: Mon, 7 Feb 2022 13:46:46 -0500
|
||||
Subject: M98: Vulkan: Fix vkCmdResolveImage offsets
|
||||
|
||||
glBlitFramebuffer takes identical regions for src and dst when
|
||||
resolving. vkCmdResolveImage should use the clipped area instead of
|
||||
using the actual offsets passed to this function.
|
||||
|
||||
Bug: chromium:1292537
|
||||
Change-Id: If283a8acbca3249b771facbc30bd9f8080a03656
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3457023
|
||||
Reviewed-by: Tim Van Patten <timvp@google.com>
|
||||
|
||||
diff --git a/src/libANGLE/renderer/vulkan/FramebufferVk.cpp b/src/libANGLE/renderer/vulkan/FramebufferVk.cpp
|
||||
index 4ece465efb683c40027dfee083dd2ed567a0bfc4..8099a00084eebcd41603087627a7254a2ef04fd4 100644
|
||||
--- a/src/libANGLE/renderer/vulkan/FramebufferVk.cpp
|
||||
+++ b/src/libANGLE/renderer/vulkan/FramebufferVk.cpp
|
||||
@@ -1456,13 +1456,13 @@ angle::Result FramebufferVk::resolveColorWithCommand(ContextVk *contextVk,
|
||||
resolveRegion.srcSubresource.mipLevel = 0;
|
||||
resolveRegion.srcSubresource.baseArrayLayer = params.srcLayer;
|
||||
resolveRegion.srcSubresource.layerCount = 1;
|
||||
- resolveRegion.srcOffset.x = params.srcOffset[0];
|
||||
- resolveRegion.srcOffset.y = params.srcOffset[1];
|
||||
+ resolveRegion.srcOffset.x = params.blitArea.x;
|
||||
+ resolveRegion.srcOffset.y = params.blitArea.y;
|
||||
resolveRegion.srcOffset.z = 0;
|
||||
resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
resolveRegion.dstSubresource.layerCount = 1;
|
||||
- resolveRegion.dstOffset.x = params.destOffset[0];
|
||||
- resolveRegion.dstOffset.y = params.destOffset[1];
|
||||
+ resolveRegion.dstOffset.x = params.blitArea.x;
|
||||
+ resolveRegion.dstOffset.y = params.blitArea.y;
|
||||
resolveRegion.dstOffset.z = 0;
|
||||
resolveRegion.extent.width = params.blitArea.width;
|
||||
resolveRegion.extent.height = params.blitArea.height;
|
||||
diff --git a/src/tests/angle_end2end_tests_expectations.txt b/src/tests/angle_end2end_tests_expectations.txt
|
||||
index 844d38a75ad054c6ed5cd95cb20a49dadbae267b..5cde8f7170688686cde3e1984a788d64d85d9c2d 100644
|
||||
--- a/src/tests/angle_end2end_tests_expectations.txt
|
||||
+++ b/src/tests/angle_end2end_tests_expectations.txt
|
||||
@@ -21,6 +21,8 @@
|
||||
6347 OPENGL : FramebufferTestWithFormatFallback.RGBA4444_BlitCopyTexImage/* = SKIP
|
||||
6347 GLES : FramebufferTestWithFormatFallback.R5G5B5A1_BlitCopyTexImage/* = SKIP
|
||||
6347 GLES : FramebufferTestWithFormatFallback.RGBA4444_BlitCopyTexImage/* = SKIP
|
||||
+6989 OPENGL : BlitFramebufferTestES31.OOBResolve/* = SKIP
|
||||
+6989 GLES : BlitFramebufferTestES31.OOBResolve/* = SKIP
|
||||
|
||||
// Direct SPIR-V generation. The following tests pass on some platforms but not others. Need to investigate.
|
||||
4889 VULKAN : GeometryShaderTest.LayeredFramebufferPreRenderClear2DArrayColor/ES3_1_Vulkan_DirectSPIRVGen = SKIP
|
||||
diff --git a/src/tests/gl_tests/BlitFramebufferANGLETest.cpp b/src/tests/gl_tests/BlitFramebufferANGLETest.cpp
|
||||
index e4d82a511b77ac3b379ec088703d21ce480fafa9..92559f965137c8a2202b0840e298648c5e8b8740 100644
|
||||
--- a/src/tests/gl_tests/BlitFramebufferANGLETest.cpp
|
||||
+++ b/src/tests/gl_tests/BlitFramebufferANGLETest.cpp
|
||||
@@ -2603,6 +2603,55 @@ TEST_P(BlitFramebufferTest, BlitDepthStencilPixelByPixel)
|
||||
EXPECT_PIXEL_RECT_EQ(64, 0, 128, 1, GLColor::blue);
|
||||
}
|
||||
|
||||
+// Regression test for a bug in the Vulkan backend where vkCmdResolveImage was used with
|
||||
+// out-of-bounds regions.
|
||||
+TEST_P(BlitFramebufferTestES31, OOBResolve)
|
||||
+{
|
||||
+ constexpr GLint kWidth = 16;
|
||||
+ constexpr GLint kHeight = 32;
|
||||
+
|
||||
+ // Read framebuffer is multisampled.
|
||||
+ GLTexture readTexture;
|
||||
+ glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, readTexture);
|
||||
+ glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, kWidth, kHeight, GL_TRUE);
|
||||
+
|
||||
+ GLFramebuffer readFbo;
|
||||
+ glBindFramebuffer(GL_FRAMEBUFFER, readFbo);
|
||||
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
|
||||
+ readTexture, 0);
|
||||
+ ASSERT_GL_NO_ERROR();
|
||||
+ ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
|
||||
+
|
||||
+ glClearColor(1, 0, 0, 1);
|
||||
+ glClear(GL_COLOR_BUFFER_BIT);
|
||||
+
|
||||
+ // Draw framebuffer is single sampled.
|
||||
+ GLTexture drawTexture;
|
||||
+ glBindTexture(GL_TEXTURE_2D, drawTexture);
|
||||
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
|
||||
+ nullptr);
|
||||
+ glGenerateMipmap(GL_TEXTURE_2D);
|
||||
+
|
||||
+ GLFramebuffer drawFbo;
|
||||
+ glBindFramebuffer(GL_FRAMEBUFFER, drawFbo);
|
||||
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, drawTexture, 0);
|
||||
+ ASSERT_GL_NO_ERROR();
|
||||
+ ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
|
||||
+
|
||||
+ glClearColor(0, 1, 0, 1);
|
||||
+ glClear(GL_COLOR_BUFFER_BIT);
|
||||
+ EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::green);
|
||||
+
|
||||
+ // Resolve the read framebuffer, using bounds that are outside the size of the image.
|
||||
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, readFbo);
|
||||
+ glBlitFramebuffer(-kWidth * 2, -kHeight * 3, kWidth * 11, kHeight * 8, -kWidth * 2,
|
||||
+ -kHeight * 3, kWidth * 11, kHeight * 8, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
+ ASSERT_GL_NO_ERROR();
|
||||
+
|
||||
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, drawFbo);
|
||||
+ EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::red);
|
||||
+}
|
||||
+
|
||||
// Regression test for a bug in the Vulkan backend where vkCmdResolveImage was using the src extents
|
||||
// as the resolve area instead of the area passed to glBlitFramebuffer.
|
||||
TEST_P(BlitFramebufferTestES31, PartialResolve)
|
||||
@@ -0,0 +1,304 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Roman Lavrov <romanl@google.com>
|
||||
Date: Tue, 18 Jan 2022 20:05:55 +0000
|
||||
Subject: M99: Vulkan: Prevent out of bounds read in divisor emulation path.
|
||||
|
||||
Split the replicated part of StreamVertexData out to
|
||||
StreamVertexDataWithDivisor, there is only a partial argument
|
||||
overlap between the two.
|
||||
|
||||
Bug: chromium:1285885
|
||||
Change-Id: Ibf6ab3efc6b12b430b1d391c6ae61bd9668b4407
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3398816
|
||||
Reviewed-by: Jamie Madill <jmadill@chromium.org>
|
||||
Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
|
||||
Commit-Queue: Roman Lavrov <romanl@google.com>
|
||||
(cherry picked from commit 5f0badf4541ba52659c937cfe9190d3735a76c10)
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3461414
|
||||
|
||||
diff --git a/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp b/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp
|
||||
index 09cb058a612bfb62ece95b5a1bb7beb4df96e0e3..4e443ed34c29284739fbefb16a38feefed90b726 100644
|
||||
--- a/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp
|
||||
+++ b/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp
|
||||
@@ -82,34 +82,63 @@ angle::Result StreamVertexData(ContextVk *contextVk,
|
||||
size_t destOffset,
|
||||
size_t vertexCount,
|
||||
size_t sourceStride,
|
||||
- size_t destStride,
|
||||
VertexCopyFunction vertexLoadFunction,
|
||||
vk::BufferHelper **bufferOut,
|
||||
- VkDeviceSize *bufferOffsetOut,
|
||||
- uint32_t replicateCount)
|
||||
+ VkDeviceSize *bufferOffsetOut)
|
||||
{
|
||||
uint8_t *dst = nullptr;
|
||||
ANGLE_TRY(dynamicBuffer->allocate(contextVk, bytesToAllocate, &dst, nullptr, bufferOffsetOut,
|
||||
nullptr));
|
||||
*bufferOut = dynamicBuffer->getCurrentBuffer();
|
||||
dst += destOffset;
|
||||
- if (replicateCount == 1)
|
||||
+ vertexLoadFunction(sourceData, sourceStride, vertexCount, dst);
|
||||
+
|
||||
+ ANGLE_TRY(dynamicBuffer->flush(contextVk));
|
||||
+
|
||||
+ return angle::Result::Continue;
|
||||
+}
|
||||
+
|
||||
+angle::Result StreamVertexDataWithDivisor(ContextVk *contextVk,
|
||||
+ vk::DynamicBuffer *dynamicBuffer,
|
||||
+ const uint8_t *sourceData,
|
||||
+ size_t bytesToAllocate,
|
||||
+ size_t sourceStride,
|
||||
+ size_t destStride,
|
||||
+ VertexCopyFunction vertexLoadFunction,
|
||||
+ vk::BufferHelper **bufferOut,
|
||||
+ VkDeviceSize *bufferOffsetOut,
|
||||
+ uint32_t divisor,
|
||||
+ size_t numSrcVertices)
|
||||
+{
|
||||
+ uint8_t *dst = nullptr;
|
||||
+ ANGLE_TRY(dynamicBuffer->allocate(contextVk, bytesToAllocate, &dst, nullptr, bufferOffsetOut,
|
||||
+ nullptr));
|
||||
+ *bufferOut = dynamicBuffer->getCurrentBuffer();
|
||||
+
|
||||
+ // Each source vertex is used `divisor` times before advancing. Clamp to avoid OOB reads.
|
||||
+ size_t clampedSize = std::min(numSrcVertices * destStride * divisor, bytesToAllocate);
|
||||
+
|
||||
+ ASSERT(clampedSize % destStride == 0);
|
||||
+ ASSERT(divisor > 0);
|
||||
+
|
||||
+ uint32_t sourceVertexUseCount = 0;
|
||||
+ for (size_t dataCopied = 0; dataCopied < clampedSize; dataCopied += destStride, dst += destStride)
|
||||
{
|
||||
- vertexLoadFunction(sourceData, sourceStride, vertexCount, dst);
|
||||
+ vertexLoadFunction(sourceData, sourceStride, 1, dst);
|
||||
+ sourceVertexUseCount++;
|
||||
+ if (sourceVertexUseCount == divisor)
|
||||
+ {
|
||||
+ sourceData += sourceStride;
|
||||
+ sourceVertexUseCount = 0;
|
||||
+ }
|
||||
}
|
||||
- else
|
||||
+
|
||||
+ // Satisfy robustness constraints (only if extension enabled)
|
||||
+ if (contextVk->getExtensions().robustnessEXT)
|
||||
{
|
||||
- ASSERT(replicateCount > 1);
|
||||
- uint32_t sourceRemainingCount = replicateCount - 1;
|
||||
- for (size_t dataCopied = 0; dataCopied < bytesToAllocate;
|
||||
- dataCopied += destStride, dst += destStride, sourceRemainingCount--)
|
||||
+ if (clampedSize < bytesToAllocate)
|
||||
{
|
||||
- vertexLoadFunction(sourceData, sourceStride, 1, dst);
|
||||
- if (sourceRemainingCount == 0)
|
||||
- {
|
||||
- sourceData += sourceStride;
|
||||
- sourceRemainingCount = replicateCount;
|
||||
- }
|
||||
+ memset(dst + clampedSize, 0, bytesToAllocate - clampedSize);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,6 +154,7 @@ size_t GetVertexCount(BufferVk *srcBuffer, const gl::VertexBinding &binding, uin
|
||||
return 0;
|
||||
|
||||
// Count the last vertex. It may occupy less than a full stride.
|
||||
+ // This is also correct if stride happens to be less than srcFormatSize.
|
||||
size_t numVertices = 1;
|
||||
bytes -= srcFormatSize;
|
||||
|
||||
@@ -453,8 +483,8 @@ angle::Result VertexArrayVk::convertVertexBufferCPU(ContextVk *contextVk,
|
||||
ASSERT(vertexFormat.getVertexInputAlignment(compressed) <= vk::kVertexBufferAlignment);
|
||||
ANGLE_TRY(StreamVertexData(
|
||||
contextVk, &conversion->data, srcBytes, numVertices * dstFormatSize, 0, numVertices,
|
||||
- binding.getStride(), srcFormatSize, vertexFormat.getVertexLoadFunction(compressed),
|
||||
- &mCurrentArrayBuffers[attribIndex], &conversion->lastAllocationOffset, 1));
|
||||
+ binding.getStride(), vertexFormat.getVertexLoadFunction(compressed),
|
||||
+ &mCurrentArrayBuffers[attribIndex], &conversion->lastAllocationOffset));
|
||||
ANGLE_TRY(srcBuffer->unmapImpl(contextVk));
|
||||
|
||||
ASSERT(conversion->dirty);
|
||||
@@ -817,28 +847,41 @@ angle::Result VertexArrayVk::updateStreamedAttribs(const gl::Context *context,
|
||||
// Instanced attrib
|
||||
if (divisor > renderer->getMaxVertexAttribDivisor())
|
||||
{
|
||||
- // Emulated attrib
|
||||
- BufferVk *bufferVk = nullptr;
|
||||
+ // Divisor will be set to 1 & so update buffer to have 1 attrib per instance
|
||||
+ size_t bytesToAllocate = instanceCount * stride;
|
||||
+
|
||||
if (binding.getBuffer().get() != nullptr)
|
||||
{
|
||||
// Map buffer to expand attribs for divisor emulation
|
||||
- bufferVk = vk::GetImpl(binding.getBuffer().get());
|
||||
- void *buffSrc = nullptr;
|
||||
+ BufferVk *bufferVk = vk::GetImpl(binding.getBuffer().get());
|
||||
+ void *buffSrc = nullptr;
|
||||
ANGLE_TRY(bufferVk->mapImpl(contextVk, &buffSrc));
|
||||
src = reinterpret_cast<const uint8_t *>(buffSrc) + binding.getOffset();
|
||||
- }
|
||||
- // Divisor will be set to 1 & so update buffer to have 1 attrib per instance
|
||||
- size_t bytesToAllocate = instanceCount * stride;
|
||||
|
||||
- ANGLE_TRY(StreamVertexData(contextVk, &mDynamicVertexData, src, bytesToAllocate, 0,
|
||||
- instanceCount, binding.getStride(), stride,
|
||||
- vertexFormat.getVertexLoadFunction(compressed),
|
||||
- &mCurrentArrayBuffers[attribIndex],
|
||||
- &mCurrentArrayBufferOffsets[attribIndex], divisor));
|
||||
- if (bufferVk)
|
||||
- {
|
||||
+ uint32_t srcAttributeSize =
|
||||
+ static_cast<uint32_t>(ComputeVertexAttributeTypeSize(attrib));
|
||||
+
|
||||
+ size_t numVertices = GetVertexCount(bufferVk, binding, srcAttributeSize);
|
||||
+
|
||||
+ ANGLE_TRY(StreamVertexDataWithDivisor(
|
||||
+ contextVk, &mDynamicVertexData, src, bytesToAllocate, binding.getStride(),
|
||||
+ stride, vertexFormat.getVertexLoadFunction(compressed),
|
||||
+ &mCurrentArrayBuffers[attribIndex],
|
||||
+ &mCurrentArrayBufferOffsets[attribIndex], divisor,
|
||||
+ numVertices));
|
||||
+
|
||||
ANGLE_TRY(bufferVk->unmapImpl(contextVk));
|
||||
}
|
||||
+ else
|
||||
+ {
|
||||
+ size_t numVertices = instanceCount;
|
||||
+ ANGLE_TRY(StreamVertexDataWithDivisor(
|
||||
+ contextVk, &mDynamicVertexData, src, bytesToAllocate, binding.getStride(),
|
||||
+ stride, vertexFormat.getVertexLoadFunction(compressed),
|
||||
+ &mCurrentArrayBuffers[attribIndex],
|
||||
+ &mCurrentArrayBufferOffsets[attribIndex], divisor,
|
||||
+ numVertices));
|
||||
+ }
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -847,10 +890,10 @@ angle::Result VertexArrayVk::updateStreamedAttribs(const gl::Context *context,
|
||||
size_t bytesToAllocate = count * stride;
|
||||
|
||||
ANGLE_TRY(StreamVertexData(contextVk, &mDynamicVertexData, src, bytesToAllocate, 0,
|
||||
- count, binding.getStride(), stride,
|
||||
+ count, binding.getStride(),
|
||||
vertexFormat.getVertexLoadFunction(compressed),
|
||||
&mCurrentArrayBuffers[attribIndex],
|
||||
- &mCurrentArrayBufferOffsets[attribIndex], 1));
|
||||
+ &mCurrentArrayBufferOffsets[attribIndex]));
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -865,8 +908,8 @@ angle::Result VertexArrayVk::updateStreamedAttribs(const gl::Context *context,
|
||||
|
||||
ANGLE_TRY(StreamVertexData(
|
||||
contextVk, &mDynamicVertexData, src, bytesToAllocate, destOffset, vertexCount,
|
||||
- binding.getStride(), stride, vertexFormat.getVertexLoadFunction(compressed),
|
||||
- &mCurrentArrayBuffers[attribIndex], &mCurrentArrayBufferOffsets[attribIndex], 1));
|
||||
+ binding.getStride(), vertexFormat.getVertexLoadFunction(compressed),
|
||||
+ &mCurrentArrayBuffers[attribIndex], &mCurrentArrayBufferOffsets[attribIndex]));
|
||||
}
|
||||
|
||||
mCurrentArrayBufferHandles[attribIndex] =
|
||||
diff --git a/src/tests/gl_tests/RobustBufferAccessBehaviorTest.cpp b/src/tests/gl_tests/RobustBufferAccessBehaviorTest.cpp
|
||||
index 08917a2de3385eb853bced1dd576aff46f34f709..db708b0a2a3ce90a370b43786af6884b2f992bef 100644
|
||||
--- a/src/tests/gl_tests/RobustBufferAccessBehaviorTest.cpp
|
||||
+++ b/src/tests/gl_tests/RobustBufferAccessBehaviorTest.cpp
|
||||
@@ -564,6 +564,98 @@ TEST_P(RobustBufferAccessBehaviorTest, DynamicBuffer)
|
||||
}
|
||||
}
|
||||
|
||||
+// Tests out of bounds read by divisor emulation due to a user-provided offset.
|
||||
+// Adapted from https://crbug.com/1285885.
|
||||
+TEST_P(RobustBufferAccessBehaviorTest, IndexOutOfBounds)
|
||||
+{
|
||||
+ ANGLE_SKIP_TEST_IF(!initExtension());
|
||||
+
|
||||
+ constexpr char kVS[] = R"(precision highp float;
|
||||
+attribute vec4 a_position;
|
||||
+void main(void) {
|
||||
+ gl_Position = a_position;
|
||||
+})";
|
||||
+
|
||||
+ constexpr char kFS[] = R"(precision highp float;
|
||||
+uniform sampler2D oTexture;
|
||||
+uniform float oColor[3];
|
||||
+void main(void) {
|
||||
+ gl_FragData[0] = texture2DProj(oTexture, vec3(0.1,0.1,0.1));
|
||||
+})";
|
||||
+
|
||||
+ GLfloat singleFloat = 1.0f;
|
||||
+
|
||||
+ GLBuffer buf;
|
||||
+ glBindBuffer(GL_ARRAY_BUFFER, buf);
|
||||
+ glBufferData(GL_ARRAY_BUFFER, 4, &singleFloat, GL_STATIC_DRAW);
|
||||
+
|
||||
+ ANGLE_GL_PROGRAM(program, kVS, kFS);
|
||||
+ glBindAttribLocation(program, 0, "a_position");
|
||||
+ glLinkProgram(program);
|
||||
+ ASSERT_TRUE(CheckLinkStatusAndReturnProgram(program, true));
|
||||
+
|
||||
+ glEnableVertexAttribArray(0);
|
||||
+
|
||||
+ // Trying to exceed renderer->getMaxVertexAttribDivisor()
|
||||
+ GLuint constexpr kDivisor = 4096;
|
||||
+ glVertexAttribDivisor(0, kDivisor);
|
||||
+
|
||||
+ size_t outOfBoundsOffset = 0x50000000;
|
||||
+ glVertexAttribPointer(0, 1, GL_FLOAT, false, 8, reinterpret_cast<void *>(outOfBoundsOffset));
|
||||
+
|
||||
+ glUseProgram(program);
|
||||
+
|
||||
+ glDrawArrays(GL_TRIANGLES, 0, 32);
|
||||
+
|
||||
+ // No assertions, just checking for crashes.
|
||||
+}
|
||||
+
|
||||
+// Similar to the test above but index is first within bounds then goes out of bounds.
|
||||
+TEST_P(RobustBufferAccessBehaviorTest, IndexGoingOutOfBounds)
|
||||
+{
|
||||
+ ANGLE_SKIP_TEST_IF(!initExtension());
|
||||
+
|
||||
+ constexpr char kVS[] = R"(precision highp float;
|
||||
+attribute vec4 a_position;
|
||||
+void main(void) {
|
||||
+ gl_Position = a_position;
|
||||
+})";
|
||||
+
|
||||
+ constexpr char kFS[] = R"(precision highp float;
|
||||
+uniform sampler2D oTexture;
|
||||
+uniform float oColor[3];
|
||||
+void main(void) {
|
||||
+ gl_FragData[0] = texture2DProj(oTexture, vec3(0.1,0.1,0.1));
|
||||
+})";
|
||||
+
|
||||
+ GLBuffer buf;
|
||||
+ glBindBuffer(GL_ARRAY_BUFFER, buf);
|
||||
+ std::array<GLfloat, 2> buffer = {{0.2f, 0.2f}};
|
||||
+ glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * buffer.size(), buffer.data(), GL_STATIC_DRAW);
|
||||
+
|
||||
+ ANGLE_GL_PROGRAM(program, kVS, kFS);
|
||||
+ glBindAttribLocation(program, 0, "a_position");
|
||||
+ glLinkProgram(program);
|
||||
+ ASSERT_TRUE(CheckLinkStatusAndReturnProgram(program, true));
|
||||
+
|
||||
+ glEnableVertexAttribArray(0);
|
||||
+
|
||||
+ // Trying to exceed renderer->getMaxVertexAttribDivisor()
|
||||
+ GLuint constexpr kDivisor = 4096;
|
||||
+ glVertexAttribDivisor(0, kDivisor);
|
||||
+
|
||||
+ // 6 bytes remaining in the buffer from offset so only a single vertex can be read
|
||||
+ glVertexAttribPointer(0, 1, GL_FLOAT, false, 8, reinterpret_cast<void *>(2));
|
||||
+
|
||||
+ glUseProgram(program);
|
||||
+
|
||||
+ // Each vertex is read `kDivisor` times so the last read goes out of bounds
|
||||
+ GLsizei instanceCount = kDivisor + 1;
|
||||
+ glDrawArraysInstanced(GL_TRIANGLES, 0, 32, instanceCount);
|
||||
+
|
||||
+ // No assertions, just checking for crashes.
|
||||
+}
|
||||
+
|
||||
ANGLE_INSTANTIATE_TEST_ES2_AND_ES3_AND_ES31(RobustBufferAccessBehaviorTest);
|
||||
|
||||
} // namespace
|
||||
@@ -0,0 +1,51 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Charlie Lao <cclao@google.com>
|
||||
Date: Mon, 7 Feb 2022 15:08:15 -0800
|
||||
Subject: M99: Vulkan: StreamVertexDataWithDivisor write beyond buffer boundary
|
||||
|
||||
StreamVertexDataWithDivisor() function is advancing dst with dstStride,
|
||||
but then later on it is treating dst as if it never advanced, thus
|
||||
result in write out of buffer boundary. This was hidden by VMA's memory
|
||||
suballocation, which means it may result in some rendering artifacts.
|
||||
|
||||
Bug: angleproject:6990
|
||||
Change-Id: Ic91e917cedd247dfe85b12a69ae26b21b7a4e67a
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3445528
|
||||
Reviewed-by: Roman Lavrov <romanl@google.com>
|
||||
Reviewed-by: Jamie Madill <jmadill@chromium.org>
|
||||
Commit-Queue: Charlie Lao <cclao@google.com>
|
||||
(cherry picked from commit 5204587698099207ce8ae70779ef44ffae877996)
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3461417
|
||||
Reviewed-by: Charlie Lao <cclao@google.com>
|
||||
Commit-Queue: Roman Lavrov <romanl@google.com>
|
||||
|
||||
diff --git a/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp b/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp
|
||||
index 4e443ed34c29284739fbefb16a38feefed90b726..9043afe17e84737d3e8c295bbc9597fc078f82f9 100644
|
||||
--- a/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp
|
||||
+++ b/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp
|
||||
@@ -122,7 +122,7 @@ angle::Result StreamVertexDataWithDivisor(ContextVk *contextVk,
|
||||
ASSERT(divisor > 0);
|
||||
|
||||
uint32_t sourceVertexUseCount = 0;
|
||||
- for (size_t dataCopied = 0; dataCopied < clampedSize; dataCopied += destStride, dst += destStride)
|
||||
+ for (size_t dataCopied = 0; dataCopied < clampedSize; dataCopied += destStride)
|
||||
{
|
||||
vertexLoadFunction(sourceData, sourceStride, 1, dst);
|
||||
sourceVertexUseCount++;
|
||||
@@ -131,6 +131,7 @@ angle::Result StreamVertexDataWithDivisor(ContextVk *contextVk,
|
||||
sourceData += sourceStride;
|
||||
sourceVertexUseCount = 0;
|
||||
}
|
||||
+ dst += destStride;
|
||||
}
|
||||
|
||||
// Satisfy robustness constraints (only if extension enabled)
|
||||
@@ -138,7 +139,7 @@ angle::Result StreamVertexDataWithDivisor(ContextVk *contextVk,
|
||||
{
|
||||
if (clampedSize < bytesToAllocate)
|
||||
{
|
||||
- memset(dst + clampedSize, 0, bytesToAllocate - clampedSize);
|
||||
+ memset(dst, 0, bytesToAllocate - clampedSize);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Peng Huang <penghuang@chromium.org>
|
||||
Date: Mon, 25 Oct 2021 15:45:36 -0400
|
||||
Subject: VANGLE: change the default vulkan device choose logic
|
||||
|
||||
To match the vulkan device choose logic in chrome, ANGLE will choose
|
||||
the default device based on the order of (discret GPU > integrated GPU
|
||||
> other GPU)
|
||||
|
||||
TODO: for long term, ANGLE should provide a way to let chrome specify
|
||||
the physical device.
|
||||
|
||||
Bug: chromium:1260869
|
||||
Change-Id: Id023138485eb65fcc1d2758103d59a4e6cb2a51d
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3242963
|
||||
Reviewed-by: Geoff Lang <geofflang@chromium.org>
|
||||
Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
|
||||
Commit-Queue: Peng Huang <penghuang@chromium.org>
|
||||
|
||||
diff --git a/src/common/vulkan/vulkan_icd.cpp b/src/common/vulkan/vulkan_icd.cpp
|
||||
index 20da792b2b150c4dd4dffbe4b2b9997f91e921df..ffd19f84a7262d633fa17483fdac6c3ff8f536dd 100644
|
||||
--- a/src/common/vulkan/vulkan_icd.cpp
|
||||
+++ b/src/common/vulkan/vulkan_icd.cpp
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
|
||||
+#include "common/Optional.h"
|
||||
#include "common/bitset_utils.h"
|
||||
#include "common/debug.h"
|
||||
#include "common/system_utils.h"
|
||||
@@ -95,8 +96,7 @@ ICDFilterFunc GetFilterForICD(vk::ICD preferredICD)
|
||||
const std::string anglePreferredDevice =
|
||||
angle::GetEnvironmentVar(kANGLEPreferredDeviceEnv);
|
||||
return [anglePreferredDevice](const VkPhysicalDeviceProperties &deviceProperties) {
|
||||
- return (anglePreferredDevice.empty() ||
|
||||
- anglePreferredDevice == deviceProperties.deviceName);
|
||||
+ return (anglePreferredDevice == deviceProperties.deviceName);
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -269,9 +269,37 @@ void ChoosePhysicalDevice(const std::vector<VkPhysicalDevice> &physicalDevices,
|
||||
return;
|
||||
}
|
||||
}
|
||||
- WARN() << "Preferred device ICD not found. Using default physicalDevice instead.";
|
||||
|
||||
- // Fall back to first device.
|
||||
+ Optional<VkPhysicalDevice> integratedDevice;
|
||||
+ VkPhysicalDeviceProperties integratedDeviceProperties;
|
||||
+ for (const VkPhysicalDevice &physicalDevice : physicalDevices)
|
||||
+ {
|
||||
+ vkGetPhysicalDeviceProperties(physicalDevice, physicalDevicePropertiesOut);
|
||||
+ // If discrete GPU exists, uses it by default.
|
||||
+ if (physicalDevicePropertiesOut->deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU)
|
||||
+ {
|
||||
+ *physicalDeviceOut = physicalDevice;
|
||||
+ return;
|
||||
+ }
|
||||
+ if (physicalDevicePropertiesOut->deviceType == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU &&
|
||||
+ !integratedDevice.valid())
|
||||
+ {
|
||||
+ integratedDevice = physicalDevice;
|
||||
+ integratedDeviceProperties = *physicalDevicePropertiesOut;
|
||||
+ continue;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ // If only integrated GPU exists, use it by default.
|
||||
+ if (integratedDevice.valid())
|
||||
+ {
|
||||
+ *physicalDeviceOut = integratedDevice.value();
|
||||
+ *physicalDevicePropertiesOut = integratedDeviceProperties;
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ WARN() << "Preferred device ICD not found. Using default physicalDevice instead.";
|
||||
+ // Fallback to the first device.
|
||||
*physicalDeviceOut = physicalDevices[0];
|
||||
vkGetPhysicalDeviceProperties(*physicalDeviceOut, physicalDevicePropertiesOut);
|
||||
}
|
||||
@@ -113,3 +113,25 @@ load_v8_snapshot_in_browser_process.patch
|
||||
fix_patch_out_permissions_checks_in_exclusive_access.patch
|
||||
fix_aspect_ratio_with_max_size.patch
|
||||
revert_do_not_display_grammar_error_if_there_it_overlaps_with_spell.patch
|
||||
fix_crash_when_saving_edited_pdf_files.patch
|
||||
m97_unseasoned-pdf_call_pdfviewwebplugin_a11y_methods_asyncly.patch
|
||||
merge_m-97_serial_check_for_detached_buffers_when_writing.patch
|
||||
handle_potentiallydanglingmarkup_for_cssimagevalue.patch
|
||||
use_axnodeid_rather_than_axnode_in_axeventgenerator_tree_events.patch
|
||||
fire_iframe_onload_for_cross-origin-initiated_same-document.patch
|
||||
m97_webcodecs_various_decodertemplate_shutdown_cleanups.patch
|
||||
do_not_select_vulkan_device_based_on_the_passed_in_gpu_info_on_linux.patch
|
||||
cherry-pick-e3805f29fed7.patch
|
||||
cherry-pick-be50c60b4225.patch
|
||||
cherry-pick-0081bb347e67.patch
|
||||
m98_fs_fix_fileutil_lifetime_issue.patch
|
||||
cleanup_pausablecriptexecutor_usage.patch
|
||||
fix_don_t_restore_maximized_windows_when_calling_showinactive.patch
|
||||
cherry-pick-1887414c016d.patch
|
||||
cherry-pick-6b2643846ae3.patch
|
||||
cherry-pick-62142d222a80.patch
|
||||
fix_non-client_mouse_tracking_and_message_bubbling_on_windows.patch
|
||||
cherry-pick-246c10dede97.patch
|
||||
cherry-pick-905302eb3a2b.patch
|
||||
enable_forcesynchronoushtmlparsing_by_default.patch
|
||||
remove_incorrect_width_height_adjustments.patch
|
||||
|
||||
@@ -9,10 +9,10 @@ potentially prevent a window from being created.
|
||||
TODO(loc): this patch is currently broken.
|
||||
|
||||
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc
|
||||
index 193bfd1abc5f9d97f79ded22617f1a9e110175fc..b68c5ee5bd719e15d952a48ff4bc8ef0046e361a 100644
|
||||
index 551e75bc26a88206e8af9868163cd5818ebc33e1..19d944da98817b253117c6436099ab4dc7250edb 100644
|
||||
--- a/content/browser/renderer_host/render_frame_host_impl.cc
|
||||
+++ b/content/browser/renderer_host/render_frame_host_impl.cc
|
||||
@@ -6504,6 +6504,7 @@ void RenderFrameHostImpl::CreateNewWindow(
|
||||
@@ -6505,6 +6505,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,
|
||||
|
||||
26
patches/chromium/cherry-pick-0081bb347e67.patch
Normal file
26
patches/chromium/cherry-pick-0081bb347e67.patch
Normal file
@@ -0,0 +1,26 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Matt Reynolds <mattreynolds@google.com>
|
||||
Date: Wed, 19 Jan 2022 21:03:08 +0000
|
||||
Subject: gamepad: Return an invalid handle after ReportBadMessage
|
||||
|
||||
Bug: 1285449
|
||||
Change-Id: I746c539577f7bdf69cbe4212ac380e0c92a5c771
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3373944
|
||||
Auto-Submit: Matt Reynolds <mattreynolds@chromium.org>
|
||||
Reviewed-by: Reilly Grant <reillyg@chromium.org>
|
||||
Commit-Queue: Reilly Grant <reillyg@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/main@{#961125}
|
||||
|
||||
diff --git a/device/gamepad/gamepad_monitor.cc b/device/gamepad/gamepad_monitor.cc
|
||||
index ce8ba1ef7551e52f8ae4d9a112a08308ab2ce51c..28082924e632a895fc5bc4725bc6de3d6ca120ac 100644
|
||||
--- a/device/gamepad/gamepad_monitor.cc
|
||||
+++ b/device/gamepad/gamepad_monitor.cc
|
||||
@@ -53,6 +53,8 @@ void GamepadMonitor::GamepadStartPolling(GamepadStartPollingCallback callback) {
|
||||
GamepadService* service = GamepadService::GetInstance();
|
||||
if (!service->ConsumerBecameActive(this)) {
|
||||
mojo::ReportBadMessage("GamepadMonitor::GamepadStartPolling failed");
|
||||
+ std::move(callback).Run(base::ReadOnlySharedMemoryRegion());
|
||||
+ return;
|
||||
}
|
||||
std::move(callback).Run(service->DuplicateSharedMemoryRegion());
|
||||
}
|
||||
53
patches/chromium/cherry-pick-1887414c016d.patch
Normal file
53
patches/chromium/cherry-pick-1887414c016d.patch
Normal file
@@ -0,0 +1,53 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Muyao Xu <muyaoxu@google.com>
|
||||
Date: Thu, 17 Feb 2022 16:23:29 +0000
|
||||
Subject: Replace WidgetObserver::OnWidgetClosing() with OnWidgetDestroying()
|
||||
|
||||
In some cases, OnWidgetClosing() is not called when the widget is
|
||||
closed, resulting an invalid pointer |widget_| stored in
|
||||
WebContentsDisplayObserverView.
|
||||
|
||||
This CL replaces OnWidgetClosing() with OnWidgetDestroying(), which
|
||||
is recommended in crbug.com/1240365
|
||||
|
||||
(cherry picked from commit 4535fe2334d0713535adb52b641a8cb34e11333c)
|
||||
|
||||
Bug: 1291728
|
||||
Change-Id: I64fef8b30930f60220008809ee00f4385d6c3520
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3425473
|
||||
Auto-Submit: Muyao Xu <muyaoxu@google.com>
|
||||
Commit-Queue: Takumi Fujimoto <takumif@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#965431}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3435985
|
||||
Reviewed-by: Michael Ershov <miersh@google.com>
|
||||
Owners-Override: Michael Ershov <miersh@google.com>
|
||||
Commit-Queue: Roger Felipe Zanoni da Silva <rzanoni@google.com>
|
||||
Cr-Commit-Position: refs/branch-heads/4664@{#1480}
|
||||
Cr-Branched-From: 24dc4ee75e01a29d390d43c9c264372a169273a7-refs/heads/main@{#929512}
|
||||
|
||||
diff --git a/chrome/browser/ui/views/media_router/web_contents_display_observer_view.cc b/chrome/browser/ui/views/media_router/web_contents_display_observer_view.cc
|
||||
index 80d33b238cd7455ec5b44d5fd966f42f690946bf..2061c2ecb476cd33ed999f180c0293641f7ac23a 100644
|
||||
--- a/chrome/browser/ui/views/media_router/web_contents_display_observer_view.cc
|
||||
+++ b/chrome/browser/ui/views/media_router/web_contents_display_observer_view.cc
|
||||
@@ -65,7 +65,7 @@ void WebContentsDisplayObserverView::OnBrowserSetLastActive(Browser* browser) {
|
||||
}
|
||||
}
|
||||
|
||||
-void WebContentsDisplayObserverView::OnWidgetClosing(views::Widget* widget) {
|
||||
+void WebContentsDisplayObserverView::OnWidgetDestroying(views::Widget* widget) {
|
||||
if (widget_)
|
||||
widget_->RemoveObserver(this);
|
||||
widget_ = nullptr;
|
||||
diff --git a/chrome/browser/ui/views/media_router/web_contents_display_observer_view.h b/chrome/browser/ui/views/media_router/web_contents_display_observer_view.h
|
||||
index 17a8ca48b1c836a82e2be5e5c605bc1837150cba..b63cf4505318a44c65585b06ec13960bad5d9e32 100644
|
||||
--- a/chrome/browser/ui/views/media_router/web_contents_display_observer_view.h
|
||||
+++ b/chrome/browser/ui/views/media_router/web_contents_display_observer_view.h
|
||||
@@ -28,7 +28,7 @@ class WebContentsDisplayObserverView : public WebContentsDisplayObserver,
|
||||
void OnBrowserSetLastActive(Browser* browser) override;
|
||||
|
||||
// views::WidgetObserver overrides:
|
||||
- void OnWidgetClosing(views::Widget* widget) override;
|
||||
+ void OnWidgetDestroying(views::Widget* widget) override;
|
||||
void OnWidgetBoundsChanged(views::Widget* widget,
|
||||
const gfx::Rect& new_bounds) override;
|
||||
|
||||
36
patches/chromium/cherry-pick-246c10dede97.patch
Normal file
36
patches/chromium/cherry-pick-246c10dede97.patch
Normal file
@@ -0,0 +1,36 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Tony Herre <toprice@chromium.org>
|
||||
Date: Fri, 18 Feb 2022 13:52:01 +0000
|
||||
Subject: Switch to new RequestPermissionsFromCurrentDocument API method for
|
||||
Media Stream Devices
|
||||
|
||||
Switch away from the deprecated RequestPermissions() API, as a part of removing a bug where the previously provided request.security_origin param might get destroyed during the method execution.
|
||||
|
||||
(cherry picked from commit cb6778fb965e2b010922f157c68480de863c252e)
|
||||
|
||||
Bug: 1283402
|
||||
Change-Id: I512ce910146ec60d4d35fa1a86a71a3b0983a5d1
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3417436
|
||||
Reviewed-by: Florent Castelli <orphis@chromium.org>
|
||||
Commit-Queue: Tony Herre <toprice@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#964535}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3473365
|
||||
Cr-Commit-Position: refs/branch-heads/4844@{#655}
|
||||
Cr-Branched-From: 007241ce2e6c8e5a7b306cc36c730cd07cd38825-refs/heads/main@{#961656}
|
||||
|
||||
diff --git a/components/webrtc/media_stream_devices_controller.cc b/components/webrtc/media_stream_devices_controller.cc
|
||||
index c818458f413ab2afc439ddabb547659b1def3c5a..9f6829c1520f5bf46981de8c9a8c99fc7b40ad34 100644
|
||||
--- a/components/webrtc/media_stream_devices_controller.cc
|
||||
+++ b/components/webrtc/media_stream_devices_controller.cc
|
||||
@@ -138,9 +138,8 @@ void MediaStreamDevicesController::RequestPermissions(
|
||||
}
|
||||
}
|
||||
|
||||
- permission_manager->RequestPermissions(
|
||||
- content_settings_types, rfh, request.security_origin,
|
||||
- request.user_gesture,
|
||||
+ permission_manager->RequestPermissionsFromCurrentDocument(
|
||||
+ content_settings_types, rfh, request.user_gesture,
|
||||
base::BindOnce(
|
||||
&MediaStreamDevicesController::RequestAndroidPermissionsIfNeeded,
|
||||
web_contents, std::move(controller), will_prompt_for_audio,
|
||||
151
patches/chromium/cherry-pick-62142d222a80.patch
Normal file
151
patches/chromium/cherry-pick-62142d222a80.patch
Normal file
@@ -0,0 +1,151 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Ken Rockot <rockot@google.com>
|
||||
Date: Thu, 24 Feb 2022 15:13:13 +0000
|
||||
Subject: Validate message headers sooner
|
||||
|
||||
M96 merge issues:
|
||||
- multiplex_router.h: conflict in removed lines because of
|
||||
differences in comments above header_validator_
|
||||
- connector.h: conflicting includes
|
||||
|
||||
Message header validation has been tied to interface message dispatch,
|
||||
but not all mojo::Message consumers are interface bindings.
|
||||
|
||||
mojo::Connector is a more general-purpose entry point through which
|
||||
incoming messages are received and transformed into mojo::Message
|
||||
objects. Blink's MessagePort implementation uses Connector directly to
|
||||
transmit and receive raw serialized object data.
|
||||
|
||||
This change moves MessageHeaderValidator ownership into Connector and
|
||||
always applies its validation immediately after reading a message from
|
||||
the pipe, thereby ensuring that all mojo::Message objects used in
|
||||
production have validated headers before use.
|
||||
|
||||
(cherry picked from commit 8d5bc69146505785ce299c490e35e3f3ef19f69c)
|
||||
|
||||
Fixed: 1281908
|
||||
Change-Id: Ie0e251ab04681a4fd4b849d82c247e0ed800dc04
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3462461
|
||||
Commit-Queue: Ken Rockot <rockot@google.com>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#971263}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3483815
|
||||
Reviewed-by: Victor-Gabriel Savu <vsavu@google.com>
|
||||
Owners-Override: Victor-Gabriel Savu <vsavu@google.com>
|
||||
Commit-Queue: Roger Felipe Zanoni da Silva <rzanoni@google.com>
|
||||
Cr-Commit-Position: refs/branch-heads/4664@{#1505}
|
||||
Cr-Branched-From: 24dc4ee75e01a29d390d43c9c264372a169273a7-refs/heads/main@{#929512}
|
||||
|
||||
diff --git a/mojo/public/cpp/bindings/connector.h b/mojo/public/cpp/bindings/connector.h
|
||||
index c788d5adaf4c3fbbd289068e16ff44ef573b44fe..6076d73084daa8f0817097ee31c70e4be50a73a7 100644
|
||||
--- a/mojo/public/cpp/bindings/connector.h
|
||||
+++ b/mojo/public/cpp/bindings/connector.h
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "base/sequenced_task_runner.h"
|
||||
#include "mojo/public/cpp/bindings/connection_group.h"
|
||||
#include "mojo/public/cpp/bindings/message.h"
|
||||
+#include "mojo/public/cpp/bindings/message_header_validator.h"
|
||||
#include "mojo/public/cpp/bindings/sync_handle_watcher.h"
|
||||
#include "mojo/public/cpp/system/core.h"
|
||||
#include "mojo/public/cpp/system/handle_signal_tracker.h"
|
||||
@@ -348,6 +349,8 @@ class COMPONENT_EXPORT(MOJO_CPP_BINDINGS) Connector : public MessageReceiver {
|
||||
// The number of pending tasks for |CallDispatchNextMessageFromPipe|.
|
||||
size_t num_pending_dispatch_tasks_ = 0;
|
||||
|
||||
+ MessageHeaderValidator header_validator_;
|
||||
+
|
||||
#if defined(ENABLE_IPC_FUZZER)
|
||||
std::unique_ptr<MessageReceiver> message_dumper_;
|
||||
#endif
|
||||
diff --git a/mojo/public/cpp/bindings/lib/connector.cc b/mojo/public/cpp/bindings/lib/connector.cc
|
||||
index c1d111c126a4f10af6a4ba6bc78ab1fa5c771853..0af91f3ab069690b041c189bbb5946c1d3d59ddc 100644
|
||||
--- a/mojo/public/cpp/bindings/lib/connector.cc
|
||||
+++ b/mojo/public/cpp/bindings/lib/connector.cc
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "base/rand_util.h"
|
||||
#include "base/run_loop.h"
|
||||
#include "base/strings/strcat.h"
|
||||
+#include "base/strings/string_util.h"
|
||||
#include "base/synchronization/lock.h"
|
||||
#include "base/task/current_thread.h"
|
||||
#include "base/threading/sequence_local_storage_slot.h"
|
||||
@@ -155,7 +156,11 @@ Connector::Connector(ScopedMessagePipeHandle message_pipe,
|
||||
force_immediate_dispatch_(!EnableTaskPerMessage()),
|
||||
outgoing_serialization_mode_(g_default_outgoing_serialization_mode),
|
||||
incoming_serialization_mode_(g_default_incoming_serialization_mode),
|
||||
- interface_name_(interface_name) {
|
||||
+ interface_name_(interface_name),
|
||||
+ header_validator_(
|
||||
+ base::JoinString({interface_name ? interface_name : "Generic",
|
||||
+ "MessageHeaderValidator"},
|
||||
+ "")) {
|
||||
if (config == MULTI_THREADED_SEND)
|
||||
lock_.emplace();
|
||||
|
||||
@@ -495,6 +500,7 @@ MojoResult Connector::ReadMessage(Message* message) {
|
||||
return result;
|
||||
|
||||
*message = Message::CreateFromMessageHandle(&handle);
|
||||
+
|
||||
if (message->IsNull()) {
|
||||
// Even if the read was successful, the Message may still be null if there
|
||||
// was a problem extracting handles from it. We treat this essentially as
|
||||
@@ -510,6 +516,10 @@ MojoResult Connector::ReadMessage(Message* message) {
|
||||
return MOJO_RESULT_ABORTED;
|
||||
}
|
||||
|
||||
+ if (!header_validator_.Accept(message)) {
|
||||
+ return MOJO_RESULT_ABORTED;
|
||||
+ }
|
||||
+
|
||||
return MOJO_RESULT_OK;
|
||||
}
|
||||
|
||||
diff --git a/mojo/public/cpp/bindings/lib/multiplex_router.cc b/mojo/public/cpp/bindings/lib/multiplex_router.cc
|
||||
index e62252a1399731a4ee1bfe47fbfaac0a6a397605..ad7a7000eb96a45741bc811a47cd633ff030d056 100644
|
||||
--- a/mojo/public/cpp/bindings/lib/multiplex_router.cc
|
||||
+++ b/mojo/public/cpp/bindings/lib/multiplex_router.cc
|
||||
@@ -23,7 +23,6 @@
|
||||
#include "mojo/public/cpp/bindings/interface_endpoint_controller.h"
|
||||
#include "mojo/public/cpp/bindings/lib/may_auto_lock.h"
|
||||
#include "mojo/public/cpp/bindings/lib/message_quota_checker.h"
|
||||
-#include "mojo/public/cpp/bindings/message_header_validator.h"
|
||||
#include "mojo/public/cpp/bindings/sequence_local_sync_event_watcher.h"
|
||||
|
||||
namespace mojo {
|
||||
@@ -391,14 +390,7 @@ MultiplexRouter::MultiplexRouter(
|
||||
if (quota_checker)
|
||||
connector_.SetMessageQuotaChecker(std::move(quota_checker));
|
||||
|
||||
- std::unique_ptr<MessageHeaderValidator> header_validator =
|
||||
- std::make_unique<MessageHeaderValidator>();
|
||||
- header_validator_ = header_validator.get();
|
||||
- dispatcher_.SetValidator(std::move(header_validator));
|
||||
-
|
||||
if (primary_interface_name) {
|
||||
- header_validator_->SetDescription(base::JoinString(
|
||||
- {primary_interface_name, "[primary] MessageHeaderValidator"}, " "));
|
||||
control_message_handler_.SetDescription(base::JoinString(
|
||||
{primary_interface_name, "[primary] PipeControlMessageHandler"}, " "));
|
||||
}
|
||||
diff --git a/mojo/public/cpp/bindings/lib/multiplex_router.h b/mojo/public/cpp/bindings/lib/multiplex_router.h
|
||||
index df94c8a6e9dd2d28a7370d6ec9ce98bc9ecc7b8a..c20d1966206819044d10dfb133086b656abfefa6 100644
|
||||
--- a/mojo/public/cpp/bindings/lib/multiplex_router.h
|
||||
+++ b/mojo/public/cpp/bindings/lib/multiplex_router.h
|
||||
@@ -38,7 +38,6 @@ class SequencedTaskRunner;
|
||||
namespace mojo {
|
||||
|
||||
class AsyncFlusher;
|
||||
-class MessageHeaderValidator;
|
||||
class PendingFlush;
|
||||
|
||||
namespace internal {
|
||||
@@ -304,9 +303,6 @@ class COMPONENT_EXPORT(MOJO_CPP_BINDINGS) MultiplexRouter
|
||||
|
||||
scoped_refptr<base::SequencedTaskRunner> task_runner_;
|
||||
|
||||
- // Owned by |dispatcher_| below.
|
||||
- MessageHeaderValidator* header_validator_ = nullptr;
|
||||
-
|
||||
MessageDispatcher dispatcher_;
|
||||
Connector connector_;
|
||||
|
||||
150
patches/chromium/cherry-pick-6b2643846ae3.patch
Normal file
150
patches/chromium/cherry-pick-6b2643846ae3.patch
Normal file
@@ -0,0 +1,150 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Ted Meyer <tmathmeyer@chromium.org>
|
||||
Date: Thu, 24 Feb 2022 17:39:53 +0000
|
||||
Subject: Guard BatchingMediaLog::event_handlers_ with lock
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
It seems that despite MediaLog::OnWebMediaPlayerDestroyed and
|
||||
MediaLog::AddLogRecord both grabbing a lock,
|
||||
BatchingMediaLog::AddLogRecordLocked can escape the lock handle by
|
||||
posting BatchingMediaLog::SendQueuedMediaEvents, causing a race.
|
||||
|
||||
When the addition of an event is interrupted by the deletion of a player
|
||||
due to player culling in MediaInspectorContextImpl, a UAF can occur.
|
||||
|
||||
R=dalecurtis
|
||||
|
||||
(cherry picked from commit 34526c3d0a857a22618e4d77c7f63b5ca6f8d3d2)
|
||||
|
||||
Bug: 1295786
|
||||
Change-Id: I77df94988f806e4d98924669d27860e50455299d
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3451494
|
||||
Commit-Queue: Ted (Chromium) Meyer <tmathmeyer@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#970815}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3483655
|
||||
Reviewed-by: Victor-Gabriel Savu <vsavu@google.com>
|
||||
Owners-Override: Victor-Gabriel Savu <vsavu@google.com>
|
||||
Commit-Queue: Roger Felipe Zanoni da Silva <rzanoni@google.com>
|
||||
Cr-Commit-Position: refs/branch-heads/4664@{#1508}
|
||||
Cr-Branched-From: 24dc4ee75e01a29d390d43c9c264372a169273a7-refs/heads/main@{#929512}
|
||||
|
||||
diff --git a/content/renderer/media/batching_media_log.cc b/content/renderer/media/batching_media_log.cc
|
||||
index 79e6df99f2161da1ef551562c8277d4e02739d91..e2d33781f8c4254595e216202f3c9b3b55377e33 100644
|
||||
--- a/content/renderer/media/batching_media_log.cc
|
||||
+++ b/content/renderer/media/batching_media_log.cc
|
||||
@@ -52,9 +52,9 @@ BatchingMediaLog::BatchingMediaLog(
|
||||
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
|
||||
std::vector<std::unique_ptr<EventHandler>> event_handlers)
|
||||
: task_runner_(std::move(task_runner)),
|
||||
- event_handlers_(std::move(event_handlers)),
|
||||
tick_clock_(base::DefaultTickClock::GetInstance()),
|
||||
last_ipc_send_time_(tick_clock_->NowTicks()),
|
||||
+ event_handlers_(std::move(event_handlers)),
|
||||
ipc_send_pending_(false),
|
||||
logged_rate_limit_warning_(false) {
|
||||
// Pre-bind the WeakPtr on the right thread since we'll receive calls from
|
||||
@@ -76,6 +76,7 @@ BatchingMediaLog::~BatchingMediaLog() {
|
||||
}
|
||||
|
||||
void BatchingMediaLog::OnWebMediaPlayerDestroyedLocked() {
|
||||
+ base::AutoLock lock(lock_);
|
||||
for (const auto& handler : event_handlers_)
|
||||
handler->OnWebMediaPlayerDestroyed();
|
||||
}
|
||||
@@ -198,32 +199,30 @@ std::string BatchingMediaLog::MediaEventToMessageString(
|
||||
|
||||
void BatchingMediaLog::SendQueuedMediaEvents() {
|
||||
DCHECK(task_runner_->BelongsToCurrentThread());
|
||||
+ base::AutoLock auto_lock(lock_);
|
||||
|
||||
- std::vector<media::MediaLogRecord> events_to_send;
|
||||
- {
|
||||
- base::AutoLock auto_lock(lock_);
|
||||
- DCHECK(ipc_send_pending_);
|
||||
- ipc_send_pending_ = false;
|
||||
-
|
||||
- if (last_duration_changed_event_) {
|
||||
- queued_media_events_.push_back(*last_duration_changed_event_);
|
||||
- last_duration_changed_event_.reset();
|
||||
- }
|
||||
+ DCHECK(ipc_send_pending_);
|
||||
+ ipc_send_pending_ = false;
|
||||
|
||||
- if (last_buffering_state_event_) {
|
||||
- queued_media_events_.push_back(*last_buffering_state_event_);
|
||||
- last_buffering_state_event_.reset();
|
||||
- }
|
||||
+ if (last_duration_changed_event_) {
|
||||
+ queued_media_events_.push_back(*last_duration_changed_event_);
|
||||
+ last_duration_changed_event_.reset();
|
||||
+ }
|
||||
|
||||
- queued_media_events_.swap(events_to_send);
|
||||
- last_ipc_send_time_ = tick_clock_->NowTicks();
|
||||
+ if (last_buffering_state_event_) {
|
||||
+ queued_media_events_.push_back(*last_buffering_state_event_);
|
||||
+ last_buffering_state_event_.reset();
|
||||
}
|
||||
|
||||
- if (events_to_send.empty())
|
||||
+ last_ipc_send_time_ = tick_clock_->NowTicks();
|
||||
+
|
||||
+ if (queued_media_events_.empty())
|
||||
return;
|
||||
|
||||
for (const auto& handler : event_handlers_)
|
||||
- handler->SendQueuedMediaEvents(events_to_send);
|
||||
+ handler->SendQueuedMediaEvents(queued_media_events_);
|
||||
+
|
||||
+ queued_media_events_.clear();
|
||||
}
|
||||
|
||||
void BatchingMediaLog::SetTickClockForTesting(
|
||||
diff --git a/content/renderer/media/batching_media_log.h b/content/renderer/media/batching_media_log.h
|
||||
index 6753ebe6605b239bdff84ff7f169cb00ea7d2b64..d3dd09d0c881c4894d0df1b1c6d18c53dcf480b8 100644
|
||||
--- a/content/renderer/media/batching_media_log.h
|
||||
+++ b/content/renderer/media/batching_media_log.h
|
||||
@@ -67,9 +67,6 @@ class CONTENT_EXPORT BatchingMediaLog : public media::MediaLog {
|
||||
|
||||
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
|
||||
|
||||
- // impl for sending queued events.
|
||||
- std::vector<std::unique_ptr<EventHandler>> event_handlers_;
|
||||
-
|
||||
// |lock_| protects access to all of the following member variables. It
|
||||
// allows any render process thread to AddEvent(), while preserving their
|
||||
// sequence for throttled send on |task_runner_| and coherent retrieval by
|
||||
@@ -77,19 +74,24 @@ class CONTENT_EXPORT BatchingMediaLog : public media::MediaLog {
|
||||
// guarantees provided by MediaLog, since SendQueuedMediaEvents must also
|
||||
// be synchronized with respect to AddEvent.
|
||||
mutable base::Lock lock_;
|
||||
- const base::TickClock* tick_clock_;
|
||||
- base::TimeTicks last_ipc_send_time_;
|
||||
- std::vector<media::MediaLogRecord> queued_media_events_;
|
||||
+ const base::TickClock* tick_clock_ GUARDED_BY(lock_);
|
||||
+ base::TimeTicks last_ipc_send_time_ GUARDED_BY(lock_);
|
||||
+ std::vector<media::MediaLogRecord> queued_media_events_ GUARDED_BY(lock_);
|
||||
+
|
||||
+ // impl for sending queued events.
|
||||
+ std::vector<std::unique_ptr<EventHandler>> event_handlers_ GUARDED_BY(lock_);
|
||||
|
||||
// For enforcing max 1 pending send.
|
||||
- bool ipc_send_pending_;
|
||||
+ bool ipc_send_pending_ GUARDED_BY(lock_);
|
||||
|
||||
// True if we've logged a warning message about exceeding rate limits.
|
||||
- bool logged_rate_limit_warning_;
|
||||
+ bool logged_rate_limit_warning_ GUARDED_BY(lock_);
|
||||
|
||||
// Limits the number of events we send over IPC to one.
|
||||
- absl::optional<media::MediaLogRecord> last_duration_changed_event_;
|
||||
- absl::optional<media::MediaLogRecord> last_buffering_state_event_;
|
||||
+ absl::optional<media::MediaLogRecord> last_duration_changed_event_
|
||||
+ GUARDED_BY(lock_);
|
||||
+ absl::optional<media::MediaLogRecord> last_buffering_state_event_
|
||||
+ GUARDED_BY(lock_);
|
||||
|
||||
// Holds the earliest MEDIA_ERROR_LOG_ENTRY event added to this log. This is
|
||||
// most likely to contain the most specific information available describing
|
||||
1863
patches/chromium/cherry-pick-905302eb3a2b.patch
Normal file
1863
patches/chromium/cherry-pick-905302eb3a2b.patch
Normal file
File diff suppressed because it is too large
Load Diff
41
patches/chromium/cherry-pick-be50c60b4225.patch
Normal file
41
patches/chromium/cherry-pick-be50c60b4225.patch
Normal file
@@ -0,0 +1,41 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Ken Rockot <rockot@google.com>
|
||||
Date: Wed, 2 Feb 2022 05:45:44 +0000
|
||||
Subject: Viz: Fix UAF on context loss
|
||||
|
||||
(cherry picked from commit 98d246cabe677e1d8287e4d42ce02825417be9e2)
|
||||
|
||||
Fixed: 1250655
|
||||
Change-Id: I2898316635d370fa36b94e0ae2564ed357745b2c
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3413372
|
||||
Auto-Submit: Ken Rockot <rockot@google.com>
|
||||
Reviewed-by: Kyle Charbonneau <kylechar@chromium.org>
|
||||
Commit-Queue: Kyle Charbonneau <kylechar@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#963012}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3430523
|
||||
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
|
||||
Commit-Queue: Ken Rockot <rockot@google.com>
|
||||
Cr-Commit-Position: refs/branch-heads/4758@{#1050}
|
||||
Cr-Branched-From: 4a2cf4baf90326df19c3ee70ff987960d59a386e-refs/heads/main@{#950365}
|
||||
|
||||
diff --git a/services/viz/public/cpp/gpu/context_provider_command_buffer.cc b/services/viz/public/cpp/gpu/context_provider_command_buffer.cc
|
||||
index a31c10c610000415b5a88a0824eea63b45a435cc..1b323f142d934afea0215dea190efaa197cec554 100644
|
||||
--- a/services/viz/public/cpp/gpu/context_provider_command_buffer.cc
|
||||
+++ b/services/viz/public/cpp/gpu/context_provider_command_buffer.cc
|
||||
@@ -478,9 +478,13 @@ const gpu::GpuFeatureInfo& ContextProviderCommandBuffer::GetGpuFeatureInfo()
|
||||
void ContextProviderCommandBuffer::OnLostContext() {
|
||||
CheckValidThreadOrLockAcquired();
|
||||
|
||||
- // Ensure |this| isn't destroyed in the middle of OnLostContext() if observers
|
||||
- // drop all references to it.
|
||||
- scoped_refptr<ContextProviderCommandBuffer> ref(this);
|
||||
+ // Observers may drop the last persistent references to `this`, but there may
|
||||
+ // be weak references in use further up the stack. This task is posted to
|
||||
+ // ensure that destruction is deferred until it's safe.
|
||||
+ base::SequencedTaskRunnerHandle::Get()->PostTask(
|
||||
+ FROM_HERE,
|
||||
+ base::BindOnce([](scoped_refptr<ContextProviderCommandBuffer>) {},
|
||||
+ base::WrapRefCounted(this)));
|
||||
|
||||
for (auto& observer : observers_)
|
||||
observer.OnContextLost();
|
||||
72
patches/chromium/cherry-pick-e3805f29fed7.patch
Normal file
72
patches/chromium/cherry-pick-e3805f29fed7.patch
Normal file
@@ -0,0 +1,72 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Kevin Ellis <kevers@google.com>
|
||||
Date: Fri, 11 Feb 2022 01:36:04 +0000
|
||||
Subject: Code health cleanup: replacing animations.
|
||||
|
||||
Animation::Update performed a synchronous processing of the finish
|
||||
microtask to ensure that finished events where dispatched ahead of
|
||||
replace events. This step does not align with the spec. Instead we
|
||||
should be queuing the replace event. Microtasks will be processed in
|
||||
the correct order.
|
||||
|
||||
Spec link: https://www.w3.org/TR/web-animations-1/#timelines
|
||||
|
||||
Change-Id: Ibe7753e792fb6cf905bbe6815a080a8cc51c2803
|
||||
|
||||
(cherry picked from commit d4fb69ff0fe343fe8a171014785a88eabfe2b1c2)
|
||||
|
||||
Bug: 1290858
|
||||
Change-Id: Ibe7753e792fb6cf905bbe6815a080a8cc51c2803
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3414765
|
||||
Reviewed-by: Mustaq Ahmed <mustaq@chromium.org>
|
||||
Commit-Queue: Kevin Ellis <kevers@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#964223}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3453925
|
||||
Reviewed-by: Adrian Taylor <adetaylor@google.com>
|
||||
Commit-Queue: Krishna Govind <govind@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/4758@{#1134}
|
||||
Cr-Branched-From: 4a2cf4baf90326df19c3ee70ff987960d59a386e-refs/heads/main@{#950365}
|
||||
|
||||
diff --git a/third_party/blink/renderer/core/animation/animation.cc b/third_party/blink/renderer/core/animation/animation.cc
|
||||
index 943d0594b9c2fdcb10f90e3b4e951b8a809e74f3..734e10902292d7d81884af34b562d18a7802135a 100644
|
||||
--- a/third_party/blink/renderer/core/animation/animation.cc
|
||||
+++ b/third_party/blink/renderer/core/animation/animation.cc
|
||||
@@ -2275,10 +2275,6 @@ bool Animation::Update(TimingUpdateReason reason) {
|
||||
|
||||
if (reason == kTimingUpdateForAnimationFrame) {
|
||||
if (idle || CalculateAnimationPlayState() == kFinished) {
|
||||
- // TODO(crbug.com/1029348): Per spec, we should have a microtask
|
||||
- // checkpoint right after the update cycle. Once this is fixed we should
|
||||
- // no longer need to force a synchronous resolution here.
|
||||
- AsyncFinishMicrotask();
|
||||
finished_ = true;
|
||||
}
|
||||
}
|
||||
diff --git a/third_party/blink/renderer/core/animation/document_animations.cc b/third_party/blink/renderer/core/animation/document_animations.cc
|
||||
index 29217ecb96dbdd342e75145c337c189d85c9bca5..681b30bfdcc30db0d1b8904d327f36582c47a197 100644
|
||||
--- a/third_party/blink/renderer/core/animation/document_animations.cc
|
||||
+++ b/third_party/blink/renderer/core/animation/document_animations.cc
|
||||
@@ -47,6 +47,7 @@
|
||||
#include "third_party/blink/renderer/core/page/page_animator.h"
|
||||
#include "third_party/blink/renderer/core/style/computed_style.h"
|
||||
#include "third_party/blink/renderer/platform/bindings/microtask.h"
|
||||
+#include "third_party/blink/renderer/platform/heap/persistent.h"
|
||||
|
||||
namespace blink {
|
||||
|
||||
@@ -258,10 +259,13 @@ void DocumentAnimations::RemoveReplacedAnimations(
|
||||
|
||||
// The list of animations for removal is constructed in reverse composite
|
||||
// ordering for efficiency. Flip the ordering to ensure that events are
|
||||
- // dispatched in composite order.
|
||||
+ // dispatched in composite order. Queue as a microtask so that the finished
|
||||
+ // event is dispatched ahead of the remove event.
|
||||
for (auto it = animations_to_remove.rbegin();
|
||||
it != animations_to_remove.rend(); it++) {
|
||||
- (*it)->RemoveReplacedAnimation();
|
||||
+ Animation* animation = *it;
|
||||
+ Microtask::EnqueueMicrotask(WTF::Bind(&Animation::RemoveReplacedAnimation,
|
||||
+ WrapWeakPersistent(animation)));
|
||||
}
|
||||
}
|
||||
|
||||
138
patches/chromium/cleanup_pausablecriptexecutor_usage.patch
Normal file
138
patches/chromium/cleanup_pausablecriptexecutor_usage.patch
Normal file
@@ -0,0 +1,138 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Dave Tapuska <dtapuska@chromium.org>
|
||||
Date: Tue, 8 Feb 2022 15:58:40 +0000
|
||||
Subject: Cleanup PausablecriptExecutor usage.
|
||||
|
||||
Improve performance of API so we don't have to go from
|
||||
WTF::String->WebString->WTF::String for execution.
|
||||
|
||||
Ensure the Executor is traced via the PausableScriptExecutor.
|
||||
|
||||
BUG=1289384
|
||||
|
||||
(cherry picked from commit c8231f9a89460fd8336e6c0d8e10347f52f540ec)
|
||||
|
||||
Change-Id: If9badab91222c49c08a983c60132ce71b183e951
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3407654
|
||||
Reviewed-by: Michael Lippautz <mlippautz@chromium.org>
|
||||
Reviewed-by: Daniel Cheng <dcheng@chromium.org>
|
||||
Commit-Queue: Dave Tapuska <dtapuska@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#963010}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3443262
|
||||
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
|
||||
Cr-Commit-Position: refs/branch-heads/4758@{#1109}
|
||||
Cr-Branched-From: 4a2cf4baf90326df19c3ee70ff987960d59a386e-refs/heads/main@{#950365}
|
||||
|
||||
diff --git a/third_party/blink/renderer/core/frame/local_frame_mojo_handler.cc b/third_party/blink/renderer/core/frame/local_frame_mojo_handler.cc
|
||||
index 81fd3960e132305d9d860b01f79d30493530d074..0de7559b3e4d325678d1729c1a7386248eaec63f 100644
|
||||
--- a/third_party/blink/renderer/core/frame/local_frame_mojo_handler.cc
|
||||
+++ b/third_party/blink/renderer/core/frame/local_frame_mojo_handler.cc
|
||||
@@ -213,15 +213,16 @@ v8::MaybeLocal<v8::Value> CallMethodOnFrame(LocalFrame* local_frame,
|
||||
|
||||
// A wrapper class used as the callback for JavaScript executed
|
||||
// in an isolated world.
|
||||
-class JavaScriptIsolatedWorldRequest
|
||||
- : public GarbageCollected<JavaScriptIsolatedWorldRequest>,
|
||||
- public WebScriptExecutionCallback {
|
||||
+class JavaScriptIsolatedWorldRequest : public PausableScriptExecutor::Executor,
|
||||
+ public WebScriptExecutionCallback {
|
||||
using JavaScriptExecuteRequestInIsolatedWorldCallback =
|
||||
mojom::blink::LocalFrame::JavaScriptExecuteRequestInIsolatedWorldCallback;
|
||||
|
||||
public:
|
||||
JavaScriptIsolatedWorldRequest(
|
||||
LocalFrame* local_frame,
|
||||
+ int32_t world_id,
|
||||
+ const String& script,
|
||||
bool wants_result,
|
||||
mojom::blink::LocalFrame::JavaScriptExecuteRequestInIsolatedWorldCallback
|
||||
callback);
|
||||
@@ -231,27 +232,53 @@ class JavaScriptIsolatedWorldRequest
|
||||
const JavaScriptIsolatedWorldRequest&) = delete;
|
||||
~JavaScriptIsolatedWorldRequest() override;
|
||||
|
||||
- // WebScriptExecutionCallback:
|
||||
- void Completed(const WebVector<v8::Local<v8::Value>>& result) override;
|
||||
+ // PausableScriptExecutor::Executor overrides.
|
||||
+ Vector<v8::Local<v8::Value>> Execute(LocalDOMWindow*) override;
|
||||
+
|
||||
+ void Trace(Visitor* visitor) const override;
|
||||
|
||||
- void Trace(Visitor* visitor) const { visitor->Trace(local_frame_); }
|
||||
+ // WebScriptExecutionCallback overrides.
|
||||
+ void Completed(const WebVector<v8::Local<v8::Value>>& result) override;
|
||||
|
||||
private:
|
||||
Member<LocalFrame> local_frame_;
|
||||
+ int32_t world_id_;
|
||||
+ String script_;
|
||||
bool wants_result_;
|
||||
JavaScriptExecuteRequestInIsolatedWorldCallback callback_;
|
||||
};
|
||||
|
||||
JavaScriptIsolatedWorldRequest::JavaScriptIsolatedWorldRequest(
|
||||
LocalFrame* local_frame,
|
||||
+ int32_t world_id,
|
||||
+ const String& script,
|
||||
bool wants_result,
|
||||
JavaScriptExecuteRequestInIsolatedWorldCallback callback)
|
||||
: local_frame_(local_frame),
|
||||
+ world_id_(world_id),
|
||||
+ script_(script),
|
||||
wants_result_(wants_result),
|
||||
- callback_(std::move(callback)) {}
|
||||
+ callback_(std::move(callback)) {
|
||||
+ DCHECK_GT(world_id, DOMWrapperWorld::kMainWorldId);
|
||||
+}
|
||||
|
||||
JavaScriptIsolatedWorldRequest::~JavaScriptIsolatedWorldRequest() = default;
|
||||
|
||||
+void JavaScriptIsolatedWorldRequest::Trace(Visitor* visitor) const {
|
||||
+ PausableScriptExecutor::Executor::Trace(visitor);
|
||||
+ visitor->Trace(local_frame_);
|
||||
+}
|
||||
+
|
||||
+Vector<v8::Local<v8::Value>> JavaScriptIsolatedWorldRequest::Execute(
|
||||
+ LocalDOMWindow* window) {
|
||||
+ // Note: An error event in an isolated world will never be dispatched to
|
||||
+ // a foreign world.
|
||||
+ ClassicScript* classic_script = ClassicScript::CreateUnspecifiedScript(
|
||||
+ script_, SanitizeScriptErrors::kDoNotSanitize);
|
||||
+ return {classic_script->RunScriptInIsolatedWorldAndReturnValue(window,
|
||||
+ world_id_)};
|
||||
+}
|
||||
+
|
||||
void JavaScriptIsolatedWorldRequest::Completed(
|
||||
const WebVector<v8::Local<v8::Value>>& result) {
|
||||
base::Value value;
|
||||
@@ -271,7 +298,6 @@ void JavaScriptIsolatedWorldRequest::Completed(
|
||||
if (new_value)
|
||||
value = base::Value::FromUniquePtrValue(std::move(new_value));
|
||||
}
|
||||
-
|
||||
std::move(callback_).Run(std::move(value));
|
||||
}
|
||||
|
||||
@@ -934,13 +960,16 @@ void LocalFrameMojoHandler::JavaScriptExecuteRequestInIsolatedWorld(
|
||||
v8::HandleScope handle_scope(v8::Isolate::GetCurrent());
|
||||
scoped_refptr<DOMWrapperWorld> isolated_world =
|
||||
DOMWrapperWorld::EnsureIsolatedWorld(ToIsolate(frame_), world_id);
|
||||
- ScriptSourceCode source_code = ScriptSourceCode(javascript);
|
||||
- HeapVector<ScriptSourceCode> sources;
|
||||
- sources.Append(&source_code, 1);
|
||||
- auto* executor = MakeGarbageCollected<PausableScriptExecutor>(
|
||||
- DomWindow(), std::move(isolated_world), sources, false /* user_gesture */,
|
||||
+
|
||||
+ // This member will be traced as the |executor| on the PausableScriptExector.
|
||||
+ auto* execution_request =
|
||||
MakeGarbageCollected<JavaScriptIsolatedWorldRequest>(
|
||||
- frame_, wants_result, std::move(callback)));
|
||||
+ frame_, world_id, javascript, wants_result, std::move(callback));
|
||||
+
|
||||
+ auto* executor = MakeGarbageCollected<PausableScriptExecutor>(
|
||||
+ DomWindow(), ToScriptState(frame_, *isolated_world),
|
||||
+ /*callback=*/execution_request,
|
||||
+ /*executor=*/execution_request);
|
||||
executor->Run();
|
||||
|
||||
script_execution_power_mode_voter_->ResetVoteAfterTimeout(
|
||||
@@ -52,7 +52,7 @@ index 98cc4e039ba2b5a467175b15650a7b8ef38e8249..f5aea6a5916b9aa56ee7b81a8de97dc4
|
||||
const Source& GetSource(int index) const override;
|
||||
DesktopMediaList::Type GetMediaListType() const override;
|
||||
diff --git a/chrome/browser/media/webrtc/native_desktop_media_list.cc b/chrome/browser/media/webrtc/native_desktop_media_list.cc
|
||||
index c899b52ef01d2c9ea16b281a2b7c4d37f175fa36..f752163d4e1951b2f79c7cc1cb4db51c0965472e 100644
|
||||
index c899b52ef01d2c9ea16b281a2b7c4d37f175fa36..5d47550a96e670ce6f0b274e3d683589d8fa3999 100644
|
||||
--- a/chrome/browser/media/webrtc/native_desktop_media_list.cc
|
||||
+++ b/chrome/browser/media/webrtc/native_desktop_media_list.cc
|
||||
@@ -16,7 +16,7 @@
|
||||
@@ -72,7 +72,17 @@ index c899b52ef01d2c9ea16b281a2b7c4d37f175fa36..f752163d4e1951b2f79c7cc1cb4db51c
|
||||
const base::Feature kWindowCaptureMacV2{"WindowCaptureMacV2",
|
||||
base::FEATURE_DISABLED_BY_DEFAULT};
|
||||
#endif
|
||||
@@ -427,6 +428,11 @@ void NativeDesktopMediaList::RefreshForVizFrameSinkWindows(
|
||||
@@ -273,6 +274,9 @@ void NativeDesktopMediaList::Worker::RefreshNextThumbnail() {
|
||||
FROM_HERE,
|
||||
base::BindOnce(&NativeDesktopMediaList::UpdateNativeThumbnailsFinished,
|
||||
media_list_));
|
||||
+
|
||||
+ // This call is necessary to release underlying OS screen capture mechanisms.
|
||||
+ capturer_.reset();
|
||||
}
|
||||
|
||||
void NativeDesktopMediaList::Worker::OnCaptureResult(
|
||||
@@ -427,6 +431,11 @@ void NativeDesktopMediaList::RefreshForVizFrameSinkWindows(
|
||||
FROM_HERE, base::BindOnce(&Worker::RefreshThumbnails,
|
||||
base::Unretained(worker_.get()),
|
||||
std::move(native_ids), thumbnail_size_));
|
||||
|
||||
@@ -34,7 +34,7 @@ index da1bc9c7e01c6eef07b1066976e7487767d716f2..5d123c6c48b299745f7524ea8927043e
|
||||
// |routing_id| must not be MSG_ROUTING_NONE.
|
||||
// If this object outlives |delegate|, DetachDelegate() must be called when
|
||||
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc
|
||||
index 239088813b9fa96e9e9899acee6f02bcb828ecde..7955f2cb725ef4c011bbbce74820d98783d56a0c 100644
|
||||
index c9cbda8362ebdf8594a8234c2ad85cacbb653ead..9505a5bfc0c88762bc00ba26774a906c9115282e 100644
|
||||
--- a/content/browser/renderer_host/render_widget_host_view_aura.cc
|
||||
+++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
|
||||
@@ -611,7 +611,7 @@ void RenderWidgetHostViewAura::HideImpl() {
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Peng Huang <penghuang@chromium.org>
|
||||
Date: Mon, 25 Oct 2021 21:10:55 +0000
|
||||
Subject: Do not select vulkan device based on the passed in gpu_info on Linux
|
||||
|
||||
On linux dual GPU setup, we cannot detect the active GPU correctly.
|
||||
It causes problems for GL and Vulkan interop. So we would to use
|
||||
ANGLE vulkan backend when vulkan is enabled. So we can choose the same
|
||||
GPU for both vulkan and GL. So for this CL, we will not create vulkan
|
||||
device based on passed in gpu_info anymore, instead GPU device will be
|
||||
selected by the order of
|
||||
(discrete GPU > integrated GPU > virtual GPU > CPU simulated GPU).
|
||||
And we will use the same logic in ANGLE vulkan backend as well.
|
||||
|
||||
Bug: 1260869
|
||||
Change-Id: I6fb79a4e6ce1710e4809cd63a0f7738955a8e2d2
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3242785
|
||||
Commit-Queue: Peng Huang <penghuang@chromium.org>
|
||||
Commit-Queue: Vasiliy Telezhnikov <vasilyt@chromium.org>
|
||||
Auto-Submit: Peng Huang <penghuang@chromium.org>
|
||||
Reviewed-by: Vasiliy Telezhnikov <vasilyt@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/main@{#934696}
|
||||
|
||||
diff --git a/gpu/vulkan/vulkan_device_queue.cc b/gpu/vulkan/vulkan_device_queue.cc
|
||||
index e4fe73f613dfe27b2ac6ccd7d31448e0f16ff459..22abed4db134647699d5622c4b92c3a861274f7c 100644
|
||||
--- a/gpu/vulkan/vulkan_device_queue.cc
|
||||
+++ b/gpu/vulkan/vulkan_device_queue.cc
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "base/strings/stringprintf.h"
|
||||
+#include "build/build_config.h"
|
||||
#include "gpu/config/gpu_info.h" // nogncheck
|
||||
#include "gpu/config/vulkan_info.h"
|
||||
#include "gpu/vulkan/vulkan_command_pool.h"
|
||||
@@ -77,11 +78,15 @@ bool VulkanDeviceQueue::Initialize(
|
||||
if (device_properties.apiVersion < info.used_api_version)
|
||||
continue;
|
||||
|
||||
+ // In dual-CPU cases, we cannot detect the active GPU correctly on Linux,
|
||||
+ // so don't select GPU device based on the |gpu_info|.
|
||||
+#if !defined(OS_LINUX)
|
||||
// If gpu_info is provided, the device should match it.
|
||||
if (gpu_info && (device_properties.vendorID != gpu_info->gpu.vendor_id ||
|
||||
device_properties.deviceID != gpu_info->gpu.device_id)) {
|
||||
continue;
|
||||
}
|
||||
+#endif
|
||||
|
||||
if (device_properties.deviceType < 0 ||
|
||||
device_properties.deviceType > VK_PHYSICAL_DEVICE_TYPE_CPU) {
|
||||
@@ -112,7 +117,7 @@ bool VulkanDeviceQueue::Initialize(
|
||||
break;
|
||||
}
|
||||
}
|
||||
-
|
||||
+
|
||||
if (!found)
|
||||
continue;
|
||||
|
||||
@@ -0,0 +1,164 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Mason Freed <masonf@chromium.org>
|
||||
Date: Wed, 15 Dec 2021 01:51:28 +0000
|
||||
Subject: Enable ForceSynchronousHTMLParsing by default
|
||||
|
||||
This feature is enabled at 100% (with 1% stable holdback) on all
|
||||
channels since M96. No unresolved problems have been reported,
|
||||
and overall metrics are improved [1]. This CL enables the
|
||||
ForceSynchronousHTMLParsing feature by default, and removes the
|
||||
LoaderDataPipeTuning feature entirely, replacing it with newly-
|
||||
hard-coded values from the launched experiment.
|
||||
|
||||
[1] https://docs.google.com/document/d/13GewLNZ50nqs0OI7-rzofOXtjuAlD0R4PMLTUsr73dg/edit#heading=h.ctbltu75kgzp
|
||||
|
||||
This part is cool:
|
||||
Fixed: 901056
|
||||
Fixed: 461877
|
||||
Fixed: 761992
|
||||
Fixed: 789124
|
||||
Fixed: 995660
|
||||
Fixed: 1038534
|
||||
Fixed: 1041006
|
||||
Fixed: 1128608
|
||||
Fixed: 1130290
|
||||
Fixed: 1149988
|
||||
Fixed: 1231037
|
||||
-> That's 85 stars worth of bugs, as of 12-13-21.
|
||||
|
||||
Not sure this is "fixed" by this CL, but it should at least address
|
||||
comment #3:
|
||||
Bug: 1087177
|
||||
|
||||
Change-Id: Icbf01ef6665362ae23f28657e5574ca705b82717
|
||||
Cq-Do-Not-Cancel-Tryjobs: true
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2798812
|
||||
Reviewed-by: Nate Chapin <japhet@chromium.org>
|
||||
Reviewed-by: John Abd-El-Malek <jam@chromium.org>
|
||||
Reviewed-by: Kentaro Hara <haraken@chromium.org>
|
||||
Reviewed-by: Yutaka Hirano <yhirano@chromium.org>
|
||||
Commit-Queue: Mason Freed <masonf@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/main@{#951773}
|
||||
|
||||
diff --git a/services/network/public/cpp/features.cc b/services/network/public/cpp/features.cc
|
||||
index d109cac66b5ff947ff04088d023b24e13d73e826..4edc5236373164c1bbceeba54b94c4b448a88bd5 100644
|
||||
--- a/services/network/public/cpp/features.cc
|
||||
+++ b/services/network/public/cpp/features.cc
|
||||
@@ -202,38 +202,41 @@ const base::Feature kSCTAuditingRetryAndPersistReports{
|
||||
// This feature is used for tuning several loading-related data pipe
|
||||
// parameters. See crbug.com/1041006.
|
||||
const base::Feature kLoaderDataPipeTuningFeature{
|
||||
- "LoaderDataPipeTuning", base::FEATURE_DISABLED_BY_DEFAULT};
|
||||
+ "LoaderDataPipeTuning", base::FEATURE_ENABLED_BY_DEFAULT};
|
||||
|
||||
namespace {
|
||||
-// The default buffer size of DataPipe which is used to send the content body.
|
||||
-static constexpr uint32_t kDataPipeDefaultAllocationSize = 512 * 1024;
|
||||
-constexpr base::FeatureParam<int> kDataPipeAllocationSize{
|
||||
- &kLoaderDataPipeTuningFeature, "allocation_size_bytes",
|
||||
- base::saturated_cast<int>(kDataPipeDefaultAllocationSize)};
|
||||
+// The default Mojo ring buffer size, used to send the content body.
|
||||
+static constexpr uint32_t kDefaultDataPipeAllocationSize = 512 * 1024;
|
||||
+// The larger ring buffer size, used primarily for network::URLLoader loads.
|
||||
+// This value was optimized via Finch: see crbug.com/1041006.
|
||||
+static constexpr uint32_t kLargerDataPipeAllocationSize = 2 * 1024 * 1024;
|
||||
|
||||
// The maximal number of bytes consumed in a loading task. When there are more
|
||||
// bytes in the data pipe, they will be consumed in following tasks. Setting too
|
||||
// small of a number will generate many tasks but setting a too large of a
|
||||
-// number will lead to thread janks.
|
||||
-static constexpr uint32_t kMaxNumConsumedBytesInTask = 64 * 1024;
|
||||
-constexpr base::FeatureParam<int> kLoaderChunkSize{
|
||||
- &kLoaderDataPipeTuningFeature, "loader_chunk_size",
|
||||
- base::saturated_cast<int>(kMaxNumConsumedBytesInTask)};
|
||||
+// number will lead to thread janks. This value was optimized via Finch:
|
||||
+// see crbug.com/1041006.
|
||||
+static constexpr uint32_t kDefaultMaxNumConsumedBytesInTask = 64 * 1024;
|
||||
+static constexpr uint32_t kLargerMaxNumConsumedBytesInTask = 1024 * 1024;
|
||||
} // namespace
|
||||
|
||||
// static
|
||||
uint32_t GetDataPipeDefaultAllocationSize(DataPipeAllocationSize option) {
|
||||
if (option == DataPipeAllocationSize::kDefaultSizeOnly)
|
||||
- return kDataPipeDefaultAllocationSize;
|
||||
+ return kDefaultDataPipeAllocationSize;
|
||||
// For low-memory devices, always use the (smaller) default buffer size.
|
||||
if (base::SysInfo::AmountOfPhysicalMemoryMB() <= 512)
|
||||
- return kDataPipeDefaultAllocationSize;
|
||||
- return base::saturated_cast<uint32_t>(kDataPipeAllocationSize.Get());
|
||||
+ return kDefaultDataPipeAllocationSize;
|
||||
+ if (!base::FeatureList::IsEnabled(features::kLoaderDataPipeTuningFeature))
|
||||
+ return kDefaultDataPipeAllocationSize;
|
||||
+ return kLargerDataPipeAllocationSize;
|
||||
}
|
||||
|
||||
// static
|
||||
uint32_t GetLoaderChunkSize() {
|
||||
- return base::saturated_cast<uint32_t>(kLoaderChunkSize.Get());
|
||||
+ if (!base::FeatureList::IsEnabled(features::kLoaderDataPipeTuningFeature))
|
||||
+ return kDefaultMaxNumConsumedBytesInTask;
|
||||
+ return kLargerMaxNumConsumedBytesInTask;
|
||||
}
|
||||
|
||||
// Enable recording UMAs for network activities which can wake-up radio on
|
||||
diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/features.cc
|
||||
index 35effca2b0365524a024a4bc2b352c8e12180d63..abe85d88f622553fdc80309fa410263014e86032 100644
|
||||
--- a/third_party/blink/common/features.cc
|
||||
+++ b/third_party/blink/common/features.cc
|
||||
@@ -110,7 +110,7 @@ const base::Feature kJSONModules{"JSONModules",
|
||||
base::FEATURE_ENABLED_BY_DEFAULT};
|
||||
|
||||
const base::Feature kForceSynchronousHTMLParsing{
|
||||
- "ForceSynchronousHTMLParsing", base::FEATURE_DISABLED_BY_DEFAULT};
|
||||
+ "ForceSynchronousHTMLParsing", base::FEATURE_ENABLED_BY_DEFAULT};
|
||||
|
||||
// Enables top-level await in modules.
|
||||
const base::Feature kTopLevelAwait{"TopLevelAwait",
|
||||
diff --git a/third_party/blink/renderer/platform/loader/fetch/response_body_loader_test.cc b/third_party/blink/renderer/platform/loader/fetch/response_body_loader_test.cc
|
||||
index 88e4a9fdd359dfe63f2b932a7ddd401fc330d6fc..0e59a70e458ebf1a6a8e8c68e3086dde1ac3a55e 100644
|
||||
--- a/third_party/blink/renderer/platform/loader/fetch/response_body_loader_test.cc
|
||||
+++ b/third_party/blink/renderer/platform/loader/fetch/response_body_loader_test.cc
|
||||
@@ -47,15 +47,6 @@ class ResponseBodyLoaderTest : public testing::Test {
|
||||
using PublicState = BytesConsumer::PublicState;
|
||||
using Result = BytesConsumer::Result;
|
||||
|
||||
- static constexpr uint32_t kMaxNumConsumedBytesInTaskForTesting = 512 * 1024;
|
||||
- ResponseBodyLoaderTest() {
|
||||
- base::FieldTrialParams params;
|
||||
- params["loader_chunk_size"] =
|
||||
- base::NumberToString(kMaxNumConsumedBytesInTaskForTesting);
|
||||
- scoped_feature_list_.InitAndEnableFeatureWithParameters(
|
||||
- network::features::kLoaderDataPipeTuningFeature, params);
|
||||
- }
|
||||
-
|
||||
class TestClient final : public GarbageCollected<TestClient>,
|
||||
public ResponseBodyLoaderClient {
|
||||
public:
|
||||
@@ -361,7 +352,7 @@ TEST_F(ResponseBodyLoaderTest, Suspend) {
|
||||
TEST_F(ResponseBodyLoaderTest, ReadTooBigBuffer) {
|
||||
auto task_runner = base::MakeRefCounted<scheduler::FakeTaskRunner>();
|
||||
auto* consumer = MakeGarbageCollected<ReplayingBytesConsumer>(task_runner);
|
||||
- constexpr auto kMax = kMaxNumConsumedBytesInTaskForTesting;
|
||||
+ const uint32_t kMax = network::features::GetLoaderChunkSize();
|
||||
|
||||
consumer->Add(Command(Command::kData, std::string(kMax - 1, 'a').data()));
|
||||
consumer->Add(Command(Command::kData, std::string(2, 'b').data()));
|
||||
diff --git a/third_party/blink/web_tests/platform/fuchsia/external/wpt/html/semantics/interactive-elements/the-details-element/toggleEvent-expected.txt b/third_party/blink/web_tests/platform/fuchsia/external/wpt/html/semantics/interactive-elements/the-details-element/toggleEvent-expected.txt
|
||||
deleted file mode 100644
|
||||
index 5c808aa0a050a4ad866e65445b3fbd7c6807903d..0000000000000000000000000000000000000000
|
||||
--- a/third_party/blink/web_tests/platform/fuchsia/external/wpt/html/semantics/interactive-elements/the-details-element/toggleEvent-expected.txt
|
||||
+++ /dev/null
|
||||
@@ -1,13 +0,0 @@
|
||||
-This is a testharness.js-based test.
|
||||
-PASS Adding open to 'details' should fire a toggle event at the 'details' element
|
||||
-PASS Removing open from 'details' should fire a toggle event at the 'details' element
|
||||
-PASS Adding open to 'details' (display:none) should fire a toggle event at the 'details' element
|
||||
-PASS Adding open from 'details' (no children) should fire a toggle event at the 'details' element
|
||||
-PASS Calling open twice on 'details' fires only one toggle event
|
||||
-PASS Calling setAttribute('open', '') to 'details' should fire a toggle event at the 'details' element
|
||||
-PASS Calling removeAttribute('open') to 'details' should fire a toggle event at the 'details' element
|
||||
-FAIL Setting open=true to opened 'details' element should not fire a toggle event at the 'details' element assert_true: expected true got false
|
||||
-PASS Setting open=false to closed 'details' element should not fire a toggle event at the 'details' element
|
||||
-PASS Adding open to 'details' (not in the document) should fire a toggle event at the 'details' element
|
||||
-Harness: the test ran to completion.
|
||||
-
|
||||
@@ -0,0 +1,191 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Nate Chapin <japhet@chromium.org>
|
||||
Date: Thu, 14 Oct 2021 20:24:32 +0000
|
||||
Subject: Fire iframe onload for cross-origin-initiated same-document
|
||||
navigations
|
||||
|
||||
A cross-origin initiator can check whether or not onload fired to
|
||||
guess the url of a target frame. Always firing onload makes it
|
||||
appear to be a cross-document navigation, even when it wasn't.
|
||||
|
||||
Bug: 1248444
|
||||
Change-Id: I79249cb441f61ac6cab65ab9e5dd4a44b291bc4a
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3193885
|
||||
Commit-Queue: Nate Chapin <japhet@chromium.org>
|
||||
Reviewed-by: Rakina Zata Amni <rakina@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/main@{#931681}
|
||||
|
||||
diff --git a/third_party/blink/renderer/core/loader/document_loader.cc b/third_party/blink/renderer/core/loader/document_loader.cc
|
||||
index aa1b3ca0c8a877f4de5b819bdc52d335e6bc21c0..da83bd3077306c13e9536a61812434a190de6e5f 100644
|
||||
--- a/third_party/blink/renderer/core/loader/document_loader.cc
|
||||
+++ b/third_party/blink/renderer/core/loader/document_loader.cc
|
||||
@@ -1398,7 +1398,25 @@ void DocumentLoader::CommitSameDocumentNavigationInternal(
|
||||
|
||||
initial_scroll_state_.was_scrolled_by_user = false;
|
||||
|
||||
- frame_->GetDocument()->CheckCompleted();
|
||||
+ if (frame_->GetDocument()->LoadEventStillNeeded()) {
|
||||
+ frame_->GetDocument()->CheckCompleted();
|
||||
+ } else if (frame_->Owner() && initiator_origin &&
|
||||
+ !initiator_origin->CanAccess(
|
||||
+ frame_->DomWindow()->GetSecurityOrigin()) &&
|
||||
+ frame_->Tree()
|
||||
+ .Parent()
|
||||
+ ->GetSecurityContext()
|
||||
+ ->GetSecurityOrigin()) {
|
||||
+ // If this same-document navigation was initiated by a cross-origin iframe
|
||||
+ // and is cross-origin to its parent, fire onload on the owner iframe.
|
||||
+ // Normally, the owner iframe's onload fires if and only if the window's
|
||||
+ // onload fires (i.e., when a navigation to a different document completes).
|
||||
+ // However, a cross-origin initiator can use the presence or absence of a
|
||||
+ // load event to detect whether the navigation was same- or cross-document,
|
||||
+ // and can therefore try to guess the url of a cross-origin iframe. Fire the
|
||||
+ // iframe's onload to prevent this technique. https://crbug.com/1251790
|
||||
+ frame_->Owner()->DispatchLoad();
|
||||
+ }
|
||||
|
||||
// If the item sequence number didn't change, there's no need to trigger
|
||||
// popstate, restore scroll positions, or scroll to fragments for this
|
||||
diff --git a/third_party/blink/web_tests/http/tests/navigation/cross-origin-fragment-navigation-is-async-expected.txt b/third_party/blink/web_tests/http/tests/navigation/cross-origin-fragment-navigation-is-async-expected.txt
|
||||
index 850c54970953c62eae282e177949f9082f22a03c..09122d9c3f39f042116d197276420cc1841c5ea8 100644
|
||||
--- a/third_party/blink/web_tests/http/tests/navigation/cross-origin-fragment-navigation-is-async-expected.txt
|
||||
+++ b/third_party/blink/web_tests/http/tests/navigation/cross-origin-fragment-navigation-is-async-expected.txt
|
||||
@@ -1,4 +1,6 @@
|
||||
+ALERT: iframe onload fired
|
||||
ALERT: PASS: url fragment is changing asynchronously
|
||||
ALERT: PASS: scheduled postMessage() before hashchange triggered.
|
||||
+ALERT: iframe onload fired
|
||||
ALERT: PASS: hashchange triggered after postMessage().
|
||||
-This tests that cross-origin fragment navigations are asynchronous. It does so by scheduling a postMessage before scheduling the navigation. If the navigation is synchronous, the internals API will be able to report the presence of an url fragment immediately.
|
||||
+This tests that cross-origin-initiated fragment navigations are asynchronous and always fire the load event at their embedding iframe element if it's cross-origin. It does so by scheduling a postMessage before scheduling the navigation. If the navigation is synchronous, the internals API will be able to report the presence of an url fragment immediately.
|
||||
diff --git a/third_party/blink/web_tests/http/tests/navigation/cross-origin-fragment-navigation-is-async.html b/third_party/blink/web_tests/http/tests/navigation/cross-origin-fragment-navigation-is-async.html
|
||||
index 3d74de086c1a7f8a5fedff72d7c6bb970fca57ed..a1fc3bc87ccd2319f2dff3c5d8729a1a62875ec8 100644
|
||||
--- a/third_party/blink/web_tests/http/tests/navigation/cross-origin-fragment-navigation-is-async.html
|
||||
+++ b/third_party/blink/web_tests/http/tests/navigation/cross-origin-fragment-navigation-is-async.html
|
||||
@@ -1,48 +1,51 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
-<head>
|
||||
- <script>
|
||||
- if (window.testRunner) {
|
||||
- testRunner.dumpAsText();
|
||||
- testRunner.waitUntilDone();
|
||||
- }
|
||||
+<body>
|
||||
+<script>
|
||||
+if (window.testRunner) {
|
||||
+ testRunner.dumpAsText();
|
||||
+ testRunner.waitUntilDone();
|
||||
+}
|
||||
|
||||
- function testFragmentNavigation() {
|
||||
- window.postMessage("postmessage", "*");
|
||||
- document.querySelector('iframe').src = "http://localhost:8000/navigation/resources/postmessage-on-hashchange.html#anchor1";
|
||||
- if (window.internals) {
|
||||
- if (internals.doesWindowHaveUrlFragment(document.querySelector('iframe').contentWindow))
|
||||
- alert("FAIL: url fragment should change asynchronously");
|
||||
- else
|
||||
- alert("PASS: url fragment is changing asynchronously");
|
||||
- }
|
||||
- }
|
||||
+window.onload = function() {
|
||||
+ window.postMessage("postmessage", "*");
|
||||
+ document.querySelector('iframe').src = "http://localhost:8000/navigation/resources/postmessage-on-hashchange.html#anchor1";
|
||||
+ if (window.internals) {
|
||||
+ if (internals.doesWindowHaveUrlFragment(document.querySelector('iframe').contentWindow))
|
||||
+ alert("FAIL: url fragment should change asynchronously");
|
||||
+ else
|
||||
+ alert("PASS: url fragment is changing asynchronously");
|
||||
+ }
|
||||
+}
|
||||
|
||||
- var receivedScheduledPostMessage = false;
|
||||
- var receivedHashchangeMessage = false;
|
||||
- window.addEventListener('message', function (e) {
|
||||
- if (e.data === 'postmessage') {
|
||||
- receivedScheduledPostMessage = true;
|
||||
- if (receivedHashchangeMessage)
|
||||
- alert('FAIL: hashchange already triggered!');
|
||||
- else
|
||||
- alert('PASS: scheduled postMessage() before hashchange triggered.');
|
||||
- } else {
|
||||
- receivedHashchangeMessage = true;
|
||||
- if (receivedScheduledPostMessage)
|
||||
- alert('PASS: hashchange triggered after postMessage().');
|
||||
- else
|
||||
- alert('FAIL: hashchange triggered before postMessage().');
|
||||
- testRunner.notifyDone();
|
||||
- }
|
||||
- });
|
||||
- </script>
|
||||
-</head>
|
||||
-<body>
|
||||
- <p>This tests that cross-origin fragment navigations are asynchronous. It does
|
||||
- so by scheduling a postMessage before scheduling the navigation. If the
|
||||
- navigation is synchronous, the internals API will be able to report the presence
|
||||
- of an url fragment immediately.</p>
|
||||
- <iframe src="http://localhost:8000/navigation/resources/postmessage-on-hashchange.html" onload='testFragmentNavigation()'></iframe>
|
||||
+var receivedScheduledPostMessage = false;
|
||||
+var receivedHashchangeMessage = false;
|
||||
+window.addEventListener('message', function (e) {
|
||||
+ if (e.data === 'postmessage') {
|
||||
+ receivedScheduledPostMessage = true;
|
||||
+ if (receivedHashchangeMessage)
|
||||
+ alert('FAIL: hashchange already triggered!');
|
||||
+ else
|
||||
+ alert('PASS: scheduled postMessage() before hashchange triggered.');
|
||||
+ } else {
|
||||
+ receivedHashchangeMessage = true;
|
||||
+ if (receivedScheduledPostMessage)
|
||||
+ alert('PASS: hashchange triggered after postMessage().');
|
||||
+ else
|
||||
+ alert('FAIL: hashchange triggered before postMessage().');
|
||||
+ testRunner.notifyDone();
|
||||
+ }
|
||||
+});
|
||||
+
|
||||
+function onloadFired() {
|
||||
+ alert("iframe onload fired");
|
||||
+}
|
||||
+</script>
|
||||
+<p>This tests that cross-origin-initiated fragment navigations are asynchronous
|
||||
+and always fire the load event at their embedding iframe element if it's cross-origin. It does
|
||||
+so by scheduling a postMessage before scheduling the navigation. If the
|
||||
+navigation is synchronous, the internals API will be able to report the presence
|
||||
+of an url fragment immediately.</p>
|
||||
+<iframe src="http://localhost:8000/navigation/resources/postmessage-on-hashchange.html" onload="onloadFired()"></iframe>
|
||||
</body>
|
||||
</html>
|
||||
diff --git a/third_party/blink/web_tests/http/tests/navigation/same-origin-fragment-navigation-is-sync-expected.txt b/third_party/blink/web_tests/http/tests/navigation/same-origin-fragment-navigation-is-sync-expected.txt
|
||||
index c1c1143026cad5cfe51829a8c34d61c01a63ffbf..5a6ccc855e14417df8039f18dba7aa0474ff552d 100644
|
||||
--- a/third_party/blink/web_tests/http/tests/navigation/same-origin-fragment-navigation-is-sync-expected.txt
|
||||
+++ b/third_party/blink/web_tests/http/tests/navigation/same-origin-fragment-navigation-is-sync-expected.txt
|
||||
@@ -1,3 +1,4 @@
|
||||
+ALERT: iframe onload fired
|
||||
ALERT: PASS: url fragment has changed synchronously
|
||||
ALERT: PASS: scheduled postMessage() before hashchange triggered.
|
||||
ALERT: PASS: hashchange triggered after postMessage().
|
||||
diff --git a/third_party/blink/web_tests/http/tests/navigation/same-origin-fragment-navigation-is-sync.html b/third_party/blink/web_tests/http/tests/navigation/same-origin-fragment-navigation-is-sync.html
|
||||
index 0ffe3cc8759e8e0ff4df7cad66c93cd5e2cbbe69..2cb9143bfce9a28d8803b49cf6afa7403554cdf4 100644
|
||||
--- a/third_party/blink/web_tests/http/tests/navigation/same-origin-fragment-navigation-is-sync.html
|
||||
+++ b/third_party/blink/web_tests/http/tests/navigation/same-origin-fragment-navigation-is-sync.html
|
||||
@@ -36,6 +36,11 @@
|
||||
testRunner.notifyDone();
|
||||
}
|
||||
});
|
||||
+
|
||||
+ function onloadFired() {
|
||||
+ alert("iframe onload fired");
|
||||
+ testFragmentNavigation();
|
||||
+ }
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
@@ -43,6 +48,6 @@
|
||||
so by scheduling a postMessage before scheduling the navigation. If the
|
||||
navigation is synchronous, the internals API will be able to report the presence
|
||||
of an url fragment immediately.</p>
|
||||
- <iframe src="http://127.0.0.1:8000/navigation/resources/postmessage-on-hashchange.html" onload='testFragmentNavigation()'></iframe>
|
||||
+ <iframe src="http://127.0.0.1:8000/navigation/resources/postmessage-on-hashchange.html" onload='onloadFired()'></iframe>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,85 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shelley Vohr <shelley.vohr@gmail.com>
|
||||
Date: Mon, 17 Jan 2022 23:47:54 +0100
|
||||
Subject: fix: crash when saving edited PDF files
|
||||
|
||||
This commit fixes a crash that persists any time a user attempts to
|
||||
download an edited PDF. This was happening because the logic flow for
|
||||
downloading of any edited PDF triggers a call to
|
||||
chrome.fileSystem.chooseEntry, which we do not support and which
|
||||
therefore causes unmapped page access crashes.
|
||||
|
||||
This patch can be removed should we choose to support chrome.fileSystem
|
||||
or support it enough to fix the crash.
|
||||
|
||||
diff --git a/chrome/browser/resources/pdf/pdf_viewer.js b/chrome/browser/resources/pdf/pdf_viewer.js
|
||||
index 64308b73b70940187451f0475e4717def9f89cce..1888061bb7a5a6ae778d701aa554191288f20c87 100644
|
||||
--- a/chrome/browser/resources/pdf/pdf_viewer.js
|
||||
+++ b/chrome/browser/resources/pdf/pdf_viewer.js
|
||||
@@ -976,25 +976,12 @@ export class PDFViewerElement extends PDFViewerBaseElement {
|
||||
dataArray = [result.dataToSave];
|
||||
}
|
||||
|
||||
+ const a = document.createElement('a');
|
||||
+ a.download = this.attachments_[index].name;
|
||||
const blob = new Blob(dataArray);
|
||||
- const fileName = this.attachments_[index].name;
|
||||
- chrome.fileSystem.chooseEntry(
|
||||
- {type: 'saveFile', suggestedName: fileName}, entry => {
|
||||
- if (chrome.runtime.lastError) {
|
||||
- if (chrome.runtime.lastError.message !== 'User cancelled') {
|
||||
- console.error(
|
||||
- 'chrome.fileSystem.chooseEntry failed: ' +
|
||||
- chrome.runtime.lastError.message);
|
||||
- }
|
||||
- return;
|
||||
- }
|
||||
- entry.createWriter(writer => {
|
||||
- writer.write(blob);
|
||||
- // Unblock closing the window now that the user has saved
|
||||
- // successfully.
|
||||
- chrome.mimeHandlerPrivate.setShowBeforeUnloadDialog(false);
|
||||
- });
|
||||
- });
|
||||
+ a.href = URL.createObjectURL(blob);
|
||||
+ a.click();
|
||||
+ URL.revokeObjectURL(a.href);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1122,29 +1109,12 @@ export class PDFViewerElement extends PDFViewerBaseElement {
|
||||
fileName = fileName + '.pdf';
|
||||
}
|
||||
|
||||
- chrome.fileSystem.chooseEntry(
|
||||
- {
|
||||
- type: 'saveFile',
|
||||
- accepts: [{description: '*.pdf', extensions: ['pdf']}],
|
||||
- suggestedName: fileName
|
||||
- },
|
||||
- entry => {
|
||||
- if (chrome.runtime.lastError) {
|
||||
- if (chrome.runtime.lastError.message !== 'User cancelled') {
|
||||
- console.error(
|
||||
- 'chrome.fileSystem.chooseEntry failed: ' +
|
||||
- chrome.runtime.lastError.message);
|
||||
- }
|
||||
- return;
|
||||
- }
|
||||
- entry.createWriter(writer => {
|
||||
- writer.write(
|
||||
- new Blob([result.dataToSave], {type: 'application/pdf'}));
|
||||
- // Unblock closing the window now that the user has saved
|
||||
- // successfully.
|
||||
- chrome.mimeHandlerPrivate.setShowBeforeUnloadDialog(false);
|
||||
- });
|
||||
- });
|
||||
+ const a = document.createElement('a');
|
||||
+ a.download = fileName;
|
||||
+ const blob = new Blob([result.dataToSave], {type: 'application/pdf'});
|
||||
+ a.href = URL.createObjectURL(blob);
|
||||
+ a.click();
|
||||
+ URL.revokeObjectURL(a.href);
|
||||
|
||||
// <if expr="enable_ink">
|
||||
// Saving in Annotation mode is destructive: crbug.com/919364
|
||||
@@ -0,0 +1,42 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: David Sanders <dsanders11@ucsbalum.com>
|
||||
Date: Fri, 11 Feb 2022 22:37:39 +0000
|
||||
Subject: fix: don't restore maximized windows when calling ShowInactive
|
||||
|
||||
This is a backport from Chromium of
|
||||
https://chromium-review.googlesource.com/c/chromium/src/+/3371573.
|
||||
|
||||
diff --git a/ui/views/win/hwnd_message_handler.cc b/ui/views/win/hwnd_message_handler.cc
|
||||
index f7c1232b0893c366aeeb77e6df0bbd275b6f7bd4..ef01843018cfada041330c3ed75d9d55c3225049 100644
|
||||
--- a/ui/views/win/hwnd_message_handler.cc
|
||||
+++ b/ui/views/win/hwnd_message_handler.cc
|
||||
@@ -664,9 +664,16 @@ void HWNDMessageHandler::Show(ui::WindowShowState show_state,
|
||||
SetWindowPlacement(hwnd(), &placement);
|
||||
native_show_state = SW_SHOWMAXIMIZED;
|
||||
} else {
|
||||
+ const bool is_maximized = IsMaximized();
|
||||
+
|
||||
+ // Use SW_SHOW/SW_SHOWNA instead of SW_SHOWNORMAL/SW_SHOWNOACTIVATE so that
|
||||
+ // the window is not restored to its original position if it is maximized.
|
||||
+ // This could be used unconditionally for ui::SHOW_STATE_INACTIVE, but
|
||||
+ // cross-platform behavior when showing a minimized window is inconsistent,
|
||||
+ // some platforms restore the position, some do not. See crbug.com/1296710
|
||||
switch (show_state) {
|
||||
case ui::SHOW_STATE_INACTIVE:
|
||||
- native_show_state = SW_SHOWNOACTIVATE;
|
||||
+ native_show_state = is_maximized ? SW_SHOWNA : SW_SHOWNOACTIVATE;
|
||||
break;
|
||||
case ui::SHOW_STATE_MAXIMIZED:
|
||||
native_show_state = SW_SHOWMAXIMIZED;
|
||||
@@ -677,9 +684,9 @@ void HWNDMessageHandler::Show(ui::WindowShowState show_state,
|
||||
case ui::SHOW_STATE_NORMAL:
|
||||
if ((GetWindowLong(hwnd(), GWL_EXSTYLE) & WS_EX_TRANSPARENT) ||
|
||||
(GetWindowLong(hwnd(), GWL_EXSTYLE) & WS_EX_NOACTIVATE)) {
|
||||
- native_show_state = SW_SHOWNOACTIVATE;
|
||||
+ native_show_state = is_maximized ? SW_SHOWNA : SW_SHOWNOACTIVATE;
|
||||
} else {
|
||||
- native_show_state = SW_SHOWNORMAL;
|
||||
+ native_show_state = is_maximized ? SW_SHOW : SW_SHOWNORMAL;
|
||||
}
|
||||
break;
|
||||
case ui::SHOW_STATE_FULLSCREEN:
|
||||
@@ -0,0 +1,61 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: clavin <cwatford@slack-corp.com>
|
||||
Date: Fri, 11 Feb 2022 15:05:42 -0700
|
||||
Subject: fix: non-client mouse tracking and message bubbling on windows
|
||||
|
||||
It is not known why, but for some reason calling |DefWindowProc| on the parent
|
||||
window handle causes a WM_NCMOUSELEAVE (non-client mouse exit) message to be
|
||||
sent to the parent window, even though |TrackMouseEvent| is never called on it.
|
||||
|
||||
This patch also adds some boilerplate for properly tracking non-client mouse
|
||||
messages in the legacy window handle layer.
|
||||
|
||||
These conditions are regularly hit with WCO-enabled windows on Windows.
|
||||
|
||||
diff --git a/content/browser/renderer_host/legacy_render_widget_host_win.cc b/content/browser/renderer_host/legacy_render_widget_host_win.cc
|
||||
index 4a894ef70eeb1d8489049aef552c9bae4f24ae62..f5049d730a850f2947023f976b25fb772e42107a 100644
|
||||
--- a/content/browser/renderer_host/legacy_render_widget_host_win.cc
|
||||
+++ b/content/browser/renderer_host/legacy_render_widget_host_win.cc
|
||||
@@ -288,12 +288,12 @@ LRESULT LegacyRenderWidgetHostHWND::OnMouseRange(UINT message,
|
||||
WPARAM w_param,
|
||||
LPARAM l_param,
|
||||
BOOL& handled) {
|
||||
- if (message == WM_MOUSEMOVE) {
|
||||
+ if (message == WM_MOUSEMOVE || message == WM_NCMOUSEMOVE) {
|
||||
if (!mouse_tracking_enabled_) {
|
||||
mouse_tracking_enabled_ = true;
|
||||
TRACKMOUSEEVENT tme;
|
||||
tme.cbSize = sizeof(tme);
|
||||
- tme.dwFlags = TME_LEAVE;
|
||||
+ tme.dwFlags = message == WM_NCMOUSEMOVE ? TME_NONCLIENT | TME_LEAVE : TME_LEAVE;
|
||||
tme.hwndTrack = hwnd();
|
||||
tme.dwHoverTime = 0;
|
||||
TrackMouseEvent(&tme);
|
||||
@@ -319,12 +319,11 @@ LRESULT LegacyRenderWidgetHostHWND::OnMouseRange(UINT message,
|
||||
message, w_param, l_param, &msg_handled);
|
||||
handled = msg_handled;
|
||||
// If the parent did not handle non client mouse messages, we call
|
||||
- // DefWindowProc on the message with the parent window handle. This
|
||||
- // ensures that WM_SYSCOMMAND is generated for the parent and we are
|
||||
- // out of the picture.
|
||||
+ // DefWindowProc on the message. This ensures that WM_SYSCOMMAND is
|
||||
+ // generated.
|
||||
if (!handled &&
|
||||
(message >= WM_NCMOUSEMOVE && message <= WM_NCXBUTTONDBLCLK)) {
|
||||
- ret = ::DefWindowProc(GetParent(), message, w_param, l_param);
|
||||
+ ret = ::DefWindowProc(hwnd(), message, w_param, l_param);
|
||||
handled = TRUE;
|
||||
}
|
||||
}
|
||||
diff --git a/content/browser/renderer_host/legacy_render_widget_host_win.h b/content/browser/renderer_host/legacy_render_widget_host_win.h
|
||||
index 026e8b93602766e8d8e4a04f467b68ce3cea92de..83ca674adb6c6bf5e16d38b12aa33dddbf685bd8 100644
|
||||
--- a/content/browser/renderer_host/legacy_render_widget_host_win.h
|
||||
+++ b/content/browser/renderer_host/legacy_render_widget_host_win.h
|
||||
@@ -100,6 +100,7 @@ class CONTENT_EXPORT LegacyRenderWidgetHostHWND
|
||||
MESSAGE_HANDLER_EX(WM_NCHITTEST, OnNCHitTest)
|
||||
MESSAGE_RANGE_HANDLER(WM_NCMOUSEMOVE, WM_NCXBUTTONDBLCLK,
|
||||
OnMouseRange)
|
||||
+ MESSAGE_HANDLER_EX(WM_NCMOUSELEAVE, OnMouseLeave)
|
||||
MESSAGE_HANDLER_EX(WM_NCCALCSIZE, OnNCCalcSize)
|
||||
MESSAGE_HANDLER_EX(WM_SIZE, OnSize)
|
||||
MESSAGE_HANDLER_EX(WM_DESTROY, OnDestroy)
|
||||
@@ -0,0 +1,135 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Rune Lillesveen <futhark@chromium.org>
|
||||
Date: Fri, 15 Oct 2021 14:33:17 +0000
|
||||
Subject: Handle PotentiallyDanglingMarkup() for CSSImageValue
|
||||
|
||||
The flag was lost in the KURL -> String -> KURL conversions. Store the
|
||||
flag on CSSImageValue and always re-resolve from the original relative
|
||||
url before fetching when that flag is set. The blocking happens in
|
||||
BaseFetchContext::CanRequestInternal().
|
||||
|
||||
Bug: 1039885
|
||||
Change-Id: Ia5777739a0ee0bee591163873926d19e0ea014bf
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3226142
|
||||
Reviewed-by: Anders Hartvoll Ruud <andruud@chromium.org>
|
||||
Reviewed-by: Mike West <mkwst@chromium.org>
|
||||
Commit-Queue: Rune Lillesveen <futhark@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/main@{#932004}
|
||||
|
||||
diff --git a/third_party/blink/renderer/core/css/build.gni b/third_party/blink/renderer/core/css/build.gni
|
||||
index 58b924f732185d95efe6a9438d1f34aebcab377c..3ea66ffca1dd4a0b86c6951ba8e3b2b03139e0c4 100644
|
||||
--- a/third_party/blink/renderer/core/css/build.gni
|
||||
+++ b/third_party/blink/renderer/core/css/build.gni
|
||||
@@ -645,6 +645,7 @@ blink_core_tests_css = [
|
||||
"css_font_family_webkit_prefix_test.cc",
|
||||
"css_gradient_value_test.cc",
|
||||
"css_id_selector_value_test.cc",
|
||||
+ "css_image_value_test.cc",
|
||||
"css_invalid_variable_value_test.cc",
|
||||
"css_light_dark_value_pair_test.cc",
|
||||
"css_math_expression_node_test.cc",
|
||||
diff --git a/third_party/blink/renderer/core/css/css_image_value.cc b/third_party/blink/renderer/core/css/css_image_value.cc
|
||||
index 81fe3aa1175a31d5c6f3611ec6bd2a27f71e900d..732b48f787d782779e5fea8bf60a55ca3f7fe95d 100644
|
||||
--- a/third_party/blink/renderer/core/css/css_image_value.cc
|
||||
+++ b/third_party/blink/renderer/core/css/css_image_value.cc
|
||||
@@ -51,7 +51,8 @@ CSSImageValue::CSSImageValue(const AtomicString& raw_value,
|
||||
absolute_url_(url.GetString()),
|
||||
cached_image_(image),
|
||||
origin_clean_(origin_clean),
|
||||
- is_ad_related_(is_ad_related) {}
|
||||
+ is_ad_related_(is_ad_related),
|
||||
+ potentially_dangling_markup_(url.PotentiallyDanglingMarkup()) {}
|
||||
|
||||
CSSImageValue::~CSSImageValue() = default;
|
||||
|
||||
@@ -59,7 +60,17 @@ FetchParameters CSSImageValue::PrepareFetch(
|
||||
const Document& document,
|
||||
FetchParameters::ImageRequestBehavior image_request_behavior,
|
||||
CrossOriginAttributeValue cross_origin) const {
|
||||
- ResourceRequest resource_request(absolute_url_);
|
||||
+ // The PotentiallyDanglingMarkup() flag is lost when storing the absolute url
|
||||
+ // as a string from which the KURL is constructed here.
|
||||
+ // The url passed into the constructor had the PotentiallyDanglingMarkup flag
|
||||
+ // set. That information needs to be passed on to the fetch code to block such
|
||||
+ // resources from loading.
|
||||
+ KURL request_url = potentially_dangling_markup_
|
||||
+ ? document.CompleteURL(relative_url_)
|
||||
+ : KURL(absolute_url_);
|
||||
+ SECURITY_CHECK(request_url.PotentiallyDanglingMarkup() ==
|
||||
+ potentially_dangling_markup_);
|
||||
+ ResourceRequest resource_request(request_url);
|
||||
resource_request.SetReferrerPolicy(
|
||||
ReferrerUtils::MojoReferrerPolicyResolveDefault(
|
||||
referrer_.referrer_policy));
|
||||
diff --git a/third_party/blink/renderer/core/css/css_image_value.h b/third_party/blink/renderer/core/css/css_image_value.h
|
||||
index fca1d73c764412d2014bfd1fe4775937794c9e2d..f414195f4a543fb3f47c1fef3799161d13495507 100644
|
||||
--- a/third_party/blink/renderer/core/css/css_image_value.h
|
||||
+++ b/third_party/blink/renderer/core/css/css_image_value.h
|
||||
@@ -102,6 +102,11 @@ class CORE_EXPORT CSSImageValue : public CSSValue {
|
||||
|
||||
// Whether this was created by an ad-related CSSParserContext.
|
||||
const bool is_ad_related_;
|
||||
+
|
||||
+ // The url passed into the constructor had the PotentiallyDanglingMarkup flag
|
||||
+ // set. That information needs to be passed on to the fetch code to block such
|
||||
+ // resources from loading.
|
||||
+ const bool potentially_dangling_markup_;
|
||||
};
|
||||
|
||||
template <>
|
||||
diff --git a/third_party/blink/renderer/core/css/css_image_value_test.cc b/third_party/blink/renderer/core/css/css_image_value_test.cc
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..83415bd586e3187287dcb020ddafe4c7f8671a61
|
||||
--- /dev/null
|
||||
+++ b/third_party/blink/renderer/core/css/css_image_value_test.cc
|
||||
@@ -0,0 +1,50 @@
|
||||
+// Copyright 2021 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 "third_party/blink/renderer/core/css/css_image_value.h"
|
||||
+
|
||||
+#include "testing/gtest/include/gtest/gtest.h"
|
||||
+#include "third_party/blink/renderer/core/dom/document.h"
|
||||
+#include "third_party/blink/renderer/core/dom/element.h"
|
||||
+#include "third_party/blink/renderer/core/dom/node_computed_style.h"
|
||||
+#include "third_party/blink/renderer/core/loader/resource/image_resource_content.h"
|
||||
+#include "third_party/blink/renderer/core/style/computed_style.h"
|
||||
+#include "third_party/blink/renderer/core/testing/sim/sim_request.h"
|
||||
+#include "third_party/blink/renderer/core/testing/sim/sim_test.h"
|
||||
+#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
|
||||
+
|
||||
+namespace blink {
|
||||
+
|
||||
+class CSSImageValueTest : public SimTest {};
|
||||
+
|
||||
+TEST_F(CSSImageValueTest, BlockPotentiallyDanglingMarkup) {
|
||||
+ SimRequest main_resource("https://example.com", "text/html");
|
||||
+
|
||||
+ LoadURL("https://example.com");
|
||||
+
|
||||
+ main_resource.Complete(R"HTML(
|
||||
+ <!doctype html>
|
||||
+ <table id="t1" background="ht
|
||||
+ tps://example.com/y<ay?foo"><td>XXX</td></table>
|
||||
+ <table id="t2" background="ht
|
||||
+ tps://example.com/y<ay?bar#boo"><td>XXX</td></table>
|
||||
+ )HTML");
|
||||
+
|
||||
+ test::RunPendingTasks();
|
||||
+ Compositor().BeginFrame();
|
||||
+
|
||||
+ auto* t1 = GetDocument().getElementById("t1");
|
||||
+ ImageResourceContent* content1 =
|
||||
+ t1->ComputedStyleRef().BackgroundLayers().GetImage()->CachedImage();
|
||||
+ ASSERT_TRUE(content1);
|
||||
+ EXPECT_TRUE(content1->ErrorOccurred());
|
||||
+
|
||||
+ auto* t2 = GetDocument().getElementById("t2");
|
||||
+ ImageResourceContent* content2 =
|
||||
+ t2->ComputedStyleRef().BackgroundLayers().GetImage()->CachedImage();
|
||||
+ ASSERT_TRUE(content2);
|
||||
+ EXPECT_TRUE(content2->ErrorOccurred());
|
||||
+}
|
||||
+
|
||||
+} // namespace blink
|
||||
@@ -0,0 +1,128 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Hosseinian <dhoss@chromium.org>
|
||||
Date: Wed, 8 Dec 2021 00:32:35 +0000
|
||||
Subject: Call PdfViewWebPlugin a11y methods asyncly
|
||||
|
||||
Calling a11y methods asyncly protects against the self-deletions they
|
||||
may cause. The a11y methods call
|
||||
content::RenderAccessibility::GenerateAXID() underneath, which may
|
||||
cause a relayout which causes the PdfViewWebPlugin to be deleted.
|
||||
|
||||
Isolating the calls in posted tasks is a clean way to protect against
|
||||
continuing control flow in the object after it is deleted.
|
||||
|
||||
(cherry picked from commit 6d9638366ae0f60f8d2db41857fcbc738c2514d4)
|
||||
|
||||
Bug: 1274376
|
||||
Change-Id: Iffd610a95199826fea56d7f23cb8e344657631d3
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3313692
|
||||
Reviewed-by: Lei Zhang <thestig@chromium.org>
|
||||
Commit-Queue: Daniel Hosseinian <dhoss@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#948105}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3319376
|
||||
Auto-Submit: Daniel Hosseinian <dhoss@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/4692@{#799}
|
||||
Cr-Branched-From: 038cd96142d384c0d2238973f1cb277725a62eba-refs/heads/main@{#938553}
|
||||
|
||||
diff --git a/pdf/pdf_view_web_plugin.cc b/pdf/pdf_view_web_plugin.cc
|
||||
index 29f922ed74379e2d2327a896e4c8149692590de8..193ac2e1b3fed341ce460e736c107652369f87fd 100644
|
||||
--- a/pdf/pdf_view_web_plugin.cc
|
||||
+++ b/pdf/pdf_view_web_plugin.cc
|
||||
@@ -802,9 +802,9 @@ void PdfViewWebPlugin::SetFormFieldInFocus(bool in_focus) {
|
||||
|
||||
void PdfViewWebPlugin::SetAccessibilityDocInfo(
|
||||
const AccessibilityDocInfo& doc_info) {
|
||||
- if (!pdf_accessibility_data_handler_)
|
||||
- return;
|
||||
- pdf_accessibility_data_handler_->SetAccessibilityDocInfo(doc_info);
|
||||
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
|
||||
+ FROM_HERE, base::BindOnce(&PdfViewWebPlugin::OnSetAccessibilityDocInfo,
|
||||
+ weak_factory_.GetWeakPtr(), doc_info));
|
||||
}
|
||||
|
||||
void PdfViewWebPlugin::SetAccessibilityPageInfo(
|
||||
@@ -812,16 +812,15 @@ void PdfViewWebPlugin::SetAccessibilityPageInfo(
|
||||
std::vector<AccessibilityTextRunInfo> text_runs,
|
||||
std::vector<AccessibilityCharInfo> chars,
|
||||
AccessibilityPageObjects page_objects) {
|
||||
- if (!pdf_accessibility_data_handler_)
|
||||
- return;
|
||||
- pdf_accessibility_data_handler_->SetAccessibilityPageInfo(
|
||||
- page_info, text_runs, chars, page_objects);
|
||||
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
|
||||
+ FROM_HERE, base::BindOnce(&PdfViewWebPlugin::OnSetAccessibilityPageInfo,
|
||||
+ weak_factory_.GetWeakPtr(),
|
||||
+ std::move(page_info), std::move(text_runs),
|
||||
+ std::move(chars), std::move(page_objects)));
|
||||
}
|
||||
|
||||
void PdfViewWebPlugin::SetAccessibilityViewportInfo(
|
||||
const AccessibilityViewportInfo& viewport_info) {
|
||||
- // The accessibility tree cannot be updated within the scope of
|
||||
- // `UpdateGeometry`.
|
||||
base::ThreadTaskRunnerHandle::Get()->PostTask(
|
||||
FROM_HERE,
|
||||
base::BindOnce(&PdfViewWebPlugin::OnSetAccessibilityViewportInfo,
|
||||
@@ -1009,11 +1008,32 @@ void PdfViewWebPlugin::OnInvokePrintDialog(int32_t /*result*/) {
|
||||
client_->Print(Container()->GetElement());
|
||||
}
|
||||
|
||||
+void PdfViewWebPlugin::OnSetAccessibilityDocInfo(
|
||||
+ AccessibilityDocInfo doc_info) {
|
||||
+ if (!pdf_accessibility_data_handler_)
|
||||
+ return;
|
||||
+ pdf_accessibility_data_handler_->SetAccessibilityDocInfo(doc_info);
|
||||
+ // `this` may be deleted. Don't do anything else.
|
||||
+}
|
||||
+
|
||||
+void PdfViewWebPlugin::OnSetAccessibilityPageInfo(
|
||||
+ AccessibilityPageInfo page_info,
|
||||
+ std::vector<AccessibilityTextRunInfo> text_runs,
|
||||
+ std::vector<AccessibilityCharInfo> chars,
|
||||
+ AccessibilityPageObjects page_objects) {
|
||||
+ if (!pdf_accessibility_data_handler_)
|
||||
+ return;
|
||||
+ pdf_accessibility_data_handler_->SetAccessibilityPageInfo(
|
||||
+ page_info, text_runs, chars, page_objects);
|
||||
+ // `this` may be deleted. Don't do anything else.
|
||||
+}
|
||||
+
|
||||
void PdfViewWebPlugin::OnSetAccessibilityViewportInfo(
|
||||
- const AccessibilityViewportInfo& viewport_info) {
|
||||
+ AccessibilityViewportInfo viewport_info) {
|
||||
if (!pdf_accessibility_data_handler_)
|
||||
return;
|
||||
pdf_accessibility_data_handler_->SetAccessibilityViewportInfo(viewport_info);
|
||||
+ // `this` may be deleted. Don't do anything else.
|
||||
}
|
||||
|
||||
pdf::mojom::PdfService* PdfViewWebPlugin::GetPdfService() {
|
||||
diff --git a/pdf/pdf_view_web_plugin.h b/pdf/pdf_view_web_plugin.h
|
||||
index f0c182f948ded59474e73bb03b89a3364d0b399e..f3eb489f6dc6553a67ab783814b111e2a64213fa 100644
|
||||
--- a/pdf/pdf_view_web_plugin.h
|
||||
+++ b/pdf/pdf_view_web_plugin.h
|
||||
@@ -330,10 +330,21 @@ class PdfViewWebPlugin final : public PdfViewPluginBase,
|
||||
// the plugin are moved off the main thread.
|
||||
void OnInvokePrintDialog(int32_t /*result*/);
|
||||
|
||||
- // Callback to set the viewport information in accessibility tree
|
||||
+ // Callback to set the document information in the accessibility tree
|
||||
// asynchronously.
|
||||
- void OnSetAccessibilityViewportInfo(
|
||||
- const AccessibilityViewportInfo& viewport_info);
|
||||
+ void OnSetAccessibilityDocInfo(AccessibilityDocInfo doc_info);
|
||||
+
|
||||
+ // Callback to set the page information in the accessibility tree
|
||||
+ // asynchronously.
|
||||
+ void OnSetAccessibilityPageInfo(
|
||||
+ AccessibilityPageInfo page_info,
|
||||
+ std::vector<AccessibilityTextRunInfo> text_runs,
|
||||
+ std::vector<AccessibilityCharInfo> chars,
|
||||
+ AccessibilityPageObjects page_objects);
|
||||
+
|
||||
+ // Callback to set the viewport information in the accessibility tree
|
||||
+ // asynchronously.
|
||||
+ void OnSetAccessibilityViewportInfo(AccessibilityViewportInfo viewport_info);
|
||||
|
||||
// May be null in unit tests.
|
||||
pdf::mojom::PdfService* GetPdfService();
|
||||
@@ -0,0 +1,107 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Chris Cunningham <chcunningham@chromium.org>
|
||||
Date: Tue, 30 Nov 2021 20:53:26 +0000
|
||||
Subject: Various DecoderTemplate shutdown cleanups
|
||||
|
||||
1. Use DeleteSoon() when destroying the |decoder_| to avoid destructing
|
||||
in error conditions where it's callback (OnDecodeDone()) is actively
|
||||
executing.
|
||||
|
||||
2. Call Shutdown() from ContextDestroyed() to invoke full reset
|
||||
algorithm and tidily clean up all state.
|
||||
|
||||
(cherry picked from commit b5e609d4e7a296fa8c2d50f1373e9f3a50003995)
|
||||
|
||||
Bug: 1267426
|
||||
Change-Id: I927d8a3bd245b3f833e73c74103cbaacf6d73406
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3277273
|
||||
Commit-Queue: Chrome Cunningham <chcunningham@chromium.org>
|
||||
Auto-Submit: Chrome Cunningham <chcunningham@chromium.org>
|
||||
Reviewed-by: Dan Sanders <sandersd@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#941390}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3308537
|
||||
Commit-Queue: Dan Sanders <sandersd@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/4692@{#599}
|
||||
Cr-Branched-From: 038cd96142d384c0d2238973f1cb277725a62eba-refs/heads/main@{#938553}
|
||||
|
||||
diff --git a/third_party/blink/renderer/modules/webcodecs/decoder_template.cc b/third_party/blink/renderer/modules/webcodecs/decoder_template.cc
|
||||
index 7bc6b575584d4ef0e59508bf6ef170b12ec86534..736799dca31a3c7c71ffc84e60ae24cb3dbb1082 100644
|
||||
--- a/third_party/blink/renderer/modules/webcodecs/decoder_template.cc
|
||||
+++ b/third_party/blink/renderer/modules/webcodecs/decoder_template.cc
|
||||
@@ -79,8 +79,10 @@ DecoderTemplate<Traits>::DecoderTemplate(ScriptState* script_state,
|
||||
ExecutionContext* context = GetExecutionContext();
|
||||
DCHECK(context);
|
||||
|
||||
- logger_ = std::make_unique<CodecLogger>(
|
||||
- context, context->GetTaskRunner(TaskType::kInternalMedia));
|
||||
+ main_thread_task_runner_ =
|
||||
+ context->GetTaskRunner(TaskType::kInternalMediaRealTime);
|
||||
+
|
||||
+ logger_ = std::make_unique<CodecLogger>(context, main_thread_task_runner_);
|
||||
|
||||
logger_->log()->SetProperty<media::MediaLogProperty::kFrameUrl>(
|
||||
context->Url().GetString().Ascii());
|
||||
@@ -506,8 +508,10 @@ void DecoderTemplate<Traits>::Shutdown(DOMException* exception) {
|
||||
// Prevent any further logging from being reported.
|
||||
logger_->Neuter();
|
||||
|
||||
- // Clear decoding and JS-visible queue state.
|
||||
- decoder_.reset();
|
||||
+ // Clear decoding and JS-visible queue state. Use DeleteSoon() to avoid
|
||||
+ // deleting decoder_ when its callback (e.g. OnDecodeDone()) may be below us
|
||||
+ // in the stack.
|
||||
+ main_thread_task_runner_->DeleteSoon(FROM_HERE, std::move(decoder_));
|
||||
|
||||
if (pending_request_) {
|
||||
// This request was added as part of calling ResetAlgorithm above. However,
|
||||
@@ -724,9 +728,8 @@ void DecoderTemplate<Traits>::TraceQueueSizes() const {
|
||||
|
||||
template <typename Traits>
|
||||
void DecoderTemplate<Traits>::ContextDestroyed() {
|
||||
- state_ = V8CodecState(V8CodecState::Enum::kClosed);
|
||||
- logger_->Neuter();
|
||||
- decoder_.reset();
|
||||
+ // Deallocate resources and supress late callbacks from media thread.
|
||||
+ Shutdown();
|
||||
}
|
||||
|
||||
template <typename Traits>
|
||||
diff --git a/third_party/blink/renderer/modules/webcodecs/decoder_template.h b/third_party/blink/renderer/modules/webcodecs/decoder_template.h
|
||||
index bc186b60c84e2b4b76468f21a9305c5792796e7e..c16dbeee58048644291fe856e33573068da3c69f 100644
|
||||
--- a/third_party/blink/renderer/modules/webcodecs/decoder_template.h
|
||||
+++ b/third_party/blink/renderer/modules/webcodecs/decoder_template.h
|
||||
@@ -29,6 +29,10 @@
|
||||
#include "third_party/blink/renderer/platform/heap/heap_allocator.h"
|
||||
#include "third_party/blink/renderer/platform/heap/member.h"
|
||||
|
||||
+namespace base {
|
||||
+class SingleThreadTaskRunner;
|
||||
+}
|
||||
+
|
||||
namespace media {
|
||||
class GpuVideoAcceleratorFactories;
|
||||
class ScopedDecodeTrace;
|
||||
@@ -227,6 +231,9 @@ class MODULES_EXPORT DecoderTemplate
|
||||
|
||||
// Keyframes are required after configure(), flush(), and reset().
|
||||
bool require_key_frame_ = true;
|
||||
+
|
||||
+ // Task runner for main thread.
|
||||
+ scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
|
||||
};
|
||||
|
||||
} // namespace blink
|
||||
diff --git a/third_party/blink/renderer/modules/webcodecs/decoder_template_test.cc b/third_party/blink/renderer/modules/webcodecs/decoder_template_test.cc
|
||||
index ebc7395606a8a2574d1639db8cc8ae5d3c9cdde9..36cbf25cbc5582f83ff4d9c945a4c514aa520885 100644
|
||||
--- a/third_party/blink/renderer/modules/webcodecs/decoder_template_test.cc
|
||||
+++ b/third_party/blink/renderer/modules/webcodecs/decoder_template_test.cc
|
||||
@@ -215,9 +215,6 @@ TYPED_TEST(DecoderTemplateTest, MAYBE_CodecReclamation) {
|
||||
testing::Mock::VerifyAndClearExpectations(error_callback);
|
||||
}
|
||||
|
||||
-// Note: AudioDecoder and VideoDecoder specific tests should be put in
|
||||
-// audio_decoder_test.cc and video_decoder_test.cc respectively.
|
||||
-
|
||||
} // namespace
|
||||
|
||||
} // namespace blink
|
||||
67
patches/chromium/m98_fs_fix_fileutil_lifetime_issue.patch
Normal file
67
patches/chromium/m98_fs_fix_fileutil_lifetime_issue.patch
Normal file
@@ -0,0 +1,67 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Austin Sullivan <asully@chromium.org>
|
||||
Date: Thu, 10 Feb 2022 22:18:54 +0000
|
||||
Subject: M98: FS: Fix FileUtil lifetime issue
|
||||
|
||||
Keeps FileSystemContext alive while while resolving a URL on an open
|
||||
file system, removing the possibility of the file system being
|
||||
destroyed while a URL is being resolved on it.
|
||||
|
||||
(cherry picked from commit 3fdf2adf11b3c716c9015597d30b59bffc7ac91b)
|
||||
|
||||
Bug: 1275622, 1289394
|
||||
Change-Id: Ic1b97552f9d41a61163d72ff8c605699f673f55f
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3373583
|
||||
Reviewed-by: Marijn Kruisselbrink <mek@chromium.org>
|
||||
Commit-Queue: Austin Sullivan <asully@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#968470}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3451059
|
||||
Auto-Submit: Austin Sullivan <asully@chromium.org>
|
||||
Commit-Queue: Marijn Kruisselbrink <mek@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/4758@{#1131}
|
||||
Cr-Branched-From: 4a2cf4baf90326df19c3ee70ff987960d59a386e-refs/heads/main@{#950365}
|
||||
|
||||
diff --git a/storage/browser/file_system/file_system_context.cc b/storage/browser/file_system/file_system_context.cc
|
||||
index f6362869e4f6767c5a95b363fceca3455b9a9b1a..ea499242a6b81f7c74bbdeb50c08af096a0b0867 100644
|
||||
--- a/storage/browser/file_system/file_system_context.cc
|
||||
+++ b/storage/browser/file_system/file_system_context.cc
|
||||
@@ -430,9 +430,22 @@ void FileSystemContext::OpenFileSystem(const blink::StorageKey& storage_key,
|
||||
return;
|
||||
}
|
||||
|
||||
+ // Bind `this` to the callback to ensure this instance stays alive while the
|
||||
+ // URL is resolving.
|
||||
backend->ResolveURL(
|
||||
CreateCrackedFileSystemURL(storage_key, type, base::FilePath()), mode,
|
||||
- std::move(callback));
|
||||
+ base::BindOnce(&FileSystemContext::DidResolveURLOnOpenFileSystem, this,
|
||||
+ std::move(callback)));
|
||||
+}
|
||||
+
|
||||
+void FileSystemContext::DidResolveURLOnOpenFileSystem(
|
||||
+ OpenFileSystemCallback callback,
|
||||
+ const GURL& filesystem_root,
|
||||
+ const std::string& filesystem_name,
|
||||
+ base::File::Error error) {
|
||||
+ DCHECK(io_task_runner_->RunsTasksInCurrentSequence());
|
||||
+
|
||||
+ std::move(callback).Run(filesystem_root, filesystem_name, error);
|
||||
}
|
||||
|
||||
void FileSystemContext::ResolveURL(const FileSystemURL& url,
|
||||
diff --git a/storage/browser/file_system/file_system_context.h b/storage/browser/file_system/file_system_context.h
|
||||
index 99699365e0a4c4fe8280cd3aa64c30dce124651d..f768bcc456a737d46e5e551c8d7e2b1a421f620b 100644
|
||||
--- a/storage/browser/file_system/file_system_context.h
|
||||
+++ b/storage/browser/file_system/file_system_context.h
|
||||
@@ -402,6 +402,11 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) FileSystemContext
|
||||
const std::string& filesystem_name,
|
||||
base::File::Error error);
|
||||
|
||||
+ void DidResolveURLOnOpenFileSystem(OpenFileSystemCallback callback,
|
||||
+ const GURL& filesystem_root,
|
||||
+ const std::string& filesystem_name,
|
||||
+ base::File::Error error);
|
||||
+
|
||||
// Returns a FileSystemBackend, used only by test code.
|
||||
SandboxFileSystemBackend* sandbox_backend() const {
|
||||
return sandbox_backend_.get();
|
||||
@@ -0,0 +1,122 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Reilly Grant <reillyg@chromium.org>
|
||||
Date: Fri, 12 Nov 2021 20:09:12 +0000
|
||||
Subject: serial: Check for detached buffers when writing
|
||||
|
||||
This change adds check in SerialPortUnderlyingSink::WriteData() to
|
||||
ensure that the V8BufferSource being written to the Mojo data pipe has
|
||||
not been detached since it was passed to the WritableStream.
|
||||
|
||||
(cherry picked from commit 7ce1516b49e86430c9216d0df8e23a325104a8c5)
|
||||
|
||||
Bug: 1267627
|
||||
Change-Id: I63d48584eb0be1c1d87c27115900aa5c17931fcf
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3269348
|
||||
Commit-Queue: Reilly Grant <reillyg@chromium.org>
|
||||
Auto-Submit: Reilly Grant <reillyg@chromium.org>
|
||||
Reviewed-by: Hongchan Choi <hongchan@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#940631}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3279207
|
||||
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
|
||||
Cr-Commit-Position: refs/branch-heads/4692@{#132}
|
||||
Cr-Branched-From: 038cd96142d384c0d2238973f1cb277725a62eba-refs/heads/main@{#938553}
|
||||
|
||||
diff --git a/third_party/blink/renderer/modules/serial/serial_port_underlying_sink.cc b/third_party/blink/renderer/modules/serial/serial_port_underlying_sink.cc
|
||||
index 08ab2c7e05668710b77712f3ffc0d5aeef4dd213..7876baf19a1f547c71e2a115db8a2cc4ccd43a3b 100644
|
||||
--- a/third_party/blink/renderer/modules/serial/serial_port_underlying_sink.cc
|
||||
+++ b/third_party/blink/renderer/modules/serial/serial_port_underlying_sink.cc
|
||||
@@ -172,12 +172,25 @@ void SerialPortUnderlyingSink::WriteData() {
|
||||
DCHECK(buffer_source_);
|
||||
|
||||
DOMArrayPiece array_piece(buffer_source_);
|
||||
+ // From https://webidl.spec.whatwg.org/#dfn-get-buffer-source-copy, if the
|
||||
+ // buffer source is detached then an empty byte sequence is returned, which
|
||||
+ // means the write is complete.
|
||||
+ if (array_piece.IsDetached()) {
|
||||
+ buffer_source_ = nullptr;
|
||||
+ offset_ = 0;
|
||||
+ pending_operation_->Resolve();
|
||||
+ pending_operation_ = nullptr;
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
if (array_piece.ByteLength() > std::numeric_limits<uint32_t>::max()) {
|
||||
- pending_exception_ = DOMException::Create(
|
||||
- "Buffer size exceeds maximum heap object size.", "DataError");
|
||||
+ pending_exception_ = MakeGarbageCollected<DOMException>(
|
||||
+ DOMExceptionCode::kDataError,
|
||||
+ "Buffer size exceeds maximum heap object size.");
|
||||
PipeClosed();
|
||||
return;
|
||||
}
|
||||
+
|
||||
const uint8_t* data = array_piece.Bytes();
|
||||
const uint32_t length = static_cast<uint32_t>(array_piece.ByteLength());
|
||||
|
||||
diff --git a/third_party/blink/web_tests/external/wpt/serial/serialPort_writable.https.any.js b/third_party/blink/web_tests/external/wpt/serial/serialPort_writable.https.any.js
|
||||
index 9728af7de5051dce874e10082e1443a3ca9fa7dc..5e3b8548a91ddc2a0afa9793dea167f8e89defe3 100644
|
||||
--- a/third_party/blink/web_tests/external/wpt/serial/serialPort_writable.https.any.js
|
||||
+++ b/third_party/blink/web_tests/external/wpt/serial/serialPort_writable.https.any.js
|
||||
@@ -70,7 +70,7 @@ serial_test(async (t, fake) => {
|
||||
compareArrays(data, value);
|
||||
|
||||
await port.close();
|
||||
-}, 'Can read a large amount of data');
|
||||
+}, 'Can write a large amount of data');
|
||||
|
||||
serial_test(async (t, fake) => {
|
||||
const {port, fakePort} = await getFakeSerialPort(fake);
|
||||
diff --git a/third_party/blink/web_tests/external/wpt/serial/serialPort_writable_detachBuffer.https.any.js b/third_party/blink/web_tests/external/wpt/serial/serialPort_writable_detachBuffer.https.any.js
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..828e877726b1c63dba14efc36324d9a16aa4e62f
|
||||
--- /dev/null
|
||||
+++ b/third_party/blink/web_tests/external/wpt/serial/serialPort_writable_detachBuffer.https.any.js
|
||||
@@ -0,0 +1,48 @@
|
||||
+// META: script=/resources/test-only-api.js
|
||||
+// META: script=/serial/resources/common.js
|
||||
+// META: script=resources/automation.js
|
||||
+
|
||||
+function detachBuffer(buffer) {
|
||||
+ const channel = new MessageChannel();
|
||||
+ channel.port1.postMessage('', [buffer]);
|
||||
+}
|
||||
+
|
||||
+serial_test(async (t, fake) => {
|
||||
+ const {port, fakePort} = await getFakeSerialPort(fake);
|
||||
+ await port.open({baudRate: 9600, bufferSize: 64});
|
||||
+
|
||||
+ const writer = port.writable.getWriter();
|
||||
+ const data = new Uint8Array(64);
|
||||
+ detachBuffer(data.buffer);
|
||||
+
|
||||
+ // Writing a detached buffer is equivalent to writing an empty buffer so this
|
||||
+ // should trivially succeed.
|
||||
+ await writer.write(data);
|
||||
+ writer.releaseLock();
|
||||
+
|
||||
+ await port.close();
|
||||
+}, 'Writing a detached buffer is safe');
|
||||
+
|
||||
+serial_test(async (t, fake) => {
|
||||
+ const {port, fakePort} = await getFakeSerialPort(fake);
|
||||
+ // Select a buffer size smaller than the amount of data transferred.
|
||||
+ await port.open({baudRate: 9600, bufferSize: 64});
|
||||
+
|
||||
+ // Start writing a buffer much larger than bufferSize above so that it can't
|
||||
+ // all be transfered in a single operation.
|
||||
+ const writer = port.writable.getWriter();
|
||||
+ const data = new Uint8Array(1024);
|
||||
+ const promise = writer.write(data);
|
||||
+ writer.releaseLock();
|
||||
+
|
||||
+ // Read half of the written data and then detach the buffer.
|
||||
+ await fakePort.readable();
|
||||
+ await fakePort.readWithLength(data.byteLength / 2);
|
||||
+ detachBuffer(data.buffer);
|
||||
+
|
||||
+ // When the buffer is detached its length becomes zero and so the write should
|
||||
+ // succeed but it is undefined how much data was written before that happened.
|
||||
+ await promise;
|
||||
+
|
||||
+ await port.close();
|
||||
+}, 'Detaching a buffer while writing is safe');
|
||||
@@ -147,7 +147,7 @@ index 288b9f89129de88ea078b2e6d3b2d255dd527a95..e9979d5c9707e94580d4a10b4c48c32c
|
||||
}
|
||||
|
||||
diff --git a/chrome/browser/printing/print_view_manager_base.cc b/chrome/browser/printing/print_view_manager_base.cc
|
||||
index 2011d52338081666b4761e0bf66d01245abd0213..647ac4cd9730c8983868ea165907b7c9a42767aa 100644
|
||||
index 5491e04e7eba8ad7a29f1cb3aa51ee13716e0d9d..2f2348f3d2e35bfcf419b654032a799f34d13884 100644
|
||||
--- a/chrome/browser/printing/print_view_manager_base.cc
|
||||
+++ b/chrome/browser/printing/print_view_manager_base.cc
|
||||
@@ -28,10 +28,10 @@
|
||||
@@ -223,10 +223,10 @@ index 2011d52338081666b4761e0bf66d01245abd0213..647ac4cd9730c8983868ea165907b7c9
|
||||
+ bool silent,
|
||||
+ base::Value settings,
|
||||
+ CompletionCallback callback) {
|
||||
auto weak_this = weak_ptr_factory_.GetWeakPtr();
|
||||
DisconnectFromCurrentPrintJob();
|
||||
if (!weak_this)
|
||||
@@ -369,7 +380,14 @@ bool PrintViewManagerBase::PrintNow(content::RenderFrameHost* rfh) {
|
||||
// Remember the ID for `rfh`, to enable checking that the `RenderFrameHost`
|
||||
// is still valid after a possible inner message loop runs in
|
||||
// `DisconnectFromCurrentPrintJob()`.
|
||||
@@ -377,7 +388,14 @@ bool PrintViewManagerBase::PrintNow(content::RenderFrameHost* rfh) {
|
||||
// go in `ReleasePrintJob()`.
|
||||
|
||||
SetPrintingRFH(rfh);
|
||||
@@ -242,7 +242,7 @@ index 2011d52338081666b4761e0bf66d01245abd0213..647ac4cd9730c8983868ea165907b7c9
|
||||
|
||||
for (auto& observer : GetObservers())
|
||||
observer.OnPrintNow(rfh);
|
||||
@@ -528,9 +546,9 @@ void PrintViewManagerBase::ScriptedPrintReply(
|
||||
@@ -536,9 +554,9 @@ void PrintViewManagerBase::ScriptedPrintReply(
|
||||
void PrintViewManagerBase::UpdatePrintingEnabled() {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
// The Unretained() is safe because ForEachFrame() is synchronous.
|
||||
@@ -255,7 +255,7 @@ index 2011d52338081666b4761e0bf66d01245abd0213..647ac4cd9730c8983868ea165907b7c9
|
||||
}
|
||||
|
||||
void PrintViewManagerBase::NavigationStopped() {
|
||||
@@ -644,12 +662,13 @@ void PrintViewManagerBase::DidPrintDocument(
|
||||
@@ -652,12 +670,13 @@ void PrintViewManagerBase::DidPrintDocument(
|
||||
void PrintViewManagerBase::GetDefaultPrintSettings(
|
||||
GetDefaultPrintSettingsCallback callback) {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
@@ -270,7 +270,7 @@ index 2011d52338081666b4761e0bf66d01245abd0213..647ac4cd9730c8983868ea165907b7c9
|
||||
content::RenderFrameHost* render_frame_host = GetCurrentTargetFrame();
|
||||
auto callback_wrapper =
|
||||
base::BindOnce(&PrintViewManagerBase::GetDefaultPrintSettingsReply,
|
||||
@@ -667,18 +686,20 @@ void PrintViewManagerBase::UpdatePrintSettings(
|
||||
@@ -675,18 +694,20 @@ void PrintViewManagerBase::UpdatePrintSettings(
|
||||
base::Value job_settings,
|
||||
UpdatePrintSettingsCallback callback) {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
@@ -292,7 +292,7 @@ index 2011d52338081666b4761e0bf66d01245abd0213..647ac4cd9730c8983868ea165907b7c9
|
||||
content::BrowserContext* context =
|
||||
web_contents() ? web_contents()->GetBrowserContext() : nullptr;
|
||||
PrefService* prefs =
|
||||
@@ -688,6 +709,7 @@ void PrintViewManagerBase::UpdatePrintSettings(
|
||||
@@ -696,6 +717,7 @@ void PrintViewManagerBase::UpdatePrintSettings(
|
||||
if (value > 0)
|
||||
job_settings.SetIntKey(kSettingRasterizePdfDpi, value);
|
||||
}
|
||||
@@ -300,7 +300,7 @@ index 2011d52338081666b4761e0bf66d01245abd0213..647ac4cd9730c8983868ea165907b7c9
|
||||
|
||||
content::RenderFrameHost* render_frame_host = GetCurrentTargetFrame();
|
||||
auto callback_wrapper =
|
||||
@@ -727,7 +749,6 @@ void PrintViewManagerBase::PrintingFailed(int32_t cookie) {
|
||||
@@ -735,7 +757,6 @@ void PrintViewManagerBase::PrintingFailed(int32_t cookie) {
|
||||
PrintManager::PrintingFailed(cookie);
|
||||
|
||||
#if BUILDFLAG(ENABLE_PRINT_PREVIEW)
|
||||
@@ -308,7 +308,7 @@ index 2011d52338081666b4761e0bf66d01245abd0213..647ac4cd9730c8983868ea165907b7c9
|
||||
#endif
|
||||
|
||||
ReleasePrinterQuery();
|
||||
@@ -742,6 +763,11 @@ void PrintViewManagerBase::RemoveObserver(Observer& observer) {
|
||||
@@ -750,6 +771,11 @@ void PrintViewManagerBase::RemoveObserver(Observer& observer) {
|
||||
}
|
||||
|
||||
void PrintViewManagerBase::ShowInvalidPrinterSettingsError() {
|
||||
@@ -320,7 +320,7 @@ index 2011d52338081666b4761e0bf66d01245abd0213..647ac4cd9730c8983868ea165907b7c9
|
||||
base::ThreadTaskRunnerHandle::Get()->PostTask(
|
||||
FROM_HERE, base::BindOnce(&ShowWarningMessageBox,
|
||||
l10n_util::GetStringUTF16(
|
||||
@@ -820,6 +846,11 @@ void PrintViewManagerBase::OnNotifyPrintJobEvent(
|
||||
@@ -828,6 +854,11 @@ void PrintViewManagerBase::OnNotifyPrintJobEvent(
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
@@ -332,7 +332,7 @@ index 2011d52338081666b4761e0bf66d01245abd0213..647ac4cd9730c8983868ea165907b7c9
|
||||
case JobEventDetails::JOB_DONE:
|
||||
// Printing is done, we don't need it anymore.
|
||||
// print_job_->is_job_pending() may still be true, depending on the order
|
||||
@@ -889,7 +920,10 @@ bool PrintViewManagerBase::CreateNewPrintJob(
|
||||
@@ -897,7 +928,10 @@ bool PrintViewManagerBase::CreateNewPrintJob(
|
||||
|
||||
// Disconnect the current |print_job_|.
|
||||
auto weak_this = weak_ptr_factory_.GetWeakPtr();
|
||||
@@ -344,7 +344,7 @@ index 2011d52338081666b4761e0bf66d01245abd0213..647ac4cd9730c8983868ea165907b7c9
|
||||
if (!weak_this)
|
||||
return false;
|
||||
|
||||
@@ -912,8 +946,6 @@ bool PrintViewManagerBase::CreateNewPrintJob(
|
||||
@@ -920,8 +954,6 @@ bool PrintViewManagerBase::CreateNewPrintJob(
|
||||
/*source_id=*/"");
|
||||
#endif
|
||||
|
||||
@@ -353,7 +353,7 @@ index 2011d52338081666b4761e0bf66d01245abd0213..647ac4cd9730c8983868ea165907b7c9
|
||||
printing_succeeded_ = false;
|
||||
return true;
|
||||
}
|
||||
@@ -965,14 +997,22 @@ void PrintViewManagerBase::ReleasePrintJob() {
|
||||
@@ -973,6 +1005,16 @@ void PrintViewManagerBase::ReleasePrintJob() {
|
||||
content::RenderFrameHost* rfh = printing_rfh_;
|
||||
printing_rfh_ = nullptr;
|
||||
|
||||
@@ -370,15 +370,16 @@ index 2011d52338081666b4761e0bf66d01245abd0213..647ac4cd9730c8983868ea165907b7c9
|
||||
if (!print_job_)
|
||||
return;
|
||||
|
||||
if (rfh)
|
||||
@@ -983,8 +1025,6 @@ void PrintViewManagerBase::ReleasePrintJob() {
|
||||
GetPrintRenderFrame(rfh)->PrintingDone(printing_succeeded_);
|
||||
}
|
||||
|
||||
- registrar_.Remove(this, chrome::NOTIFICATION_PRINT_JOB_EVENT,
|
||||
- content::Source<PrintJob>(print_job_.get()));
|
||||
// Don't close the worker thread.
|
||||
print_job_ = nullptr;
|
||||
}
|
||||
@@ -1010,7 +1050,7 @@ bool PrintViewManagerBase::RunInnerMessageLoop() {
|
||||
@@ -1022,7 +1062,7 @@ bool PrintViewManagerBase::RunInnerMessageLoop() {
|
||||
}
|
||||
|
||||
bool PrintViewManagerBase::OpportunisticallyCreatePrintJob(int cookie) {
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Bruce Dawson <brucedawson@chromium.org>
|
||||
Date: Mon, 28 Feb 2022 19:07:41 +0000
|
||||
Subject: Remove incorrect width/height adjustments
|
||||
|
||||
In late 2016 a change which fixed some problems around window sizing
|
||||
when attaching or detaching additional displays was landed, which fixed
|
||||
some genuine bugs. Unfortunately it included a subtraction of 1 from the
|
||||
width and height of the Chrome window. I couldn't find any discussion of
|
||||
this size adjustment and I think that it was just a misunderstanding of
|
||||
how window rectangles work (inclusive versus exclusive extents).
|
||||
|
||||
This size adjustment causes non-maximized Chrome windows to shrink every
|
||||
time a monitor is added or removed. The problematic commit was found
|
||||
by the bug-filer through a bisect of more than four years of Chrome
|
||||
history - I'm just landing the fix that they suggested.
|
||||
|
||||
Bug: 1300415
|
||||
Change-Id: Ief124f584a91aa9cc3f10704b0cc1e83356dea5b
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3492658
|
||||
Reviewed-by: Allen Bauer <kylixrd@chromium.org>
|
||||
Commit-Queue: Bruce Dawson <brucedawson@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/main@{#975872}
|
||||
|
||||
diff --git a/ui/views/win/hwnd_message_handler.cc b/ui/views/win/hwnd_message_handler.cc
|
||||
index ef01843018cfada041330c3ed75d9d55c3225049..76dcfa99e9958d66ccd17db914aaafa354a03682 100644
|
||||
--- a/ui/views/win/hwnd_message_handler.cc
|
||||
+++ b/ui/views/win/hwnd_message_handler.cc
|
||||
@@ -2829,8 +2829,8 @@ void HWNDMessageHandler::OnWindowPosChanging(WINDOWPOS* window_pos) {
|
||||
// (Win+Shift+Arrows). See crbug.com/656001.
|
||||
window_rect.left = window_pos->x;
|
||||
window_rect.top = window_pos->y;
|
||||
- window_rect.right = window_pos->x + window_pos->cx - 1;
|
||||
- window_rect.bottom = window_pos->y + window_pos->cy - 1;
|
||||
+ window_rect.right = window_pos->x + window_pos->cx;
|
||||
+ window_rect.bottom = window_pos->y + window_pos->cy;
|
||||
}
|
||||
|
||||
HMONITOR monitor;
|
||||
@@ -32,10 +32,10 @@ Reviewed-by: Jing Wang <jiwan@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/main@{#946860}
|
||||
|
||||
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc
|
||||
index 7955f2cb725ef4c011bbbce74820d98783d56a0c..fc2c236b8bb9c29cd720225bf14a014f61b01181 100644
|
||||
index 9505a5bfc0c88762bc00ba26774a906c9115282e..6736446f085f6854ae704f9edeccd1ec5219993d 100644
|
||||
--- a/content/browser/renderer_host/render_widget_host_view_aura.cc
|
||||
+++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
|
||||
@@ -1627,18 +1627,10 @@ bool RenderWidgetHostViewAura::AddGrammarFragments(
|
||||
@@ -1631,18 +1631,10 @@ bool RenderWidgetHostViewAura::AddGrammarFragments(
|
||||
if (!input_handler || fragments.empty())
|
||||
return false;
|
||||
|
||||
@@ -54,7 +54,7 @@ index 7955f2cb725ef4c011bbbce74820d98783d56a0c..fc2c236b8bb9c29cd720225bf14a014f
|
||||
ui::ImeTextSpan ui_ime_text_span;
|
||||
ui_ime_text_span.type = ui::ImeTextSpan::Type::kGrammarSuggestion;
|
||||
ui_ime_text_span.start_offset = fragment.range.start();
|
||||
@@ -1653,10 +1645,6 @@ bool RenderWidgetHostViewAura::AddGrammarFragments(
|
||||
@@ -1657,10 +1649,6 @@ bool RenderWidgetHostViewAura::AddGrammarFragments(
|
||||
max_fragment_end = fragment.range.end();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,387 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Abigail Klein <abigailbklein@google.com>
|
||||
Date: Wed, 3 Nov 2021 03:53:27 +0000
|
||||
Subject: Use AXNodeID rather than AXNode* in AXEventGenerator tree events.
|
||||
|
||||
We suspect that sometimes AXNodes are destroyed while processing events.
|
||||
Specifically, we suspect that the extra mac nodes that are created for
|
||||
table column and row headers when VoiceOver requests them are destroyed
|
||||
if an ancestor up the chain is modified. In order to safeguard against
|
||||
the possibility of an AXNode* becoming stale, we will store AXNodeIDs in
|
||||
the list of tree events. This way, when the tree event is used, we can
|
||||
first check for the validity of the AXNodeID before using the
|
||||
corresponding AXNode.
|
||||
|
||||
Bug: 1262967
|
||||
Change-Id: Ifa2b23544fff532b379857a637f417d5f639c7ce
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3244046
|
||||
Commit-Queue: Abigail Klein <abigailbklein@google.com>
|
||||
Reviewed-by: Aaron Leventhal <aleventhal@chromium.org>
|
||||
Reviewed-by: Nektarios Paisios <nektar@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/main@{#937698}
|
||||
|
||||
diff --git a/content/browser/accessibility/browser_accessibility_manager.cc b/content/browser/accessibility/browser_accessibility_manager.cc
|
||||
index deb726cc9553c7da2c20d232989efd31259991c1..eaecbc79c9cbd4597942b10a31f46db20d57f245 100644
|
||||
--- a/content/browser/accessibility/browser_accessibility_manager.cc
|
||||
+++ b/content/browser/accessibility/browser_accessibility_manager.cc
|
||||
@@ -503,7 +503,7 @@ bool BrowserAccessibilityManager::OnAccessibilityEvents(
|
||||
std::vector<ui::AXEventGenerator::TargetedEvent> deferred_events;
|
||||
bool received_load_complete_event = false;
|
||||
for (const auto& targeted_event : event_generator()) {
|
||||
- BrowserAccessibility* event_target = GetFromAXNode(targeted_event.node);
|
||||
+ BrowserAccessibility* event_target = GetFromID(targeted_event.node_id);
|
||||
if (!event_target)
|
||||
continue;
|
||||
|
||||
@@ -540,7 +540,7 @@ bool BrowserAccessibilityManager::OnAccessibilityEvents(
|
||||
|
||||
// Now fire all of the rest of the generated events we previously deferred.
|
||||
for (const auto& targeted_event : deferred_events) {
|
||||
- BrowserAccessibility* event_target = GetFromAXNode(targeted_event.node);
|
||||
+ BrowserAccessibility* event_target = GetFromID(targeted_event.node_id);
|
||||
if (!event_target)
|
||||
continue;
|
||||
|
||||
diff --git a/content/browser/accessibility/browser_accessibility_manager_win.cc b/content/browser/accessibility/browser_accessibility_manager_win.cc
|
||||
index f00c7f9b114cb55a02df1bab7d03d8f1bc24db7b..e56e22b0e25c0532d4c31f3b0425e51493bca51c 100644
|
||||
--- a/content/browser/accessibility/browser_accessibility_manager_win.cc
|
||||
+++ b/content/browser/accessibility/browser_accessibility_manager_win.cc
|
||||
@@ -950,7 +950,7 @@ void BrowserAccessibilityManagerWin::BeforeAccessibilityEvents() {
|
||||
for (const auto& targeted_event : event_generator()) {
|
||||
if (targeted_event.event_params.event ==
|
||||
ui::AXEventGenerator::Event::IGNORED_CHANGED) {
|
||||
- BrowserAccessibility* event_target = GetFromAXNode(targeted_event.node);
|
||||
+ BrowserAccessibility* event_target = GetFromID(targeted_event.node_id);
|
||||
if (!event_target)
|
||||
continue;
|
||||
|
||||
diff --git a/extensions/renderer/api/automation/automation_ax_tree_wrapper.cc b/extensions/renderer/api/automation/automation_ax_tree_wrapper.cc
|
||||
index f8725107d788a6cc70ad337ad92b65ba636968b6..e9e09b22ff40b657dec538813cc3464c9933ab1a 100644
|
||||
--- a/extensions/renderer/api/automation/automation_ax_tree_wrapper.cc
|
||||
+++ b/extensions/renderer/api/automation/automation_ax_tree_wrapper.cc
|
||||
@@ -152,7 +152,7 @@ bool AutomationAXTreeWrapper::OnAccessibilityEvents(
|
||||
if (ShouldIgnoreGeneratedEvent(targeted_event.event_params.event))
|
||||
continue;
|
||||
ui::AXEvent generated_event;
|
||||
- generated_event.id = targeted_event.node->id();
|
||||
+ generated_event.id = targeted_event.node_id;
|
||||
generated_event.event_from = targeted_event.event_params.event_from;
|
||||
generated_event.event_from_action =
|
||||
targeted_event.event_params.event_from_action;
|
||||
diff --git a/ui/accessibility/ax_event_generator.cc b/ui/accessibility/ax_event_generator.cc
|
||||
index b792765b57f22e3dee132b58c67c82638f28b9e5..dd347f9b5044147b644d7ad8459dc4da94f7ff09 100644
|
||||
--- a/ui/accessibility/ax_event_generator.cc
|
||||
+++ b/ui/accessibility/ax_event_generator.cc
|
||||
@@ -102,10 +102,10 @@ bool AXEventGenerator::EventParams::operator<(const EventParams& rhs) const {
|
||||
// AXEventGenerator::TargetedEvent
|
||||
//
|
||||
|
||||
-AXEventGenerator::TargetedEvent::TargetedEvent(AXNode* node,
|
||||
+AXEventGenerator::TargetedEvent::TargetedEvent(AXNodeID node_id,
|
||||
const EventParams& event_params)
|
||||
- : node(node), event_params(event_params) {
|
||||
- DCHECK(node);
|
||||
+ : node_id(node_id), event_params(event_params) {
|
||||
+ DCHECK_NE(node_id, kInvalidAXNodeID);
|
||||
}
|
||||
|
||||
AXEventGenerator::TargetedEvent::~TargetedEvent() = default;
|
||||
@@ -115,8 +115,8 @@ AXEventGenerator::TargetedEvent::~TargetedEvent() = default;
|
||||
//
|
||||
|
||||
AXEventGenerator::Iterator::Iterator(
|
||||
- std::map<AXNode*, std::set<EventParams>>::const_iterator map_start_iter,
|
||||
- std::map<AXNode*, std::set<EventParams>>::const_iterator map_end_iter)
|
||||
+ std::map<AXNodeID, std::set<EventParams>>::const_iterator map_start_iter,
|
||||
+ std::map<AXNodeID, std::set<EventParams>>::const_iterator map_end_iter)
|
||||
: map_iter_(map_start_iter), map_end_iter_(map_end_iter) {
|
||||
if (map_iter_ != map_end_iter_)
|
||||
set_iter_ = map_iter_->second.begin();
|
||||
@@ -180,11 +180,11 @@ void swap(AXEventGenerator::Iterator& lhs, AXEventGenerator::Iterator& rhs) {
|
||||
if (lhs == rhs)
|
||||
return;
|
||||
|
||||
- std::map<AXNode*, std::set<AXEventGenerator::EventParams>>::const_iterator
|
||||
+ std::map<AXNodeID, std::set<AXEventGenerator::EventParams>>::const_iterator
|
||||
map_iter = lhs.map_iter_;
|
||||
lhs.map_iter_ = rhs.map_iter_;
|
||||
rhs.map_iter_ = map_iter;
|
||||
- std::map<AXNode*, std::set<AXEventGenerator::EventParams>>::const_iterator
|
||||
+ std::map<AXNodeID, std::set<AXEventGenerator::EventParams>>::const_iterator
|
||||
map_end_iter = lhs.map_end_iter_;
|
||||
lhs.map_end_iter_ = rhs.map_end_iter_;
|
||||
rhs.map_end_iter_ = map_end_iter;
|
||||
@@ -269,7 +269,7 @@ void AXEventGenerator::AddEvent(AXNode* node, AXEventGenerator::Event event) {
|
||||
if (node->GetRole() == ax::mojom::Role::kInlineTextBox)
|
||||
return;
|
||||
|
||||
- std::set<EventParams>& node_events = tree_events_[node];
|
||||
+ std::set<EventParams>& node_events = tree_events_[node->id()];
|
||||
node_events.emplace(event, ax::mojom::EventFrom::kNone,
|
||||
ax::mojom::Action::kNone, tree_->event_intents());
|
||||
}
|
||||
@@ -742,7 +742,7 @@ void AXEventGenerator::OnNodeWillBeDeleted(AXTree* tree, AXNode* node) {
|
||||
live_region_tracker_->OnNodeWillBeDeleted(*node);
|
||||
|
||||
DCHECK_EQ(tree_, tree);
|
||||
- tree_events_.erase(node);
|
||||
+ tree_events_.erase(node->id());
|
||||
}
|
||||
|
||||
void AXEventGenerator::OnSubtreeWillBeDeleted(AXTree* tree, AXNode* node) {
|
||||
@@ -751,7 +751,7 @@ void AXEventGenerator::OnSubtreeWillBeDeleted(AXTree* tree, AXNode* node) {
|
||||
|
||||
void AXEventGenerator::OnNodeWillBeReparented(AXTree* tree, AXNode* node) {
|
||||
DCHECK_EQ(tree_, tree);
|
||||
- tree_events_.erase(node);
|
||||
+ tree_events_.erase(node->id());
|
||||
}
|
||||
|
||||
void AXEventGenerator::OnSubtreeWillBeReparented(AXTree* tree, AXNode* node) {
|
||||
@@ -826,10 +826,9 @@ void AXEventGenerator::OnAtomicUpdateFinished(
|
||||
}
|
||||
|
||||
void AXEventGenerator::AddEventsForTesting(
|
||||
- AXNode* node,
|
||||
+ const AXNode& node,
|
||||
const std::set<EventParams>& events) {
|
||||
- DCHECK(node);
|
||||
- tree_events_[node] = events;
|
||||
+ tree_events_[node.id()] = events;
|
||||
}
|
||||
|
||||
void AXEventGenerator::FireLiveRegionEvents(AXNode* node) {
|
||||
@@ -953,7 +952,7 @@ void AXEventGenerator::TrimEventsDueToAncestorIgnoredChanged(
|
||||
// IGNORED_CHANGED event.
|
||||
const auto& parent_map_iter =
|
||||
ancestor_ignored_changed_map.find(node->parent());
|
||||
- const auto& curr_events_iter = tree_events_.find(node);
|
||||
+ const auto& curr_events_iter = tree_events_.find(node->id());
|
||||
|
||||
// Initialize |ancestor_ignored_changed_map[node]| with an empty bitset,
|
||||
// representing neither |node| nor its ancestor has IGNORED_CHANGED.
|
||||
@@ -1029,7 +1028,8 @@ void AXEventGenerator::PostprocessEvents() {
|
||||
|
||||
// First pass through |tree_events_|, remove events that we do not need.
|
||||
for (auto& iter : tree_events_) {
|
||||
- AXNode* node = iter.first;
|
||||
+ AXNodeID node_id = iter.first;
|
||||
+ AXNode* node = tree_->GetFromId(node_id);
|
||||
|
||||
// TODO(http://crbug.com/2279799): remove all of the cases that could
|
||||
// add a null node to |tree_events|.
|
||||
@@ -1069,8 +1069,8 @@ void AXEventGenerator::PostprocessEvents() {
|
||||
// Don't fire text attribute changed on this node if its immediate parent
|
||||
// also has text attribute changed.
|
||||
if (parent && HasEvent(node_events, Event::TEXT_ATTRIBUTE_CHANGED) &&
|
||||
- tree_events_.find(parent) != tree_events_.end() &&
|
||||
- HasEvent(tree_events_[parent], Event::TEXT_ATTRIBUTE_CHANGED)) {
|
||||
+ tree_events_.find(parent->id()) != tree_events_.end() &&
|
||||
+ HasEvent(tree_events_[parent->id()], Event::TEXT_ATTRIBUTE_CHANGED)) {
|
||||
RemoveEvent(&node_events, Event::TEXT_ATTRIBUTE_CHANGED);
|
||||
}
|
||||
|
||||
@@ -1080,11 +1080,11 @@ void AXEventGenerator::PostprocessEvents() {
|
||||
// of an existing node. In that instance, we need to inform ATs that the
|
||||
// existing node's parent has changed on the platform.
|
||||
if (HasEvent(node_events, Event::PARENT_CHANGED)) {
|
||||
- while (parent && (tree_events_.find(parent) != tree_events_.end() ||
|
||||
+ while (parent && (tree_events_.find(parent->id()) != tree_events_.end() ||
|
||||
base::Contains(removed_parent_changed_nodes, parent))) {
|
||||
if ((base::Contains(removed_parent_changed_nodes, parent) ||
|
||||
- HasEvent(tree_events_[parent], Event::PARENT_CHANGED)) &&
|
||||
- !HasEvent(tree_events_[parent], Event::SUBTREE_CREATED)) {
|
||||
+ HasEvent(tree_events_[parent->id()], Event::PARENT_CHANGED)) &&
|
||||
+ !HasEvent(tree_events_[parent->id()], Event::SUBTREE_CREATED)) {
|
||||
RemoveEvent(&node_events, Event::PARENT_CHANGED);
|
||||
removed_parent_changed_nodes.insert(node);
|
||||
break;
|
||||
@@ -1098,10 +1098,10 @@ void AXEventGenerator::PostprocessEvents() {
|
||||
parent = node->GetUnignoredParent();
|
||||
if (HasEvent(node_events, Event::SUBTREE_CREATED)) {
|
||||
while (parent &&
|
||||
- (tree_events_.find(parent) != tree_events_.end() ||
|
||||
+ (tree_events_.find(parent->id()) != tree_events_.end() ||
|
||||
base::Contains(removed_subtree_created_nodes, parent))) {
|
||||
if (base::Contains(removed_subtree_created_nodes, parent) ||
|
||||
- HasEvent(tree_events_[parent], Event::SUBTREE_CREATED)) {
|
||||
+ HasEvent(tree_events_[parent->id()], Event::SUBTREE_CREATED)) {
|
||||
RemoveEvent(&node_events, Event::SUBTREE_CREATED);
|
||||
removed_subtree_created_nodes.insert(node);
|
||||
break;
|
||||
diff --git a/ui/accessibility/ax_event_generator.h b/ui/accessibility/ax_event_generator.h
|
||||
index 6464b4af45df9bff10234f81031361d4fb81f22b..64ed33e8d694e33e3bb0900c81edf0e4054dd5b8 100644
|
||||
--- a/ui/accessibility/ax_event_generator.h
|
||||
+++ b/ui/accessibility/ax_event_generator.h
|
||||
@@ -152,11 +152,10 @@ class AX_EXPORT AXEventGenerator : public AXTreeObserver {
|
||||
};
|
||||
|
||||
struct AX_EXPORT TargetedEvent final {
|
||||
- // |node| must not be null.
|
||||
- TargetedEvent(AXNode* node, const EventParams& event_params);
|
||||
+ TargetedEvent(AXNodeID node_id, const EventParams& event_params);
|
||||
~TargetedEvent();
|
||||
|
||||
- AXNode* const node;
|
||||
+ const AXNodeID node_id;
|
||||
const EventParams& event_params;
|
||||
};
|
||||
|
||||
@@ -164,8 +163,9 @@ class AX_EXPORT AXEventGenerator : public AXTreeObserver {
|
||||
: public std::iterator<std::input_iterator_tag, TargetedEvent> {
|
||||
public:
|
||||
Iterator(
|
||||
- std::map<AXNode*, std::set<EventParams>>::const_iterator map_start_iter,
|
||||
- std::map<AXNode*, std::set<EventParams>>::const_iterator map_end_iter);
|
||||
+ std::map<AXNodeID, std::set<EventParams>>::const_iterator
|
||||
+ map_start_iter,
|
||||
+ std::map<AXNodeID, std::set<EventParams>>::const_iterator map_end_iter);
|
||||
Iterator(const Iterator& other);
|
||||
~Iterator();
|
||||
|
||||
@@ -179,8 +179,8 @@ class AX_EXPORT AXEventGenerator : public AXTreeObserver {
|
||||
AX_EXPORT friend bool operator!=(const Iterator& lhs, const Iterator& rhs);
|
||||
AX_EXPORT friend void swap(Iterator& lhs, Iterator& rhs);
|
||||
|
||||
- std::map<AXNode*, std::set<EventParams>>::const_iterator map_iter_;
|
||||
- std::map<AXNode*, std::set<EventParams>>::const_iterator map_end_iter_;
|
||||
+ std::map<AXNodeID, std::set<EventParams>>::const_iterator map_iter_;
|
||||
+ std::map<AXNodeID, std::set<EventParams>>::const_iterator map_end_iter_;
|
||||
std::set<EventParams>::const_iterator set_iter_;
|
||||
};
|
||||
|
||||
@@ -244,7 +244,8 @@ class AX_EXPORT AXEventGenerator : public AXTreeObserver {
|
||||
always_fire_load_complete_ = val;
|
||||
}
|
||||
|
||||
- void AddEventsForTesting(AXNode* node, const std::set<EventParams>& events);
|
||||
+ void AddEventsForTesting(const AXNode& node,
|
||||
+ const std::set<EventParams>& events);
|
||||
|
||||
protected:
|
||||
// AXTreeObserver overrides.
|
||||
@@ -333,7 +334,7 @@ class AX_EXPORT AXEventGenerator : public AXTreeObserver {
|
||||
void PostprocessEvents();
|
||||
|
||||
AXTree* tree_ = nullptr; // Not owned.
|
||||
- std::map<AXNode*, std::set<EventParams>> tree_events_;
|
||||
+ std::map<AXNodeID, std::set<EventParams>> tree_events_;
|
||||
|
||||
// Valid between the call to OnIntAttributeChanged and the call to
|
||||
// OnAtomicUpdateFinished. List of nodes whose active descendant changed.
|
||||
diff --git a/ui/accessibility/ax_event_generator_unittest.cc b/ui/accessibility/ax_event_generator_unittest.cc
|
||||
index bcd037c9e7a133e453fa71346509eaf7483fa9b8..5ab2f61d459c2b4ae04997258ee3efac047ba0a3 100644
|
||||
--- a/ui/accessibility/ax_event_generator_unittest.cc
|
||||
+++ b/ui/accessibility/ax_event_generator_unittest.cc
|
||||
@@ -16,7 +16,7 @@ namespace ui {
|
||||
|
||||
// Required by gmock to print TargetedEvent in a human-readable way.
|
||||
void PrintTo(const AXEventGenerator::TargetedEvent& event, std::ostream* os) {
|
||||
- *os << event.event_params.event << " on " << event.node->id();
|
||||
+ *os << event.event_params.event << " on " << event.node_id;
|
||||
}
|
||||
|
||||
namespace {
|
||||
@@ -37,7 +37,7 @@ MATCHER_P2(HasEventAtNode,
|
||||
PrintToString(expected_node_id)) {
|
||||
const auto& event = arg;
|
||||
return Matches(expected_event_type)(event.event_params.event) &&
|
||||
- Matches(expected_node_id)(event.node->id());
|
||||
+ Matches(expected_node_id)(event.node_id);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@@ -128,15 +128,15 @@ TEST(AXEventGeneratorTest, IterateThroughEmptyEventSets) {
|
||||
// Node9 contains no event.
|
||||
std::set<AXEventGenerator::EventParams> node9_events;
|
||||
|
||||
- event_generator.AddEventsForTesting(node1, node1_events);
|
||||
- event_generator.AddEventsForTesting(node2, node2_events);
|
||||
- event_generator.AddEventsForTesting(node3, node3_events);
|
||||
- event_generator.AddEventsForTesting(node4, node4_events);
|
||||
- event_generator.AddEventsForTesting(node5, node5_events);
|
||||
- event_generator.AddEventsForTesting(node6, node6_events);
|
||||
- event_generator.AddEventsForTesting(node7, node7_events);
|
||||
- event_generator.AddEventsForTesting(node8, node8_events);
|
||||
- event_generator.AddEventsForTesting(node9, node9_events);
|
||||
+ event_generator.AddEventsForTesting(*node1, node1_events);
|
||||
+ event_generator.AddEventsForTesting(*node2, node2_events);
|
||||
+ event_generator.AddEventsForTesting(*node3, node3_events);
|
||||
+ event_generator.AddEventsForTesting(*node4, node4_events);
|
||||
+ event_generator.AddEventsForTesting(*node5, node5_events);
|
||||
+ event_generator.AddEventsForTesting(*node6, node6_events);
|
||||
+ event_generator.AddEventsForTesting(*node7, node7_events);
|
||||
+ event_generator.AddEventsForTesting(*node8, node8_events);
|
||||
+ event_generator.AddEventsForTesting(*node9, node9_events);
|
||||
|
||||
std::map<AXNode*, std::set<AXEventGenerator::Event>> expected_event_map;
|
||||
expected_event_map[node3] = {AXEventGenerator::Event::IGNORED_CHANGED,
|
||||
@@ -145,10 +145,12 @@ TEST(AXEventGeneratorTest, IterateThroughEmptyEventSets) {
|
||||
expected_event_map[node7] = {AXEventGenerator::Event::IGNORED_CHANGED};
|
||||
|
||||
for (const auto& targeted_event : event_generator) {
|
||||
- auto map_iter = expected_event_map.find(targeted_event.node);
|
||||
+ AXNode* node = tree.GetFromId(targeted_event.node_id);
|
||||
+ ASSERT_NE(nullptr, node);
|
||||
+ auto map_iter = expected_event_map.find(node);
|
||||
|
||||
ASSERT_NE(map_iter, expected_event_map.end())
|
||||
- << "|expected_event_map| contains node.id=" << targeted_event.node->id()
|
||||
+ << "|expected_event_map| contains node_id=" << targeted_event.node_id
|
||||
<< "\nExpected: true"
|
||||
<< "\nActual: " << std::boolalpha
|
||||
<< (map_iter != expected_event_map.end());
|
||||
@@ -158,7 +160,7 @@ TEST(AXEventGeneratorTest, IterateThroughEmptyEventSets) {
|
||||
|
||||
ASSERT_NE(event_iter, node_events.end())
|
||||
<< "Event=" << targeted_event.event_params.event
|
||||
- << ", on node.id=" << targeted_event.node->id()
|
||||
+ << ", on node_id=" << targeted_event.node_id
|
||||
<< " NOT found in |expected_event_map|";
|
||||
|
||||
// If the event from |event_generator| is found in |expected_event_map|,
|
||||
diff --git a/ui/accessibility/ax_generated_tree_unittest.cc b/ui/accessibility/ax_generated_tree_unittest.cc
|
||||
index 6c301f68de70757a3abb2a632380e3136d9f183b..d3007e17ef07ec72145ac373ed6fea8d24650d1c 100644
|
||||
--- a/ui/accessibility/ax_generated_tree_unittest.cc
|
||||
+++ b/ui/accessibility/ax_generated_tree_unittest.cc
|
||||
@@ -365,13 +365,15 @@ TEST(AXGeneratedTreeTest, GeneratedTreesWithIgnoredNodes) {
|
||||
// Capture the events generated.
|
||||
std::map<AXNodeID, std::set<AXEventGenerator::Event>> actual_events;
|
||||
for (const AXEventGenerator::TargetedEvent& event : event_generator) {
|
||||
- if (event.node->IsIgnored() ||
|
||||
+ const AXNode* node = fat_tree.GetFromId(event.node_id);
|
||||
+ ASSERT_NE(nullptr, node);
|
||||
+ if (node->IsIgnored() ||
|
||||
event.event_params.event ==
|
||||
AXEventGenerator::Event::IGNORED_CHANGED) {
|
||||
continue;
|
||||
}
|
||||
|
||||
- actual_events[event.node->id()].insert(event.event_params.event);
|
||||
+ actual_events[event.node_id].insert(event.event_params.event);
|
||||
}
|
||||
|
||||
// Now, turn skinny_tree into skinny_tree1 and compare
|
||||
@@ -391,7 +393,7 @@ TEST(AXGeneratedTreeTest, GeneratedTreesWithIgnoredNodes) {
|
||||
std::map<AXNodeID, std::set<AXEventGenerator::Event>> expected_events;
|
||||
for (const AXEventGenerator::TargetedEvent& event :
|
||||
skinny_event_generator)
|
||||
- expected_events[event.node->id()].insert(event.event_params.event);
|
||||
+ expected_events[event.node_id].insert(event.event_params.event);
|
||||
|
||||
for (auto& entry : expected_events) {
|
||||
AXNodeID node_id = entry.first;
|
||||
diff --git a/ui/views/accessibility/views_ax_tree_manager.cc b/ui/views/accessibility/views_ax_tree_manager.cc
|
||||
index 861009afe4fbe956ab63b3f261734a6d9590042b..d999c3cda6c3ef046c80a83f89909d3b8ed3fa38 100644
|
||||
--- a/ui/views/accessibility/views_ax_tree_manager.cc
|
||||
+++ b/ui/views/accessibility/views_ax_tree_manager.cc
|
||||
@@ -185,7 +185,8 @@ void ViewsAXTreeManager::UnserializeTreeUpdates(
|
||||
// AXEventGenerator to generate events based on the updates.
|
||||
for (const ui::AXEventGenerator::TargetedEvent& targeted_event :
|
||||
event_generator_) {
|
||||
- FireGeneratedEvent(targeted_event.event_params.event, *targeted_event.node);
|
||||
+ if (ui::AXNode* node = ax_tree().GetFromId(targeted_event.node_id))
|
||||
+ FireGeneratedEvent(targeted_event.event_params.event, *node);
|
||||
}
|
||||
event_generator_.ClearEvents();
|
||||
}
|
||||
@@ -14,7 +14,7 @@ Note that we also need to manually update embedder's
|
||||
`api::WebContents::IsFullscreenForTabOrPending` value.
|
||||
|
||||
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc
|
||||
index b68c5ee5bd719e15d952a48ff4bc8ef0046e361a..44c089d82fc91462ea986ec63e124ce0cd59e7b7 100644
|
||||
index 19d944da98817b253117c6436099ab4dc7250edb..147ce007ac5cdd4814872a5803c0ce721ea26ff8 100644
|
||||
--- a/content/browser/renderer_host/render_frame_host_impl.cc
|
||||
+++ b/content/browser/renderer_host/render_frame_host_impl.cc
|
||||
@@ -5907,6 +5907,15 @@ void RenderFrameHostImpl::EnterFullscreen(
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
|
||||
"src/electron/patches/boringssl": "src/third_party/boringssl/src",
|
||||
|
||||
"src/electron/patches/devtools_frontend": "src/third_party/devtools-frontend/src",
|
||||
|
||||
"src/electron/patches/webrtc": "src/third_party/webrtc",
|
||||
|
||||
"src/electron/patches/v8": "src/v8",
|
||||
@@ -13,5 +15,7 @@
|
||||
|
||||
"src/electron/patches/Mantle": "src/third_party/squirrel.mac/vendor/Mantle",
|
||||
|
||||
"src/electron/patches/ReactiveObjC": "src/third_party/squirrel.mac/vendor/ReactiveObjC"
|
||||
"src/electron/patches/ReactiveObjC": "src/third_party/squirrel.mac/vendor/ReactiveObjC",
|
||||
|
||||
"src/electron/patches/angle": "src/third_party/angle"
|
||||
}
|
||||
|
||||
1
patches/devtools_frontend/.patches
Normal file
1
patches/devtools_frontend/.patches
Normal file
@@ -0,0 +1 @@
|
||||
revert_include_group_children_if_group_parent_header_is_filtered.patch
|
||||
@@ -0,0 +1,254 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Tim van der Lippe <tvanderlippe@chromium.org>
|
||||
Date: Wed, 27 Oct 2021 11:58:27 +0100
|
||||
Subject: Revert "Include group children if group parent header is filtered"
|
||||
|
||||
This reverts commit cf6a6340628d9d789cab05f97cd8ce0c1c3ef7a5.
|
||||
|
||||
Reason for revert: crbug.com/1263070
|
||||
|
||||
Original change's description:
|
||||
> Include group children if group parent header is filtered
|
||||
>
|
||||
> This CL adds groupParent and groupChildren to consoleMessage. These are used to filter the console message if group parent or child has the filtered text.
|
||||
>
|
||||
> Test link: https://codepen.io/noobtiger/pen/QWpYamX
|
||||
>
|
||||
> Example gif: https://i.imgur.com/8RyRdcI.gif
|
||||
>
|
||||
> Bug:363796
|
||||
> Change-Id: I874c9fd82d72ebb532d14b8b8ec46c529cdfd0b2
|
||||
> Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/3024878
|
||||
> Commit-Queue: Chait Pinnamaneni <cpinnamaneni@microsoft.com>
|
||||
> Reviewed-by: Tim van der Lippe <tvanderlippe@chromium.org>
|
||||
> Reviewed-by: Jack Franklin <jacktfranklin@chromium.org>
|
||||
|
||||
Bug: 363796
|
||||
Fixed: 1263070
|
||||
Change-Id: I8fbc85ddd79cc16c85373d0b1b7fbcb1f0665d10
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/3247430
|
||||
Reviewed-by: Chait Pinnamaneni <cpinnamaneni@microsoft.com>
|
||||
Reviewed-by: Yang Guo <yangguo@chromium.org>
|
||||
Auto-Submit: Tim van der Lippe <tvanderlippe@chromium.org>
|
||||
Commit-Queue: Yang Guo <yangguo@chromium.org>
|
||||
|
||||
diff --git a/front_end/core/sdk/ConsoleModel.ts b/front_end/core/sdk/ConsoleModel.ts
|
||||
index 566e1607d555d8377d10fefb37877e84b38d1934..2e653b45c703bb9c0a1f9700f00196e6f48f19ce 100644
|
||||
--- a/front_end/core/sdk/ConsoleModel.ts
|
||||
+++ b/front_end/core/sdk/ConsoleModel.ts
|
||||
@@ -84,7 +84,6 @@ export class ConsoleModel extends Common.ObjectWrapper.ObjectWrapper<EventTypes>
|
||||
#violationsInternal: number;
|
||||
#pageLoadSequenceNumber: number;
|
||||
readonly #targetListeners: WeakMap<Target, Common.EventTarget.EventDescriptor[]>;
|
||||
- #consoleGroupMessageStack: ConsoleMessage[] = [];
|
||||
|
||||
private constructor() {
|
||||
super();
|
||||
@@ -276,7 +275,6 @@ export class ConsoleModel extends Common.ObjectWrapper.ObjectWrapper<EventTypes>
|
||||
message = call.args[0].description;
|
||||
}
|
||||
const callFrame = call.stackTrace && call.stackTrace.callFrames.length ? call.stackTrace.callFrames[0] : null;
|
||||
- const groupParent = this.#consoleGroupMessageStack[this.#consoleGroupMessageStack.length - 1];
|
||||
const details = {
|
||||
type: call.type,
|
||||
url: callFrame?.url,
|
||||
@@ -287,20 +285,9 @@ export class ConsoleModel extends Common.ObjectWrapper.ObjectWrapper<EventTypes>
|
||||
timestamp: call.timestamp,
|
||||
executionContextId: call.executionContextId,
|
||||
context: call.context,
|
||||
- groupParent,
|
||||
- groupChildren: [],
|
||||
};
|
||||
const consoleMessage =
|
||||
new ConsoleMessage(runtimeModel, FrontendMessageSource.ConsoleAPI, level, (message as string), details);
|
||||
- if (call.type === Protocol.Runtime.ConsoleAPICalledEventType.StartGroup) {
|
||||
- this.#consoleGroupMessageStack.push(consoleMessage);
|
||||
- }
|
||||
- if (call.type === Protocol.Runtime.ConsoleAPICalledEventType.EndGroup) {
|
||||
- this.#consoleGroupMessageStack.pop();
|
||||
- }
|
||||
- if (groupParent && call.type !== Protocol.Runtime.ConsoleAPICalledEventType.EndGroup) {
|
||||
- groupParent.groupChildren?.push(consoleMessage);
|
||||
- }
|
||||
this.addMessage(consoleMessage);
|
||||
}
|
||||
|
||||
@@ -392,7 +379,6 @@ export class ConsoleModel extends Common.ObjectWrapper.ObjectWrapper<EventTypes>
|
||||
|
||||
private clear(): void {
|
||||
this.#messagesInternal = [];
|
||||
- this.#consoleGroupMessageStack = [];
|
||||
this.#messageByExceptionId.clear();
|
||||
this.#errorsInternal = 0;
|
||||
this.#warningsInternal = 0;
|
||||
@@ -518,8 +504,6 @@ export interface ConsoleMessageDetails {
|
||||
workerId?: string;
|
||||
context?: string;
|
||||
affectedResources?: AffectedResources;
|
||||
- groupParent?: ConsoleMessage;
|
||||
- groupChildren?: ConsoleMessage[];
|
||||
category?: Protocol.Log.LogEntryCategory;
|
||||
}
|
||||
|
||||
@@ -543,8 +527,6 @@ export class ConsoleMessage {
|
||||
#pageLoadSequenceNumber?: number = undefined;
|
||||
#exceptionId?: number = undefined;
|
||||
#affectedResources?: AffectedResources;
|
||||
- groupParent?: ConsoleMessage;
|
||||
- groupChildren?: Array<ConsoleMessage>;
|
||||
category?: Protocol.Log.LogEntryCategory;
|
||||
|
||||
constructor(
|
||||
@@ -565,8 +547,6 @@ export class ConsoleMessage {
|
||||
this.scriptId = details?.scriptId;
|
||||
this.workerId = details?.workerId;
|
||||
this.#affectedResources = details?.affectedResources;
|
||||
- this.groupParent = details?.groupParent;
|
||||
- this.groupChildren = details?.groupChildren;
|
||||
this.category = details?.category;
|
||||
|
||||
if (!this.#executionContextId && this.#runtimeModelInternal) {
|
||||
diff --git a/front_end/panels/console/ConsoleFilter.ts b/front_end/panels/console/ConsoleFilter.ts
|
||||
index eb0ebc32a2735905e7c357457a93613685029fb5..8887ff091ab129b3e4ebee5c652155ea30d85ffa 100644
|
||||
--- a/front_end/panels/console/ConsoleFilter.ts
|
||||
+++ b/front_end/panels/console/ConsoleFilter.ts
|
||||
@@ -68,7 +68,7 @@ export class ConsoleFilter {
|
||||
}
|
||||
|
||||
if (message.type === SDK.ConsoleModel.FrontendMessageType.Command ||
|
||||
- message.type === SDK.ConsoleModel.FrontendMessageType.Result) {
|
||||
+ message.type === SDK.ConsoleModel.FrontendMessageType.Result || message.isGroupMessage()) {
|
||||
return true;
|
||||
}
|
||||
if (message.level && !this.levelsMask[message.level as string]) {
|
||||
diff --git a/front_end/panels/console/ConsoleViewMessage.ts b/front_end/panels/console/ConsoleViewMessage.ts
|
||||
index 2f94fe09dfeb7c3eb1921468c663d8a24779caed..e8aa86f8825d4d884b3a4fec2c48186a59679b61 100644
|
||||
--- a/front_end/panels/console/ConsoleViewMessage.ts
|
||||
+++ b/front_end/panels/console/ConsoleViewMessage.ts
|
||||
@@ -1057,25 +1057,8 @@ export class ConsoleViewMessage implements ConsoleViewportElement {
|
||||
}
|
||||
|
||||
matchesFilterText(filter: string): boolean {
|
||||
- return ConsoleViewMessage.recursivelyTestParentConsoleMessage(this.message, filter) ||
|
||||
- ConsoleViewMessage.recursivelyTestChildrenConsoleMessage(this.message, filter);
|
||||
- }
|
||||
-
|
||||
- static recursivelyTestParentConsoleMessage(consoleMessage: SDK.ConsoleModel.ConsoleMessage, filterString: string):
|
||||
- boolean {
|
||||
- const doesFilterMatchText = consoleMessage.messageText.toLowerCase().includes(filterString.toLowerCase());
|
||||
- const doesParentMatchText = consoleMessage.groupParent &&
|
||||
- ConsoleViewMessage.recursivelyTestParentConsoleMessage(consoleMessage.groupParent, filterString);
|
||||
- return Boolean(doesFilterMatchText || doesParentMatchText);
|
||||
- }
|
||||
-
|
||||
- static recursivelyTestChildrenConsoleMessage(consoleMessage: SDK.ConsoleModel.ConsoleMessage, filterString: string):
|
||||
- boolean {
|
||||
- const doesFilterMatchChildren = consoleMessage.groupChildren?.some(childMessage => {
|
||||
- const filterMatch = childMessage.messageText.toLowerCase().includes(filterString.toLowerCase());
|
||||
- return filterMatch || ConsoleViewMessage.recursivelyTestChildrenConsoleMessage(childMessage, filterString);
|
||||
- });
|
||||
- return Boolean(doesFilterMatchChildren);
|
||||
+ const text = this.contentElement().deepTextContent();
|
||||
+ return text.toLowerCase().includes(filter.toLowerCase());
|
||||
}
|
||||
|
||||
updateTimestamp(): void {
|
||||
diff --git a/test/e2e/console/console-filter_test.ts b/test/e2e/console/console-filter_test.ts
|
||||
index f7a01f83a71d5e564b3309bbaf6e570e4039878b..9f782fd58fed06ff3a8f7735c0d10b4126d24c79 100644
|
||||
--- a/test/e2e/console/console-filter_test.ts
|
||||
+++ b/test/e2e/console/console-filter_test.ts
|
||||
@@ -11,6 +11,10 @@ import {CONSOLE_MESSAGE_WRAPPER_SELECTOR, deleteConsoleMessagesFilter, filterCon
|
||||
|
||||
type MessageCheck = (msg: string) => boolean;
|
||||
|
||||
+function toConsoleRegex(regex: string) {
|
||||
+ return regex.replace('\\', '\\\\');
|
||||
+}
|
||||
+
|
||||
function createUrlFilter(url: string) {
|
||||
return `-url:${url}`;
|
||||
}
|
||||
@@ -25,6 +29,10 @@ function collectSourceUrlsFromConsoleOutput(frontend: puppeteer.Page) {
|
||||
|
||||
function getExpectedMessages(unfilteredMessages: string[], filter: MessageCheck) {
|
||||
return unfilteredMessages.filter((msg: string) => {
|
||||
+ // console.group() outputs are not filtered
|
||||
+ if (/outerGroup$|innerGroup$/.test(msg)) {
|
||||
+ return true;
|
||||
+ }
|
||||
return filter(msg);
|
||||
});
|
||||
}
|
||||
@@ -157,7 +165,7 @@ describe('The Console Tab', async () => {
|
||||
});
|
||||
|
||||
for (const urlToKeep of uniqueUrls) {
|
||||
- const filter = `url:${urlToKeep}`;
|
||||
+ const filter = urlToKeep;
|
||||
const expectedMessageFilter: MessageCheck = msg => {
|
||||
return msg.indexOf(urlToKeep) !== -1;
|
||||
};
|
||||
@@ -179,19 +187,18 @@ describe('The Console Tab', async () => {
|
||||
it('can apply text filter', async () => {
|
||||
const filter = 'outer';
|
||||
const expectedMessageFilter: MessageCheck = msg => {
|
||||
- // With new implementation of console group filtering, we also include child messages
|
||||
- // if parent group is filtered.
|
||||
- return msg.indexOf(filter) !== -1 || msg.indexOf('inner') !== -1;
|
||||
+ return msg.indexOf(filter) !== -1;
|
||||
};
|
||||
await testMessageFilter(filter, expectedMessageFilter);
|
||||
});
|
||||
|
||||
it('can apply start/end line regex filter', async () => {
|
||||
- const filter = new RegExp(/.*Hello\s\d$/);
|
||||
+ const filter = '/^Hello\s\d$/';
|
||||
const expectedMessageFilter: MessageCheck = msg => {
|
||||
- return filter.test(msg);
|
||||
+ const regExp = new RegExp(filter);
|
||||
+ return regExp.test(msg);
|
||||
};
|
||||
- await testMessageFilter(filter.toString(), expectedMessageFilter);
|
||||
+ await testMessageFilter(toConsoleRegex(filter), expectedMessageFilter);
|
||||
});
|
||||
|
||||
it('can apply context filter', async () => {
|
||||
@@ -210,11 +217,12 @@ describe('The Console Tab', async () => {
|
||||
});
|
||||
|
||||
it('can apply filter on anchor', async () => {
|
||||
- const filter = new RegExp(/.*log-source\.js:\d+/);
|
||||
+ const filter = '/^log-source\.js:\d+$/';
|
||||
const expectedMessageFilter: MessageCheck = msg => {
|
||||
- return filter.test(msg);
|
||||
+ const regex = new RegExp(filter.replace('$', ''));
|
||||
+ return regex.test(msg);
|
||||
};
|
||||
- await testMessageFilter(filter.toString(), expectedMessageFilter);
|
||||
+ await testMessageFilter(toConsoleRegex(filter), expectedMessageFilter);
|
||||
});
|
||||
|
||||
it('can reset filter', async () => {
|
||||
@@ -239,22 +247,6 @@ describe('The Console Tab', async () => {
|
||||
});
|
||||
});
|
||||
|
||||
- it('will show group parent message if child is filtered', async () => {
|
||||
- const filter = '1outerGroup';
|
||||
- const expectedMessageFilter: MessageCheck = msg => {
|
||||
- return new RegExp(/.* (1|)outerGroup.*$/).test(msg);
|
||||
- };
|
||||
- await testMessageFilter(filter, expectedMessageFilter);
|
||||
- });
|
||||
-
|
||||
- it('will show messages in group if group name is filtered', async () => {
|
||||
- const filter = 'innerGroup';
|
||||
- const expectedMessageFilter: MessageCheck = msg => {
|
||||
- return msg.indexOf(filter) !== -1 || new RegExp(/.* outerGroup.*$/).test(msg);
|
||||
- };
|
||||
- await testMessageFilter(filter, expectedMessageFilter);
|
||||
- });
|
||||
-
|
||||
it('can exclude CORS error messages', async () => {
|
||||
const CORS_DETAILED_ERROR_PATTERN =
|
||||
/Access to fetch at 'https:.*' from origin 'https:.*' has been blocked by CORS policy: .*/;
|
||||
@@ -30,3 +30,6 @@ test_fix_test-datetime-change-notify_after_daylight_change.patch
|
||||
test_add_fixture_trim_option.patch
|
||||
fix_crash_caused_by_gethostnamew_on_windows_7.patch
|
||||
fix_don_t_create_console_window_when_creating_process.patch
|
||||
darwin_remove_eprototype_error_workaround_3405.patch
|
||||
darwin_translate_eprototype_to_econnreset_3413.patch
|
||||
darwin_bump_minimum_supported_version_to_10_15_3406.patch
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Ben Noordhuis <info@bnoordhuis.nl>
|
||||
Date: Tue, 8 Feb 2022 14:18:29 +0100
|
||||
Subject: darwin: bump minimum supported version to 10.15 (#3406)
|
||||
|
||||
We can't realistically claim to support 10.7 or any version that Apple
|
||||
no longer supports so let's bump the baseline to something more
|
||||
realistic.
|
||||
|
||||
Refs: https://github.com/libuv/libuv/pull/482
|
||||
Refs: https://github.com/libuv/libuv/pull/3405
|
||||
|
||||
diff --git a/deps/uv/SUPPORTED_PLATFORMS.md b/deps/uv/SUPPORTED_PLATFORMS.md
|
||||
index 30e0ea617a6fcaa5b4b7c7c5b117652e61f367d3..dc57dfb12dc7ddf8d29308ac44f46084a933d5ca 100644
|
||||
--- a/deps/uv/SUPPORTED_PLATFORMS.md
|
||||
+++ b/deps/uv/SUPPORTED_PLATFORMS.md
|
||||
@@ -3,7 +3,7 @@
|
||||
| System | Support type | Supported versions | Notes |
|
||||
|---|---|---|---|
|
||||
| GNU/Linux | Tier 1 | Linux >= 2.6.32 with glibc >= 2.12 | |
|
||||
-| macOS | Tier 1 | macOS >= 10.7 | |
|
||||
+| macOS | Tier 1 | macOS >= 10.15 | Current and previous macOS release |
|
||||
| Windows | Tier 1 | >= Windows 8 | VS 2015 and later are supported |
|
||||
| FreeBSD | Tier 1 | >= 10 | |
|
||||
| AIX | Tier 2 | >= 6 | Maintainers: @libuv/aix |
|
||||
@@ -0,0 +1,65 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Ben Noordhuis <info@bnoordhuis.nl>
|
||||
Date: Sun, 9 Jan 2022 12:20:15 +0100
|
||||
Subject: darwin: remove EPROTOTYPE error workaround (#3405)
|
||||
|
||||
It's been reported in the past that OS X 10.10, because of a race
|
||||
condition in the XNU kernel, sometimes returns a transient EPROTOTYPE
|
||||
error when trying to write to a socket. Libuv handles that by retrying
|
||||
the operation until it succeeds or fails with a different error.
|
||||
|
||||
Recently it's been reported that current versions of the operating
|
||||
system formerly known as OS X fail permanently with EPROTOTYPE under
|
||||
certain conditions, resulting in an infinite loop.
|
||||
|
||||
Because Apple isn't exactly forthcoming with bug fixes or even details,
|
||||
I'm opting to simply remove the workaround and have the error bubble up.
|
||||
|
||||
Refs: https://github.com/libuv/libuv/pull/482
|
||||
|
||||
diff --git a/deps/uv/src/unix/stream.c b/deps/uv/src/unix/stream.c
|
||||
index bc64fe8f44b26d9f4c0d4d0d282b65cdf11a531b..1af448e7691392c3f7794eed1905d9132394e207 100644
|
||||
--- a/deps/uv/src/unix/stream.c
|
||||
+++ b/deps/uv/src/unix/stream.c
|
||||
@@ -58,20 +58,6 @@ struct uv__stream_select_s {
|
||||
fd_set* swrite;
|
||||
size_t swrite_sz;
|
||||
};
|
||||
-
|
||||
-/* Due to a possible kernel bug at least in OS X 10.10 "Yosemite",
|
||||
- * EPROTOTYPE can be returned while trying to write to a socket that is
|
||||
- * shutting down. If we retry the write, we should get the expected EPIPE
|
||||
- * instead.
|
||||
- */
|
||||
-# define RETRY_ON_WRITE_ERROR(errno) (errno == EINTR || errno == EPROTOTYPE)
|
||||
-# define IS_TRANSIENT_WRITE_ERROR(errno, send_handle) \
|
||||
- (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS || \
|
||||
- (errno == EMSGSIZE && send_handle != NULL))
|
||||
-#else
|
||||
-# define RETRY_ON_WRITE_ERROR(errno) (errno == EINTR)
|
||||
-# define IS_TRANSIENT_WRITE_ERROR(errno, send_handle) \
|
||||
- (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS)
|
||||
#endif /* defined(__APPLE__) */
|
||||
|
||||
static void uv__stream_connect(uv_stream_t*);
|
||||
@@ -866,17 +852,17 @@ static int uv__try_write(uv_stream_t* stream,
|
||||
|
||||
do
|
||||
n = sendmsg(uv__stream_fd(stream), &msg, 0);
|
||||
- while (n == -1 && RETRY_ON_WRITE_ERROR(errno));
|
||||
+ while (n == -1 && errno == EINTR);
|
||||
} else {
|
||||
do
|
||||
n = uv__writev(uv__stream_fd(stream), iov, iovcnt);
|
||||
- while (n == -1 && RETRY_ON_WRITE_ERROR(errno));
|
||||
+ while (n == -1 && errno == EINTR);
|
||||
}
|
||||
|
||||
if (n >= 0)
|
||||
return n;
|
||||
|
||||
- if (IS_TRANSIENT_WRITE_ERROR(errno, send_handle))
|
||||
+ if (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS)
|
||||
return UV_EAGAIN;
|
||||
|
||||
return UV__ERR(errno);
|
||||
@@ -0,0 +1,44 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Ben Noordhuis <info@bnoordhuis.nl>
|
||||
Date: Wed, 12 Jan 2022 16:11:43 +0100
|
||||
Subject: darwin: translate EPROTOTYPE to ECONNRESET (#3413)
|
||||
|
||||
macOS versions 10.10 and 10.15 - and presumbaly 10.11 to 10.14, too -
|
||||
have a bug where a race condition causes the kernel to return EPROTOTYPE
|
||||
because the socket isn't fully constructed.
|
||||
|
||||
It's probably the result of the peer closing the connection and that is
|
||||
why libuv translates it to ECONNRESET.
|
||||
|
||||
Previously, libuv retried until the EPROTOTYPE error went away but some
|
||||
VPN software causes the same behavior except the error is permanent, not
|
||||
transient, turning the retry mechanism into an infinite loop.
|
||||
|
||||
Refs: https://github.com/libuv/libuv/pull/482
|
||||
Refs: https://github.com/libuv/libuv/pull/3405
|
||||
|
||||
diff --git a/deps/uv/src/unix/stream.c b/deps/uv/src/unix/stream.c
|
||||
index 1af448e7691392c3f7794eed1905d9132394e207..9d22debf2bf5bd5912ade152e55a85ad652e3819 100644
|
||||
--- a/deps/uv/src/unix/stream.c
|
||||
+++ b/deps/uv/src/unix/stream.c
|
||||
@@ -865,6 +865,20 @@ static int uv__try_write(uv_stream_t* stream,
|
||||
if (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS)
|
||||
return UV_EAGAIN;
|
||||
|
||||
+#ifdef __APPLE__
|
||||
+ /* macOS versions 10.10 and 10.15 - and presumbaly 10.11 to 10.14, too -
|
||||
+ * have a bug where a race condition causes the kernel to return EPROTOTYPE
|
||||
+ * because the socket isn't fully constructed. It's probably the result of
|
||||
+ * the peer closing the connection and that is why libuv translates it to
|
||||
+ * ECONNRESET. Previously, libuv retried until the EPROTOTYPE error went
|
||||
+ * away but some VPN software causes the same behavior except the error is
|
||||
+ * permanent, not transient, turning the retry mechanism into an infinite
|
||||
+ * loop. See https://github.com/libuv/libuv/pull/482.
|
||||
+ */
|
||||
+ if (errno == EPROTOTYPE)
|
||||
+ return UV_ECONNRESET;
|
||||
+#endif /* __APPLE__ */
|
||||
+
|
||||
return UV__ERR(errno);
|
||||
}
|
||||
|
||||
@@ -6,3 +6,7 @@ workaround_an_undefined_symbol_error.patch
|
||||
do_not_export_private_v8_symbols_on_windows.patch
|
||||
fix_build_deprecated_attirbute_for_older_msvc_versions.patch
|
||||
fix_disable_implies_dcheck_for_node_stream_array_buffers.patch
|
||||
skip_non-compilation_functions_in_optimizeosr.patch
|
||||
cherry-pick-27bc67f761e6.patch
|
||||
regexp_arm_fix_regexp_assembler_abortion.patch
|
||||
regexp_ensure_regress-1255368_runs_only_with_irregexp.patch
|
||||
|
||||
253
patches/v8/cherry-pick-27bc67f761e6.patch
Normal file
253
patches/v8/cherry-pick-27bc67f761e6.patch
Normal file
@@ -0,0 +1,253 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jakob Gruber <jgruber@chromium.org>
|
||||
Date: Thu, 13 Jan 2022 08:01:37 +0100
|
||||
Subject: Merged: [maps] Lock map_updater_access in
|
||||
CompleteInobjectSlackTracking
|
||||
|
||||
CompleteInobjectSlackTracking potentially shrinks multiple maps, and
|
||||
the relation between these maps should be preserved in a concurrent
|
||||
environment. Thus it is not enough to make each modification
|
||||
atomically, but all related map modifications must be within a
|
||||
critical section.
|
||||
|
||||
We do this by locking the map_updater_access mutex
|
||||
CompleteInobjectSlackTracking, and hence moving the function to the
|
||||
MapUpdater class.
|
||||
|
||||
(cherry picked from commit 4b8d04897cba70cac45eea33d78fa2354dfe2bd7)
|
||||
|
||||
No-Try: true
|
||||
No-Presubmit: true
|
||||
No-Treechecks: true
|
||||
Bug: chromium:1274445,v8:7990
|
||||
Change-Id: If99bb8b55e03180128ee397d845fa4c269c4241e
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3379819
|
||||
Reviewed-by: Igor Sheludko <ishell@chromium.org>
|
||||
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#78597}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3406537
|
||||
Cr-Commit-Position: refs/branch-heads/9.8@{#16}
|
||||
Cr-Branched-From: e218afa8473132b56a9e1532be7920dd130aeb7e-refs/heads/9.8.177@{#1}
|
||||
Cr-Branched-From: 86ebfc969cde382122a4d429f2380f06175ea2a8-refs/heads/main@{#78312}
|
||||
|
||||
diff --git a/src/objects/js-function-inl.h b/src/objects/js-function-inl.h
|
||||
index 15634b8f024705481e5f0da5008231c1e6ca2f0d..eddedfeabfb48f39418342c8d0044c941f449a5b 100644
|
||||
--- a/src/objects/js-function-inl.h
|
||||
+++ b/src/objects/js-function-inl.h
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "src/ic/ic.h"
|
||||
#include "src/init/bootstrapper.h"
|
||||
#include "src/objects/feedback-cell-inl.h"
|
||||
+#include "src/objects/map-updater.h"
|
||||
#include "src/objects/shared-function-info-inl.h"
|
||||
|
||||
// Has to be the last include (doesn't have include guards):
|
||||
@@ -124,7 +125,7 @@ bool JSFunction::IsInOptimizationQueue() {
|
||||
void JSFunction::CompleteInobjectSlackTrackingIfActive() {
|
||||
if (!has_prototype_slot()) return;
|
||||
if (has_initial_map() && initial_map().IsInobjectSlackTrackingInProgress()) {
|
||||
- initial_map().CompleteInobjectSlackTracking(GetIsolate());
|
||||
+ MapUpdater::CompleteInobjectSlackTracking(GetIsolate(), initial_map());
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/src/objects/map-inl.h b/src/objects/map-inl.h
|
||||
index c8eb40042410a684306ddb7fde69cff57ab146ce..5156cd9d9f4a5fed832466b16589c08ddd4c4faf 100644
|
||||
--- a/src/objects/map-inl.h
|
||||
+++ b/src/objects/map-inl.h
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "src/objects/field-type.h"
|
||||
#include "src/objects/instance-type-inl.h"
|
||||
#include "src/objects/js-function-inl.h"
|
||||
+#include "src/objects/map-updater.h"
|
||||
#include "src/objects/map.h"
|
||||
#include "src/objects/objects-inl.h"
|
||||
#include "src/objects/property.h"
|
||||
@@ -856,7 +857,7 @@ void Map::InobjectSlackTrackingStep(Isolate* isolate) {
|
||||
int counter = construction_counter();
|
||||
set_construction_counter(counter - 1);
|
||||
if (counter == kSlackTrackingCounterEnd) {
|
||||
- CompleteInobjectSlackTracking(isolate);
|
||||
+ MapUpdater::CompleteInobjectSlackTracking(isolate, *this);
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/src/objects/map-updater.cc b/src/objects/map-updater.cc
|
||||
index 3bfd3922a3dc2119250c20b97ac1d5061cae74db..21f2665454ae121ac448ad0df9c7d5459c72650d 100644
|
||||
--- a/src/objects/map-updater.cc
|
||||
+++ b/src/objects/map-updater.cc
|
||||
@@ -420,21 +420,50 @@ MapUpdater::State MapUpdater::Normalize(const char* reason) {
|
||||
return state_; // Done.
|
||||
}
|
||||
|
||||
-void MapUpdater::ShrinkInstanceSize(base::SharedMutex* map_updater_access,
|
||||
- Map map, int slack) {
|
||||
+// static
|
||||
+void MapUpdater::CompleteInobjectSlackTracking(Isolate* isolate,
|
||||
+ Map initial_map) {
|
||||
+ DisallowGarbageCollection no_gc;
|
||||
+ // Has to be an initial map.
|
||||
+ DCHECK(initial_map.GetBackPointer().IsUndefined(isolate));
|
||||
+
|
||||
+ const int slack = initial_map.ComputeMinObjectSlack(isolate);
|
||||
DCHECK_GE(slack, 0);
|
||||
+
|
||||
+ TransitionsAccessor transitions(isolate, initial_map, &no_gc);
|
||||
+ TransitionsAccessor::TraverseCallback callback;
|
||||
+ if (slack != 0) {
|
||||
+ // Resize the initial map and all maps in its transition tree.
|
||||
+ callback = [slack](Map map) {
|
||||
#ifdef DEBUG
|
||||
- int old_visitor_id = Map::GetVisitorId(map);
|
||||
- int new_unused = map.UnusedPropertyFields() - slack;
|
||||
+ int old_visitor_id = Map::GetVisitorId(map);
|
||||
+ int new_unused = map.UnusedPropertyFields() - slack;
|
||||
#endif
|
||||
+ map.set_instance_size(map.InstanceSizeFromSlack(slack));
|
||||
+ map.set_construction_counter(Map::kNoSlackTracking);
|
||||
+ DCHECK_EQ(old_visitor_id, Map::GetVisitorId(map));
|
||||
+ DCHECK_EQ(new_unused, map.UnusedPropertyFields());
|
||||
+ };
|
||||
+ } else {
|
||||
+ // Stop slack tracking for this map.
|
||||
+ callback = [](Map map) {
|
||||
+ map.set_construction_counter(Map::kNoSlackTracking);
|
||||
+ };
|
||||
+ }
|
||||
|
||||
{
|
||||
- base::SharedMutexGuard<base::kExclusive> mutex_guard(map_updater_access);
|
||||
- map.set_instance_size(map.InstanceSizeFromSlack(slack));
|
||||
+ // The map_updater_access lock is taken here to guarantee atomicity of all
|
||||
+ // related map changes (instead of guaranteeing only atomicity of each
|
||||
+ // single map change). This is needed e.g. by InstancesNeedsRewriting,
|
||||
+ // which expects certain relations between maps to hold.
|
||||
+ //
|
||||
+ // Note: Avoid locking the full_transition_array_access lock inside this
|
||||
+ // call to TraverseTransitionTree to prevent dependencies between the two
|
||||
+ // locks.
|
||||
+ base::SharedMutexGuard<base::kExclusive> mutex_guard(
|
||||
+ isolate->map_updater_access());
|
||||
+ transitions.TraverseTransitionTree(callback);
|
||||
}
|
||||
- map.set_construction_counter(Map::kNoSlackTracking);
|
||||
- DCHECK_EQ(old_visitor_id, Map::GetVisitorId(map));
|
||||
- DCHECK_EQ(new_unused, map.UnusedPropertyFields());
|
||||
}
|
||||
|
||||
MapUpdater::State MapUpdater::TryReconfigureToDataFieldInplace() {
|
||||
diff --git a/src/objects/map-updater.h b/src/objects/map-updater.h
|
||||
index 6f022e1d39f7222904143eb93b24a98d68ca9286..7136532bbe1c8ad97a86232110ea563ee281c3af 100644
|
||||
--- a/src/objects/map-updater.h
|
||||
+++ b/src/objects/map-updater.h
|
||||
@@ -86,8 +86,9 @@ class V8_EXPORT_PRIVATE MapUpdater {
|
||||
Representation new_representation,
|
||||
Handle<FieldType> new_field_type);
|
||||
|
||||
- static void ShrinkInstanceSize(base::SharedMutex* map_updater_access, Map map,
|
||||
- int slack);
|
||||
+ // Completes inobject slack tracking for the transition tree starting at the
|
||||
+ // initial map.
|
||||
+ static void CompleteInobjectSlackTracking(Isolate* isolate, Map initial_map);
|
||||
|
||||
private:
|
||||
enum State {
|
||||
diff --git a/src/objects/map.cc b/src/objects/map.cc
|
||||
index 0610e5968802753438b6e812a09a85400742892d..f1c52d69ad800d7345b64cf722e894f583da6517 100644
|
||||
--- a/src/objects/map.cc
|
||||
+++ b/src/objects/map.cc
|
||||
@@ -2133,28 +2133,6 @@ int Map::ComputeMinObjectSlack(Isolate* isolate) {
|
||||
return slack;
|
||||
}
|
||||
|
||||
-void Map::CompleteInobjectSlackTracking(Isolate* isolate) {
|
||||
- DisallowGarbageCollection no_gc;
|
||||
- // Has to be an initial map.
|
||||
- DCHECK(GetBackPointer().IsUndefined(isolate));
|
||||
-
|
||||
- int slack = ComputeMinObjectSlack(isolate);
|
||||
- TransitionsAccessor transitions(isolate, *this, &no_gc);
|
||||
- TransitionsAccessor::TraverseCallback callback;
|
||||
- if (slack != 0) {
|
||||
- // Resize the initial map and all maps in its transition tree.
|
||||
- callback = [&](Map map) {
|
||||
- MapUpdater::ShrinkInstanceSize(isolate->map_updater_access(), map, slack);
|
||||
- };
|
||||
- } else {
|
||||
- callback = [](Map map) {
|
||||
- // Stop slack tracking for this map.
|
||||
- map.set_construction_counter(Map::kNoSlackTracking);
|
||||
- };
|
||||
- }
|
||||
- transitions.TraverseTransitionTree(callback);
|
||||
-}
|
||||
-
|
||||
void Map::SetInstanceDescriptors(Isolate* isolate, DescriptorArray descriptors,
|
||||
int number_of_own_descriptors) {
|
||||
set_instance_descriptors(descriptors, kReleaseStore);
|
||||
diff --git a/src/objects/map.h b/src/objects/map.h
|
||||
index d60890d9103e352215d8afda9c1c8f952b5ad2be..a8655262155ce897f3f2c36211336ae190c7e334 100644
|
||||
--- a/src/objects/map.h
|
||||
+++ b/src/objects/map.h
|
||||
@@ -352,10 +352,6 @@ class Map : public TorqueGeneratedMap<Map, HeapObject> {
|
||||
int ComputeMinObjectSlack(Isolate* isolate);
|
||||
inline int InstanceSizeFromSlack(int slack) const;
|
||||
|
||||
- // Completes inobject slack tracking for the transition tree starting at this
|
||||
- // initial map.
|
||||
- V8_EXPORT_PRIVATE void CompleteInobjectSlackTracking(Isolate* isolate);
|
||||
-
|
||||
// Tells whether the object in the prototype property will be used
|
||||
// for instances created from this function. If the prototype
|
||||
// property is set to a value that is not a JSObject, the prototype
|
||||
diff --git a/src/runtime/runtime-object.cc b/src/runtime/runtime-object.cc
|
||||
index 3da21358d80fafbd8a7cc5f0d485bf417a26e27c..3c29f13814b4442dd11bbed711047f911be2015b 100644
|
||||
--- a/src/runtime/runtime-object.cc
|
||||
+++ b/src/runtime/runtime-object.cc
|
||||
@@ -990,7 +990,7 @@ RUNTIME_FUNCTION(Runtime_CompleteInobjectSlackTrackingForMap) {
|
||||
DCHECK_EQ(1, args.length());
|
||||
|
||||
CONVERT_ARG_HANDLE_CHECKED(Map, initial_map, 0);
|
||||
- initial_map->CompleteInobjectSlackTracking(isolate);
|
||||
+ MapUpdater::CompleteInobjectSlackTracking(isolate, *initial_map);
|
||||
|
||||
return ReadOnlyRoots(isolate).undefined_value();
|
||||
}
|
||||
diff --git a/src/runtime/runtime-test.cc b/src/runtime/runtime-test.cc
|
||||
index 5e5d997d6903dd5b0dd55b2fadef8b4dee9581be..aec12d3aefd8e6821a3c50633ae7dad6d61ea4f8 100644
|
||||
--- a/src/runtime/runtime-test.cc
|
||||
+++ b/src/runtime/runtime-test.cc
|
||||
@@ -1333,7 +1333,7 @@ RUNTIME_FUNCTION(Runtime_CompleteInobjectSlackTracking) {
|
||||
DCHECK_EQ(1, args.length());
|
||||
|
||||
CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
|
||||
- object->map().CompleteInobjectSlackTracking(isolate);
|
||||
+ MapUpdater::CompleteInobjectSlackTracking(isolate, object->map());
|
||||
|
||||
return ReadOnlyRoots(isolate).undefined_value();
|
||||
}
|
||||
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
|
||||
index 61398f2c5ea6cd4bbc57403eb0ddf97d2fb5f575..4b64d307887d28c844b08e9e0524e03fc2dd4183 100644
|
||||
--- a/test/cctest/test-api.cc
|
||||
+++ b/test/cctest/test-api.cc
|
||||
@@ -70,6 +70,7 @@
|
||||
#include "src/objects/js-array-inl.h"
|
||||
#include "src/objects/js-promise-inl.h"
|
||||
#include "src/objects/lookup.h"
|
||||
+#include "src/objects/map-updater.h"
|
||||
#include "src/objects/module-inl.h"
|
||||
#include "src/objects/objects-inl.h"
|
||||
#include "src/objects/string-inl.h"
|
||||
@@ -2981,9 +2982,9 @@ TEST(InternalFieldsSubclassing) {
|
||||
CHECK_LE(i_value->map().GetInObjectProperties(), kMaxNofProperties);
|
||||
}
|
||||
|
||||
- // Make Sure we get the precise property count.
|
||||
- i_value->map().FindRootMap(i_isolate).CompleteInobjectSlackTracking(
|
||||
- i_isolate);
|
||||
+ // Make sure we get the precise property count.
|
||||
+ i::MapUpdater::CompleteInobjectSlackTracking(
|
||||
+ i_isolate, i_value->map().FindRootMap(i_isolate));
|
||||
// TODO(cbruni): fix accounting to make this condition true.
|
||||
// CHECK_EQ(0, i_value->map()->UnusedPropertyFields());
|
||||
if (in_object_only) {
|
||||
@@ -18,7 +18,7 @@ This patch can be removed when streams support rab/gsab, or
|
||||
when support is synchronized across both v8 and node.
|
||||
|
||||
diff --git a/src/objects/js-array-buffer.cc b/src/objects/js-array-buffer.cc
|
||||
index 07b37dd7f5a76c13fe6f8a55fd4a93fa813d81a6..ad0e4610b7f9adc64d996800e5fdb0c6f1a58562 100644
|
||||
index fd9f3133a5fefb6d7b4b310c855cb87c8a84e9aa..b8b93351f0877df27b2dc34a2e149638ca8c9110 100644
|
||||
--- a/src/objects/js-array-buffer.cc
|
||||
+++ b/src/objects/js-array-buffer.cc
|
||||
@@ -72,9 +72,9 @@ void JSArrayBuffer::Attach(std::shared_ptr<BackingStore> backing_store) {
|
||||
|
||||
68
patches/v8/regexp_arm_fix_regexp_assembler_abortion.patch
Normal file
68
patches/v8/regexp_arm_fix_regexp_assembler_abortion.patch
Normal file
@@ -0,0 +1,68 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Clemens Backes <clemensb@chromium.org>
|
||||
Date: Tue, 5 Oct 2021 13:37:34 +0200
|
||||
Subject: Fix regexp assembler abortion
|
||||
|
||||
When aborting code generation, we need to call {AbortedCodeGeneration}
|
||||
on the {MacroAssembler} contained in the {RegExpMacroAssemblerARM}.
|
||||
|
||||
R=jgruber@chromium.org
|
||||
|
||||
Bug: chromium:1255368
|
||||
Change-Id: If37351e8f5715e23affd21ad2de8a8eaad3ea094
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3204965
|
||||
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
|
||||
Commit-Queue: Clemens Backes <clemensb@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/main@{#77250}
|
||||
|
||||
diff --git a/src/regexp/arm/regexp-macro-assembler-arm.cc b/src/regexp/arm/regexp-macro-assembler-arm.cc
|
||||
index f21ee023da951354c035b0bf2d9be29e77c9b6af..7d30c4be24eef7fbfb8e523807619dcedcf87202 100644
|
||||
--- a/src/regexp/arm/regexp-macro-assembler-arm.cc
|
||||
+++ b/src/regexp/arm/regexp-macro-assembler-arm.cc
|
||||
@@ -112,7 +112,10 @@ RegExpMacroAssemblerARM::RegExpMacroAssemblerARM(Isolate* isolate, Zone* zone,
|
||||
__ bind(&start_label_); // And then continue from here.
|
||||
}
|
||||
|
||||
-RegExpMacroAssemblerARM::~RegExpMacroAssemblerARM() {
|
||||
+RegExpMacroAssemblerARM::~RegExpMacroAssemblerARM() = default;
|
||||
+
|
||||
+void RegExpMacroAssemblerARM::AbortedCodeGeneration() {
|
||||
+ masm_->AbortedCodeGeneration();
|
||||
// Unuse labels in case we throw away the assembler without calling GetCode.
|
||||
entry_label_.Unuse();
|
||||
start_label_.Unuse();
|
||||
@@ -124,7 +127,6 @@ RegExpMacroAssemblerARM::~RegExpMacroAssemblerARM() {
|
||||
fallback_label_.Unuse();
|
||||
}
|
||||
|
||||
-
|
||||
int RegExpMacroAssemblerARM::stack_limit_slack() {
|
||||
return RegExpStack::kStackLimitSlack;
|
||||
}
|
||||
diff --git a/src/regexp/arm/regexp-macro-assembler-arm.h b/src/regexp/arm/regexp-macro-assembler-arm.h
|
||||
index 478ed292ae95235a8aa4b44efc1f4ad8d07c20fc..1446fa69821a078d45b802288c8fcafa7d4311b6 100644
|
||||
--- a/src/regexp/arm/regexp-macro-assembler-arm.h
|
||||
+++ b/src/regexp/arm/regexp-macro-assembler-arm.h
|
||||
@@ -17,6 +17,7 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerARM
|
||||
RegExpMacroAssemblerARM(Isolate* isolate, Zone* zone, Mode mode,
|
||||
int registers_to_save);
|
||||
virtual ~RegExpMacroAssemblerARM();
|
||||
+ virtual void AbortedCodeGeneration();
|
||||
virtual int stack_limit_slack();
|
||||
virtual void AdvanceCurrentPosition(int by);
|
||||
virtual void AdvanceRegister(int reg, int by);
|
||||
diff --git a/test/mjsunit/regress/regress-1255368.js b/test/mjsunit/regress/regress-1255368.js
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..9284c5893ceb1d99d427870e9f0a287b4c725a65
|
||||
--- /dev/null
|
||||
+++ b/test/mjsunit/regress/regress-1255368.js
|
||||
@@ -0,0 +1,9 @@
|
||||
+// Copyright 2021 the V8 project authors. All rights reserved.
|
||||
+// Use of this source code is governed by a BSD-style license that can be
|
||||
+// found in the LICENSE file.
|
||||
+
|
||||
+// Flags: --no-regexp-tier-up
|
||||
+
|
||||
+const arr = new Array(20000).fill([1]);
|
||||
+const regexp = RegExp(JSON.stringify(arr));
|
||||
+assertThrows(() => regexp.exec(), SyntaxError, /Regular expression too large/);
|
||||
@@ -0,0 +1,42 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jakob Gruber <jgruber@chromium.org>
|
||||
Date: Wed, 6 Oct 2021 13:01:34 +0200
|
||||
Subject: Ensure regress-1255368 runs only with irregexp
|
||||
|
||||
The expected assertion is specific to irregexp codegen.
|
||||
|
||||
Bug: chromium:1255368
|
||||
Change-Id: I14d033285014727de2e63582ed798fc82570497d
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3207892
|
||||
Auto-Submit: Jakob Gruber <jgruber@chromium.org>
|
||||
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
|
||||
Reviewed-by: Clemens Backes <clemensb@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/main@{#77254}
|
||||
|
||||
diff --git a/test/mjsunit/regress/regress-1255368.js b/test/mjsunit/regress/regress-1255368.js
|
||||
index 9284c5893ceb1d99d427870e9f0a287b4c725a65..7b4fb334ac7fa6adc3cb3af04dd3bb0ca72e3302 100644
|
||||
--- a/test/mjsunit/regress/regress-1255368.js
|
||||
+++ b/test/mjsunit/regress/regress-1255368.js
|
||||
@@ -2,7 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
-// Flags: --no-regexp-tier-up
|
||||
+// Flags: --no-regexp-tier-up --no-enable-experimental-regexp-engine
|
||||
+// Flags: --no-regexp-interpret-all
|
||||
|
||||
const arr = new Array(20000).fill([1]);
|
||||
const regexp = RegExp(JSON.stringify(arr));
|
||||
diff --git a/tools/testrunner/local/variants.py b/tools/testrunner/local/variants.py
|
||||
index 42bf12d46474335b1ecc3233785d5713bcd8d2cb..a17313dcdf6ec8db209e2e6b09ee23dc4d22745b 100644
|
||||
--- a/tools/testrunner/local/variants.py
|
||||
+++ b/tools/testrunner/local/variants.py
|
||||
@@ -54,7 +54,7 @@ ALL_VARIANT_FLAGS = {
|
||||
INCOMPATIBLE_FLAGS_PER_VARIANT = {
|
||||
"jitless": ["--opt", "--always-opt", "--liftoff", "--track-field-types",
|
||||
"--validate-asm", "--sparkplug", "--always-sparkplug",
|
||||
- "--regexp-tier-up"],
|
||||
+ "--regexp-tier-up", "--no-regexp-interpret-all"],
|
||||
"nooptimization": ["--always-opt"],
|
||||
"slow_path": ["--no-force-slow-path"],
|
||||
"stress_concurrent_allocation": ["--single-threaded-gc", "--predictable"],
|
||||
@@ -0,0 +1,40 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shu-yu Guo <syg@chromium.org>
|
||||
Date: Mon, 11 Oct 2021 16:09:15 -0700
|
||||
Subject: Skip non-compilation functions in %OptimizeOsr
|
||||
|
||||
Bug: chromium:1258603
|
||||
Change-Id: Ife2284de6151c7e70592b55871875061b93bbcca
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3218193
|
||||
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
|
||||
Commit-Queue: Shu-yu Guo <syg@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/main@{#77405}
|
||||
|
||||
diff --git a/src/runtime/runtime-test.cc b/src/runtime/runtime-test.cc
|
||||
index 38cdf5767145df2df4f00f73729ced4d3b916923..5e5d997d6903dd5b0dd55b2fadef8b4dee9581be 100644
|
||||
--- a/src/runtime/runtime-test.cc
|
||||
+++ b/src/runtime/runtime-test.cc
|
||||
@@ -494,6 +494,10 @@ RUNTIME_FUNCTION(Runtime_OptimizeOsr) {
|
||||
|
||||
if (!FLAG_opt) return ReadOnlyRoots(isolate).undefined_value();
|
||||
|
||||
+ if (!function->shared().allows_lazy_compilation()) {
|
||||
+ return CrashUnlessFuzzing(isolate);
|
||||
+ }
|
||||
+
|
||||
if (function->shared().optimization_disabled() &&
|
||||
function->shared().disable_optimization_reason() ==
|
||||
BailoutReason::kNeverOptimize) {
|
||||
diff --git a/test/mjsunit/regress/regress-crbug-1258603.js b/test/mjsunit/regress/regress-crbug-1258603.js
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..f371ae889ffaa1a190422a79f06f5af93519a830
|
||||
--- /dev/null
|
||||
+++ b/test/mjsunit/regress/regress-crbug-1258603.js
|
||||
@@ -0,0 +1,7 @@
|
||||
+// Copyright 2021 the V8 project authors. All rights reserved.
|
||||
+// Use of this source code is governed by a BSD-style license that can be
|
||||
+// found in the LICENSE file.
|
||||
+//
|
||||
+// Flags: --allow-natives-syntax --fuzzing --no-testing-d8-test-runner
|
||||
+
|
||||
+[1,2,3].reduceRight(() => { %OptimizeOsr(1); });
|
||||
@@ -14,14 +14,15 @@ PLATFORM = {
|
||||
}[sys.platform]
|
||||
|
||||
LINUX_BINARIES = [
|
||||
'electron',
|
||||
'chrome-sandbox',
|
||||
'libffmpeg.so',
|
||||
'libGLESv2.so',
|
||||
'chrome_crashpad_handler',
|
||||
'electron',
|
||||
'libEGL.so',
|
||||
'swiftshader/libGLESv2.so',
|
||||
'libGLESv2.so',
|
||||
'libffmpeg.so',
|
||||
'libvk_swiftshader.so',
|
||||
'swiftshader/libEGL.so',
|
||||
'libvk_swiftshader.so'
|
||||
'swiftshader/libGLESv2.so',
|
||||
]
|
||||
|
||||
verbose_mode = False
|
||||
|
||||
@@ -37,7 +37,6 @@ BrowserWindow::BrowserWindow(gin::Arguments* args,
|
||||
gin::Dictionary::CreateEmpty(isolate);
|
||||
options.Get(options::kWebPreferences, &web_preferences);
|
||||
|
||||
v8::Local<v8::Value> value;
|
||||
bool transparent = false;
|
||||
options.Get(options::kTransparent, &transparent);
|
||||
|
||||
@@ -47,8 +46,9 @@ BrowserWindow::BrowserWindow(gin::Arguments* args,
|
||||
#endif
|
||||
|
||||
// Copy the backgroundColor to webContents.
|
||||
if (options.Get(options::kBackgroundColor, &value)) {
|
||||
web_preferences.SetHidden(options::kBackgroundColor, value);
|
||||
std::string color;
|
||||
if (options.Get(options::kBackgroundColor, &color)) {
|
||||
web_preferences.SetHidden(options::kBackgroundColor, color);
|
||||
} else if (!vibrancy_type.empty() || transparent) {
|
||||
// If the BrowserWindow is transparent or a vibrancy type has been set,
|
||||
// also propagate transparency to the WebContents unless a separate
|
||||
@@ -80,6 +80,7 @@ BrowserWindow::BrowserWindow(gin::Arguments* args,
|
||||
|
||||
// Copy the webContents option to webPreferences. This is only used internally
|
||||
// to implement nativeWindowOpen option.
|
||||
v8::Local<v8::Value> value;
|
||||
if (options.Get("webContents", &value)) {
|
||||
web_preferences.SetHidden("webContents", value);
|
||||
}
|
||||
@@ -373,8 +374,11 @@ void BrowserWindow::SetBackgroundColor(const std::string& color_name) {
|
||||
SkColor color = ParseHexColor(color_name);
|
||||
web_contents()->SetPageBaseBackgroundColor(color);
|
||||
auto* rwhv = web_contents()->GetRenderWidgetHostView();
|
||||
if (rwhv)
|
||||
if (rwhv) {
|
||||
rwhv->SetBackgroundColor(color);
|
||||
static_cast<content::RenderWidgetHostViewBase*>(rwhv)
|
||||
->SetContentBackgroundColor(color);
|
||||
}
|
||||
// Also update the web preferences object otherwise the view will be reset on
|
||||
// the next load URL call
|
||||
if (api_web_contents_) {
|
||||
|
||||
@@ -89,8 +89,10 @@ gin::Handle<Tray> Tray::New(gin_helper::ErrorThrower thrower,
|
||||
}
|
||||
#endif
|
||||
|
||||
return gin::CreateHandle(thrower.isolate(),
|
||||
new Tray(args->isolate(), image, guid));
|
||||
auto handle = gin::CreateHandle(args->isolate(),
|
||||
new Tray(args->isolate(), image, guid));
|
||||
handle->Pin(args->isolate());
|
||||
return handle;
|
||||
}
|
||||
|
||||
void Tray::OnClicked(const gfx::Rect& bounds,
|
||||
@@ -180,6 +182,7 @@ void Tray::OnDragEnded() {
|
||||
}
|
||||
|
||||
void Tray::Destroy() {
|
||||
Unpin();
|
||||
menu_.Reset();
|
||||
tray_icon_.reset();
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "shell/common/gin_helper/cleaned_up_at_exit.h"
|
||||
#include "shell/common/gin_helper/constructible.h"
|
||||
#include "shell/common/gin_helper/error_thrower.h"
|
||||
#include "shell/common/gin_helper/pinnable.h"
|
||||
|
||||
namespace gfx {
|
||||
class Image;
|
||||
@@ -38,6 +39,7 @@ class Tray : public gin::Wrappable<Tray>,
|
||||
public gin_helper::EventEmitterMixin<Tray>,
|
||||
public gin_helper::Constructible<Tray>,
|
||||
public gin_helper::CleanedUpAtExit,
|
||||
public gin_helper::Pinnable<Tray>,
|
||||
public TrayIconObserver {
|
||||
public:
|
||||
// gin_helper::Constructible
|
||||
|
||||
@@ -599,6 +599,12 @@ bool IsDevToolsFileSystemAdded(content::WebContents* web_contents,
|
||||
return file_system_paths.find(file_system_path) != file_system_paths.end();
|
||||
}
|
||||
|
||||
void SetBackgroundColor(content::RenderWidgetHostView* rwhv, SkColor color) {
|
||||
rwhv->SetBackgroundColor(color);
|
||||
static_cast<content::RenderWidgetHostViewBase*>(rwhv)
|
||||
->SetContentBackgroundColor(color);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
@@ -760,8 +766,12 @@ WebContents::WebContents(v8::Isolate* isolate,
|
||||
#if BUILDFLAG(ENABLE_OSR)
|
||||
}
|
||||
} else if (IsOffScreen()) {
|
||||
bool transparent = false;
|
||||
options.Get(options::kTransparent, &transparent);
|
||||
// webPreferences does not have a transparent option, so if the window needs
|
||||
// to be transparent, that will be set at electron_api_browser_window.cc#L57
|
||||
// and we then need to pull it back out and check it here.
|
||||
std::string background_color;
|
||||
options.GetHidden(options::kBackgroundColor, &background_color);
|
||||
bool transparent = ParseHexColor(background_color) == SK_ColorTRANSPARENT;
|
||||
|
||||
content::WebContents::CreateParams params(session->browser_context());
|
||||
auto* view = new OffScreenWebContentsView(
|
||||
@@ -1457,7 +1467,7 @@ void WebContents::HandleNewRenderFrame(
|
||||
absl::optional<SkColor> color =
|
||||
guest ? SK_ColorTRANSPARENT : web_preferences->GetBackgroundColor();
|
||||
web_contents()->SetPageBaseBackgroundColor(color);
|
||||
rwhv->SetBackgroundColor(color.value_or(SK_ColorWHITE));
|
||||
SetBackgroundColor(rwhv, color.value_or(SK_ColorWHITE));
|
||||
}
|
||||
|
||||
if (!background_throttling_)
|
||||
@@ -1473,6 +1483,15 @@ void WebContents::HandleNewRenderFrame(
|
||||
web_frame->Connect();
|
||||
}
|
||||
|
||||
void WebContents::OnBackgroundColorChanged() {
|
||||
absl::optional<SkColor> color = web_contents()->GetBackgroundColor();
|
||||
if (color.has_value()) {
|
||||
auto* const view = web_contents()->GetRenderWidgetHostView();
|
||||
static_cast<content::RenderWidgetHostViewBase*>(view)
|
||||
->SetContentBackgroundColor(color.value());
|
||||
}
|
||||
}
|
||||
|
||||
void WebContents::RenderFrameCreated(
|
||||
content::RenderFrameHost* render_frame_host) {
|
||||
HandleNewRenderFrame(render_frame_host);
|
||||
@@ -2300,6 +2319,11 @@ v8::Local<v8::Promise> WebContents::SavePage(
|
||||
gin_helper::Promise<void> promise(isolate);
|
||||
v8::Local<v8::Promise> handle = promise.GetHandle();
|
||||
|
||||
if (!full_file_path.IsAbsolute()) {
|
||||
promise.RejectWithErrorMessage("Path must be absolute");
|
||||
return handle;
|
||||
}
|
||||
|
||||
auto* handler = new SavePageHandler(web_contents(), std::move(promise));
|
||||
handler->Handle(full_file_path, save_type);
|
||||
|
||||
@@ -4033,7 +4057,7 @@ gin::Handle<WebContents> WebContents::CreateFromWebPreferences(
|
||||
// only set rwhv background color if a color exists
|
||||
auto* rwhv = web_contents->web_contents()->GetRenderWidgetHostView();
|
||||
if (rwhv && color.has_value())
|
||||
rwhv->SetBackgroundColor(color.value());
|
||||
SetBackgroundColor(rwhv, color.value());
|
||||
}
|
||||
} else {
|
||||
// Create one if not.
|
||||
|
||||
@@ -574,6 +574,7 @@ class WebContents : public ExclusiveAccessContext,
|
||||
// content::WebContentsObserver:
|
||||
void BeforeUnloadFired(bool proceed,
|
||||
const base::TimeTicks& proceed_time) override;
|
||||
void OnBackgroundColorChanged() override;
|
||||
void RenderFrameCreated(content::RenderFrameHost* render_frame_host) override;
|
||||
void RenderFrameDeleted(content::RenderFrameHost* render_frame_host) override;
|
||||
void RenderFrameHostChanged(content::RenderFrameHost* old_host,
|
||||
|
||||
@@ -210,7 +210,7 @@ void WebFrameMain::PostMessage(v8::Isolate* isolate,
|
||||
}
|
||||
|
||||
std::vector<gin::Handle<MessagePort>> wrapped_ports;
|
||||
if (transfer) {
|
||||
if (transfer && !transfer.value()->IsUndefined()) {
|
||||
if (!gin::ConvertFromV8(isolate, *transfer, &wrapped_ports)) {
|
||||
isolate->ThrowException(v8::Exception::Error(
|
||||
gin::StringToV8(isolate, "Invalid value for transfer")));
|
||||
|
||||
@@ -67,7 +67,7 @@ bool GetProtocolLaunchPath(gin::Arguments* args, std::wstring* exe) {
|
||||
std::vector<std::wstring> launch_args;
|
||||
if (args->GetNext(&launch_args) && !launch_args.empty())
|
||||
*exe = base::StringPrintf(L"\"%ls\" \"%ls\" \"%%1\"", exe->c_str(),
|
||||
base::JoinString(launch_args, L" ").c_str());
|
||||
base::JoinString(launch_args, L"\" \"").c_str());
|
||||
else
|
||||
*exe = base::StringPrintf(L"\"%ls\" \"%%1\"", exe->c_str());
|
||||
return true;
|
||||
|
||||
@@ -467,7 +467,8 @@ void ElectronBrowserMainParts::WillRunMainMessageLoop(
|
||||
std::unique_ptr<base::RunLoop>& run_loop) {
|
||||
js_env_->OnMessageLoopCreated();
|
||||
exit_code_ = content::RESULT_CODE_NORMAL_EXIT;
|
||||
Browser::Get()->SetMainMessageLoopQuitClosure(run_loop->QuitClosure());
|
||||
Browser::Get()->SetMainMessageLoopQuitClosure(
|
||||
run_loop->QuitWhenIdleClosure());
|
||||
}
|
||||
|
||||
void ElectronBrowserMainParts::PostCreateMainMessageLoop() {
|
||||
|
||||
@@ -90,7 +90,15 @@ NativeWindow::NativeWindow(const gin_helper::Dictionary& options,
|
||||
options.Get(options::ktitleBarOverlay, &titlebar_overlay_);
|
||||
} else if (titlebar_overlay->IsObject()) {
|
||||
titlebar_overlay_ = true;
|
||||
#if !defined(OS_WIN)
|
||||
|
||||
gin_helper::Dictionary titlebar_overlay =
|
||||
gin::Dictionary::CreateEmpty(options.isolate());
|
||||
options.Get(options::ktitleBarOverlay, &titlebar_overlay);
|
||||
int height;
|
||||
if (titlebar_overlay.Get(options::kOverlayHeight, &height))
|
||||
titlebar_overlay_height_ = height;
|
||||
|
||||
#if !(defined(OS_WIN) || defined(OS_MAC))
|
||||
DCHECK(false);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -323,6 +323,7 @@ class NativeWindow : public base::SupportsUserData,
|
||||
kCustomButtonsOnHover,
|
||||
};
|
||||
TitleBarStyle title_bar_style() const { return title_bar_style_; }
|
||||
int titlebar_overlay_height() const { return titlebar_overlay_height_; }
|
||||
|
||||
bool has_frame() const { return has_frame_; }
|
||||
void set_has_frame(bool has_frame) { has_frame_ = has_frame; }
|
||||
@@ -358,6 +359,10 @@ class NativeWindow : public base::SupportsUserData,
|
||||
// The boolean parsing of the "titleBarOverlay" option
|
||||
bool titlebar_overlay_ = false;
|
||||
|
||||
// The custom height parsed from the "height" option in a Object
|
||||
// "titleBarOverlay"
|
||||
int titlebar_overlay_height_ = 0;
|
||||
|
||||
// The "titleBarStyle" option.
|
||||
TitleBarStyle title_bar_style_ = TitleBarStyle::kNormal;
|
||||
|
||||
|
||||
@@ -295,12 +295,12 @@ NativeWindowMac::NativeWindowMac(const gin_helper::Dictionary& options,
|
||||
|
||||
NSUInteger styleMask = NSWindowStyleMaskTitled;
|
||||
|
||||
// The NSWindowStyleMaskFullSizeContentView style removes rounded corners
|
||||
// for framless window.
|
||||
// Removing NSWindowStyleMaskTitled removes window title, which removes
|
||||
// rounded corners of window.
|
||||
bool rounded_corner = true;
|
||||
options.Get(options::kRoundedCorners, &rounded_corner);
|
||||
if (!rounded_corner && !has_frame())
|
||||
styleMask = NSWindowStyleMaskFullSizeContentView;
|
||||
styleMask = 0;
|
||||
|
||||
if (minimizable)
|
||||
styleMask |= NSMiniaturizableWindowMask;
|
||||
@@ -369,6 +369,7 @@ NativeWindowMac::NativeWindowMac(const gin_helper::Dictionary& options,
|
||||
InternalSetWindowButtonVisibility(false);
|
||||
} else {
|
||||
buttons_proxy_.reset([[WindowButtonsProxy alloc] initWithWindow:window_]);
|
||||
[buttons_proxy_ setHeight:titlebar_overlay_height()];
|
||||
if (traffic_light_position_) {
|
||||
[buttons_proxy_ setMargin:*traffic_light_position_];
|
||||
} else if (title_bar_style_ == TitleBarStyle::kHiddenInset) {
|
||||
@@ -1349,7 +1350,7 @@ void NativeWindowMac::UpdateVibrancyRadii(bool fullscreen) {
|
||||
|
||||
if (vibrantView != nil && !vibrancy_type_.empty()) {
|
||||
const bool no_rounded_corner =
|
||||
[window_ styleMask] & NSWindowStyleMaskFullSizeContentView;
|
||||
!([window_ styleMask] & NSWindowStyleMaskTitled);
|
||||
if (!has_frame() && !is_modal() && !no_rounded_corner) {
|
||||
CGFloat radius;
|
||||
if (fullscreen) {
|
||||
@@ -1603,10 +1604,15 @@ void NativeWindowMac::SetAspectRatio(double aspect_ratio,
|
||||
NativeWindow::SetAspectRatio(aspect_ratio, extra_size);
|
||||
|
||||
// Reset the behaviour to default if aspect_ratio is set to 0 or less.
|
||||
if (aspect_ratio > 0.0)
|
||||
[window_ setContentAspectRatio:NSMakeSize(aspect_ratio, 1.0)];
|
||||
else
|
||||
if (aspect_ratio > 0.0) {
|
||||
NSSize aspect_ratio_size = NSMakeSize(aspect_ratio, 1.0);
|
||||
if (has_frame())
|
||||
[window_ setContentAspectRatio:aspect_ratio_size];
|
||||
else
|
||||
[window_ setAspectRatio:aspect_ratio_size];
|
||||
} else {
|
||||
[window_ setResizeIncrements:NSMakeSize(1.0, 1.0)];
|
||||
}
|
||||
}
|
||||
|
||||
void NativeWindowMac::PreviewFile(const std::string& path,
|
||||
@@ -1834,7 +1840,12 @@ gfx::Rect NativeWindowMac::GetWindowControlsOverlayRect() {
|
||||
NSRect buttons = [buttons_proxy_ getButtonsContainerBounds];
|
||||
gfx::Rect overlay;
|
||||
overlay.set_width(GetContentSize().width() - NSWidth(buttons));
|
||||
overlay.set_height(NSHeight(buttons));
|
||||
if ([buttons_proxy_ useCustomHeight]) {
|
||||
overlay.set_height(titlebar_overlay_height());
|
||||
} else {
|
||||
overlay.set_height(NSHeight(buttons));
|
||||
}
|
||||
|
||||
if (!base::i18n::IsRTL())
|
||||
overlay.set_x(NSMaxX(buttons));
|
||||
return overlay;
|
||||
|
||||
@@ -179,9 +179,8 @@ NativeWindowViews::NativeWindowViews(const gin_helper::Dictionary& options,
|
||||
v8::Local<v8::Value> titlebar_overlay;
|
||||
if (options.Get(options::ktitleBarOverlay, &titlebar_overlay) &&
|
||||
titlebar_overlay->IsObject()) {
|
||||
v8::Isolate* isolate = JavascriptEnvironment::GetIsolate();
|
||||
gin_helper::Dictionary titlebar_overlay_obj =
|
||||
gin::Dictionary::CreateEmpty(isolate);
|
||||
gin::Dictionary::CreateEmpty(options.isolate());
|
||||
options.Get(options::ktitleBarOverlay, &titlebar_overlay_obj);
|
||||
|
||||
std::string overlay_color_string;
|
||||
@@ -318,15 +317,14 @@ NativeWindowViews::NativeWindowViews(const gin_helper::Dictionary& options,
|
||||
// Set Window style so that we get a minimize and maximize animation when
|
||||
// frameless.
|
||||
DWORD frame_style = WS_CAPTION | WS_OVERLAPPED;
|
||||
if (resizable_)
|
||||
if (resizable_ && thick_frame_)
|
||||
frame_style |= WS_THICKFRAME;
|
||||
if (minimizable_)
|
||||
frame_style |= WS_MINIMIZEBOX;
|
||||
if (maximizable_)
|
||||
frame_style |= WS_MAXIMIZEBOX;
|
||||
// We should not show a frame for transparent window.
|
||||
if (!thick_frame_)
|
||||
frame_style &= ~(WS_THICKFRAME | WS_CAPTION);
|
||||
if (!thick_frame_ || !has_frame())
|
||||
frame_style &= ~WS_CAPTION;
|
||||
::SetWindowLong(GetAcceleratedWidget(), GWL_STYLE, frame_style);
|
||||
}
|
||||
|
||||
@@ -570,23 +568,28 @@ void NativeWindowViews::SetEnabledInternal(bool enable) {
|
||||
|
||||
#if defined(OS_LINUX)
|
||||
void NativeWindowViews::Maximize() {
|
||||
if (IsVisible())
|
||||
if (IsVisible()) {
|
||||
widget()->Maximize();
|
||||
else
|
||||
} else {
|
||||
widget()->native_widget_private()->Show(ui::SHOW_STATE_MAXIMIZED,
|
||||
gfx::Rect());
|
||||
NotifyWindowShow();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void NativeWindowViews::Unmaximize() {
|
||||
if (IsMaximized()) {
|
||||
#if defined(OS_WIN)
|
||||
if (transparent()) {
|
||||
SetBounds(restore_bounds_, false);
|
||||
return;
|
||||
}
|
||||
if (transparent()) {
|
||||
SetBounds(restore_bounds_, false);
|
||||
NotifyWindowUnmaximize();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
widget()->Restore();
|
||||
widget()->Restore();
|
||||
}
|
||||
}
|
||||
|
||||
bool NativeWindowViews::IsMaximized() {
|
||||
|
||||
@@ -176,17 +176,19 @@ HHOOK NativeWindowViews::mouse_hook_ = NULL;
|
||||
void NativeWindowViews::Maximize() {
|
||||
// Only use Maximize() when window is NOT transparent style
|
||||
if (!transparent()) {
|
||||
if (IsVisible())
|
||||
if (IsVisible()) {
|
||||
widget()->Maximize();
|
||||
else
|
||||
} else {
|
||||
widget()->native_widget_private()->Show(ui::SHOW_STATE_MAXIMIZED,
|
||||
gfx::Rect());
|
||||
return;
|
||||
NotifyWindowShow();
|
||||
}
|
||||
} else {
|
||||
restore_bounds_ = GetBounds();
|
||||
auto display = display::Screen::GetScreen()->GetDisplayNearestWindow(
|
||||
GetNativeWindow());
|
||||
SetBounds(display.work_area(), false);
|
||||
NotifyWindowMaximize();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -50,8 +50,8 @@ END
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 16,0,7,0
|
||||
PRODUCTVERSION 16,0,7,0
|
||||
FILEVERSION 16,1,1,0
|
||||
PRODUCTVERSION 16,1,1,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@@ -68,12 +68,12 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "CompanyName", "GitHub, Inc."
|
||||
VALUE "FileDescription", "Electron"
|
||||
VALUE "FileVersion", "16.0.7"
|
||||
VALUE "FileVersion", "16.1.1"
|
||||
VALUE "InternalName", "electron.exe"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved."
|
||||
VALUE "OriginalFilename", "electron.exe"
|
||||
VALUE "ProductName", "Electron"
|
||||
VALUE "ProductVersion", "16.0.7"
|
||||
VALUE "ProductVersion", "16.1.1"
|
||||
VALUE "SquirrelAwareVersion", "1"
|
||||
END
|
||||
END
|
||||
|
||||
@@ -95,36 +95,18 @@ void SerialChooserContext::GrantPortPermission(
|
||||
const device::mojom::SerialPortInfo& port,
|
||||
content::RenderFrameHost* render_frame_host) {
|
||||
base::Value value = PortInfoToValue(port);
|
||||
port_info_.insert({port.token, value.Clone()});
|
||||
|
||||
if (CanStorePersistentEntry(port)) {
|
||||
auto* web_contents =
|
||||
content::WebContents::FromRenderFrameHost(render_frame_host);
|
||||
auto* permission_helper =
|
||||
WebContentsPermissionHelper::FromWebContents(web_contents);
|
||||
permission_helper->GrantSerialPortPermission(origin, std::move(value),
|
||||
render_frame_host);
|
||||
return;
|
||||
}
|
||||
|
||||
ephemeral_ports_[origin].insert(port.token);
|
||||
auto* web_contents =
|
||||
content::WebContents::FromRenderFrameHost(render_frame_host);
|
||||
auto* permission_helper =
|
||||
WebContentsPermissionHelper::FromWebContents(web_contents);
|
||||
permission_helper->GrantSerialPortPermission(origin, std::move(value),
|
||||
render_frame_host);
|
||||
}
|
||||
|
||||
bool SerialChooserContext::HasPortPermission(
|
||||
const url::Origin& origin,
|
||||
const device::mojom::SerialPortInfo& port,
|
||||
content::RenderFrameHost* render_frame_host) {
|
||||
auto it = ephemeral_ports_.find(origin);
|
||||
if (it != ephemeral_ports_.end()) {
|
||||
const std::set<base::UnguessableToken> ports = it->second;
|
||||
if (base::Contains(ports, port.token))
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!CanStorePersistentEntry(port)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto* web_contents =
|
||||
content::WebContents::FromRenderFrameHost(render_frame_host);
|
||||
auto* permission_helper =
|
||||
@@ -194,8 +176,6 @@ void SerialChooserContext::OnPortRemoved(
|
||||
device::mojom::SerialPortInfoPtr port) {
|
||||
for (auto& observer : port_observer_list_)
|
||||
observer.OnPortRemoved(*port);
|
||||
|
||||
port_info_.erase(port->token);
|
||||
}
|
||||
|
||||
void SerialChooserContext::EnsurePortManagerConnection() {
|
||||
@@ -221,10 +201,6 @@ void SerialChooserContext::SetUpPortManagerConnection(
|
||||
void SerialChooserContext::OnPortManagerConnectionError() {
|
||||
port_manager_.reset();
|
||||
client_receiver_.reset();
|
||||
|
||||
port_info_.clear();
|
||||
|
||||
ephemeral_ports_.clear();
|
||||
}
|
||||
|
||||
} // namespace electron
|
||||
|
||||
@@ -78,12 +78,6 @@ class SerialChooserContext : public KeyedService,
|
||||
mojo::PendingRemote<device::mojom::SerialPortManager> manager);
|
||||
void OnPortManagerConnectionError();
|
||||
|
||||
// Tracks the set of ports to which an origin has access to.
|
||||
std::map<url::Origin, std::set<base::UnguessableToken>> ephemeral_ports_;
|
||||
|
||||
// Holds information about ports in |ephemeral_ports_|.
|
||||
std::map<base::UnguessableToken, base::Value> port_info_;
|
||||
|
||||
mojo::Remote<device::mojom::SerialPortManager> port_manager_;
|
||||
mojo::Receiver<device::mojom::SerialPortManagerClient> client_receiver_{this};
|
||||
base::ObserverList<PortObserver> port_observer_list_;
|
||||
|
||||
@@ -159,6 +159,15 @@ bool ScopedDisableResize::disable_resize_ = false;
|
||||
return [[self contentView] superview];
|
||||
}
|
||||
|
||||
- (BOOL)validateUserInterfaceItem:(id<NSValidatedUserInterfaceItem>)item {
|
||||
// By default "Close Window" is always disabled when window has no title, to
|
||||
// support closing a window without title we need to manually do menu item
|
||||
// validation. This code path is used by the "roundedCorners" option.
|
||||
if ([item action] == @selector(performClose:))
|
||||
return shell_->IsClosable();
|
||||
return [super validateUserInterfaceItem:item];
|
||||
}
|
||||
|
||||
// By overriding this built-in method the corners of the vibrant view (if set)
|
||||
// will be smooth.
|
||||
- (NSImage*)_cornerMask {
|
||||
@@ -195,7 +204,10 @@ bool ScopedDisableResize::disable_resize_ = false;
|
||||
if (shell_->title_bar_style() ==
|
||||
electron::NativeWindowMac::TitleBarStyle::kCustomButtonsOnHover) {
|
||||
[[self delegate] windowShouldClose:self];
|
||||
} else if (shell_->IsSimpleFullScreen()) {
|
||||
} else if (!([self styleMask] & NSWindowStyleMaskTitled)) {
|
||||
// performClose does not work for windows without title, so we have to
|
||||
// emulate its behavior. This code path is used by "simpleFullscreen" and
|
||||
// "roundedCorners" options.
|
||||
if ([[self delegate] respondsToSelector:@selector(windowShouldClose:)]) {
|
||||
if (![[self delegate] windowShouldClose:self])
|
||||
return;
|
||||
|
||||
@@ -30,6 +30,8 @@
|
||||
gfx::Point margin_;
|
||||
// The default left-top margin.
|
||||
gfx::Point default_margin_;
|
||||
// Current height of the title bar container.
|
||||
float height_;
|
||||
|
||||
// Track mouse moves above window buttons.
|
||||
BOOL show_on_hover_;
|
||||
@@ -49,6 +51,10 @@
|
||||
// Set left-top margin of the window buttons..
|
||||
- (void)setMargin:(const absl::optional<gfx::Point>&)margin;
|
||||
|
||||
// Set height of button container
|
||||
- (void)setHeight:(const float)height;
|
||||
- (BOOL)useCustomHeight;
|
||||
|
||||
// Return the bounds of all 3 buttons, with margin on all sides.
|
||||
- (NSRect)getButtonsContainerBounds;
|
||||
|
||||
|
||||
@@ -36,6 +36,8 @@
|
||||
|
||||
// Remember the default margin.
|
||||
margin_ = default_margin_ = [self getCurrentMargin];
|
||||
// Custom height will be used if set larger than default
|
||||
height_ = 0;
|
||||
|
||||
return self;
|
||||
}
|
||||
@@ -86,6 +88,17 @@
|
||||
[self redraw];
|
||||
}
|
||||
|
||||
- (void)setHeight:(const float)height {
|
||||
height_ = height;
|
||||
[self redraw];
|
||||
}
|
||||
|
||||
- (BOOL)useCustomHeight {
|
||||
NSView* left = [self leftButton];
|
||||
float button_height = NSHeight(left.frame);
|
||||
return height_ > button_height + 2 * default_margin_.y();
|
||||
}
|
||||
|
||||
- (NSRect)getButtonsContainerBounds {
|
||||
return NSInsetRect([self getButtonsBounds], -margin_.x(), -margin_.y());
|
||||
}
|
||||
@@ -111,14 +124,18 @@
|
||||
|
||||
NSRect cbounds = titleBarContainer.frame;
|
||||
cbounds.size.height = button_height + 2 * margin_.y();
|
||||
// Custom height must be larger than the button height to use
|
||||
if ([self useCustomHeight]) {
|
||||
cbounds.size.height = height_;
|
||||
}
|
||||
cbounds.origin.y = NSHeight(window_.frame) - NSHeight(cbounds);
|
||||
[titleBarContainer setFrame:cbounds];
|
||||
|
||||
[left setFrameOrigin:NSMakePoint(start, margin_.y())];
|
||||
[left setFrameOrigin:NSMakePoint(start, [self getCurrentMargin].y())];
|
||||
start += button_width + padding;
|
||||
[middle setFrameOrigin:NSMakePoint(start, margin_.y())];
|
||||
[middle setFrameOrigin:NSMakePoint(start, [self getCurrentMargin].y())];
|
||||
start += button_width + padding;
|
||||
[right setFrameOrigin:NSMakePoint(start, margin_.y())];
|
||||
[right setFrameOrigin:NSMakePoint(start, [self getCurrentMargin].y())];
|
||||
|
||||
if (hover_view_)
|
||||
[hover_view_ setFrame:[self getButtonsBounds]];
|
||||
@@ -167,6 +184,7 @@
|
||||
- (NSRect)getButtonsBounds {
|
||||
NSView* left = [self leftButton];
|
||||
NSView* right = [self rightButton];
|
||||
|
||||
return NSMakeRect(NSMinX(left.frame), NSMinY(left.frame),
|
||||
NSMaxX(right.frame) - NSMinX(left.frame),
|
||||
NSHeight(left.frame));
|
||||
@@ -182,7 +200,17 @@
|
||||
NSView* left = [self leftButton];
|
||||
NSView* right = [self rightButton];
|
||||
|
||||
result.set_y((NSHeight(titleBarContainer.frame) - NSHeight(left.frame)) / 2);
|
||||
if (height_ != 0) {
|
||||
result.set_y((height_ - NSHeight(left.frame)) / 2);
|
||||
|
||||
// Do not center buttons if height and button position specified
|
||||
if (margin_.y() != default_margin_.y())
|
||||
result.set_y(height_ - NSHeight(left.frame) - margin_.y());
|
||||
|
||||
} else {
|
||||
result.set_y((NSHeight(titleBarContainer.frame) - NSHeight(left.frame)) /
|
||||
2);
|
||||
}
|
||||
|
||||
if (base::i18n::IsRTL())
|
||||
result.set_x(NSWidth(window_.frame) - NSMaxX(right.frame));
|
||||
|
||||
@@ -175,6 +175,10 @@ GURL GetDevToolsURL(bool can_dock) {
|
||||
return GURL(url_string);
|
||||
}
|
||||
|
||||
void OnOpenItemComplete(const base::FilePath& path, const std::string& result) {
|
||||
platform_util::ShowItemInFolder(path);
|
||||
}
|
||||
|
||||
constexpr base::TimeDelta kInitialBackoffDelay =
|
||||
base::TimeDelta::FromMilliseconds(250);
|
||||
constexpr base::TimeDelta kMaxBackoffDelay = base::TimeDelta::FromSeconds(10);
|
||||
@@ -738,9 +742,8 @@ void InspectableWebContents::ShowItemInFolder(
|
||||
return;
|
||||
|
||||
base::FilePath path = base::FilePath::FromUTF8Unsafe(file_system_path);
|
||||
|
||||
// Pass empty callback here; we can ignore errors
|
||||
platform_util::OpenPath(path, platform_util::OpenCallback());
|
||||
platform_util::OpenPath(path.DirName(),
|
||||
base::BindOnce(&OnOpenItemComplete, path));
|
||||
}
|
||||
|
||||
void InspectableWebContents::SaveToFile(const std::string& url,
|
||||
|
||||
@@ -171,8 +171,9 @@ DialogResult ShowTaskDialogWstr(NativeWindow* parent,
|
||||
|
||||
// TaskDialogIndirect doesn't allow empty name, if we set empty title it
|
||||
// will show "electron.exe" in title.
|
||||
std::wstring app_name;
|
||||
if (title.empty()) {
|
||||
std::wstring app_name = base::UTF8ToWide(Browser::Get()->GetName());
|
||||
app_name = base::UTF8ToWide(Browser::Get()->GetName());
|
||||
config.pszWindowTitle = app_name.c_str();
|
||||
} else {
|
||||
config.pszWindowTitle = base::as_wcstr(title);
|
||||
|
||||
@@ -93,6 +93,15 @@
|
||||
|
||||
- (void)setAlternateImage:(NSImage*)image {
|
||||
[[statusItem_ button] setAlternateImage:image];
|
||||
|
||||
// We need to change the button type here because the default button type for
|
||||
// NSStatusItem, NSStatusBarButton, does not display alternate content when
|
||||
// clicked. NSButtonTypeMomentaryChange displays its alternate content when
|
||||
// clicked and returns to its normal content when the user releases it, which
|
||||
// is the behavior users would expect when clicking a button with an alternate
|
||||
// image set.
|
||||
[[statusItem_ button] setButtonType:NSButtonTypeMomentaryChange];
|
||||
[self updateDimensions];
|
||||
}
|
||||
|
||||
- (void)setIgnoreDoubleClickEvents:(BOOL)ignore {
|
||||
|
||||
@@ -2,13 +2,14 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Modified from chrome/browser/ui/views/frame/windows_10_caption_button.cc
|
||||
|
||||
#include "shell/browser/ui/views/win_caption_button.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "base/i18n/rtl.h"
|
||||
#include "base/numerics/safe_conversions.h"
|
||||
#include "chrome/browser/ui/frame/window_frame_util.h"
|
||||
#include "chrome/grit/theme_resources.h"
|
||||
#include "shell/browser/ui/views/win_frame_view.h"
|
||||
#include "shell/common/color_util.h"
|
||||
@@ -37,9 +38,8 @@ WinCaptionButton::WinCaptionButton(PressedCallback callback,
|
||||
gfx::Size WinCaptionButton::CalculatePreferredSize() const {
|
||||
// TODO(bsep): The sizes in this function are for 1x device scale and don't
|
||||
// match Windows button sizes at hidpi.
|
||||
int height = WindowFrameUtil::kWindows10GlassCaptionButtonHeightRestored;
|
||||
int base_width = WindowFrameUtil::kWindows10GlassCaptionButtonWidth;
|
||||
return gfx::Size(base_width + GetBetweenButtonSpacing(), height);
|
||||
|
||||
return gfx::Size(base_width_ + GetBetweenButtonSpacing(), height_);
|
||||
}
|
||||
|
||||
void WinCaptionButton::OnPaintBackground(gfx::Canvas* canvas) {
|
||||
@@ -88,6 +88,20 @@ void WinCaptionButton::PaintButtonContents(gfx::Canvas* canvas) {
|
||||
PaintSymbol(canvas);
|
||||
}
|
||||
|
||||
gfx::Size WinCaptionButton::GetSize() const {
|
||||
return gfx::Size(base_width_, height_);
|
||||
}
|
||||
|
||||
void WinCaptionButton::SetSize(gfx::Size size) {
|
||||
int width = size.width();
|
||||
int height = size.height();
|
||||
|
||||
if (width > 0)
|
||||
base_width_ = width;
|
||||
if (height > 0)
|
||||
height_ = height;
|
||||
}
|
||||
|
||||
int WinCaptionButton::GetBetweenButtonSpacing() const {
|
||||
const int display_order_index = GetButtonDisplayOrderIndex();
|
||||
return display_order_index == 0
|
||||
|
||||
@@ -2,9 +2,12 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Modified from chrome/browser/ui/views/frame/windows_10_caption_button.h
|
||||
|
||||
#ifndef SHELL_BROWSER_UI_VIEWS_WIN_CAPTION_BUTTON_H_
|
||||
#define SHELL_BROWSER_UI_VIEWS_WIN_CAPTION_BUTTON_H_
|
||||
|
||||
#include "chrome/browser/ui/frame/window_frame_util.h"
|
||||
#include "chrome/browser/ui/view_ids.h"
|
||||
#include "ui/base/metadata/metadata_header_macros.h"
|
||||
#include "ui/gfx/canvas.h"
|
||||
@@ -28,7 +31,10 @@ class WinCaptionButton : public views::Button {
|
||||
void OnPaintBackground(gfx::Canvas* canvas) override;
|
||||
void PaintButtonContents(gfx::Canvas* canvas) override;
|
||||
|
||||
// private:
|
||||
gfx::Size GetSize() const;
|
||||
void SetSize(gfx::Size size);
|
||||
|
||||
private:
|
||||
// Returns the amount we should visually reserve on the left (right in RTL)
|
||||
// for spacing between buttons. We do this instead of repositioning the
|
||||
// buttons to avoid the sliver of deadspace that would result.
|
||||
@@ -48,6 +54,9 @@ class WinCaptionButton : public views::Button {
|
||||
|
||||
WinFrameView* frame_view_;
|
||||
ViewID button_type_;
|
||||
|
||||
int base_width_ = WindowFrameUtil::kWindows10GlassCaptionButtonWidth;
|
||||
int height_ = WindowFrameUtil::kWindows10GlassCaptionButtonHeightRestored;
|
||||
};
|
||||
} // namespace electron
|
||||
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Modified from
|
||||
// chrome/browser/ui/views/frame/glass_browser_caption_button_container.cc
|
||||
|
||||
#include "shell/browser/ui/views/win_caption_button_container.h"
|
||||
|
||||
#include <memory>
|
||||
@@ -96,6 +99,18 @@ int WinCaptionButtonContainer::NonClientHitTest(const gfx::Point& point) const {
|
||||
return HTCAPTION;
|
||||
}
|
||||
|
||||
gfx::Size WinCaptionButtonContainer::GetButtonSize() const {
|
||||
// Close button size is set the same as all the buttons
|
||||
return close_button_->GetSize();
|
||||
}
|
||||
|
||||
void WinCaptionButtonContainer::SetButtonSize(gfx::Size size) {
|
||||
minimize_button_->SetSize(size);
|
||||
maximize_button_->SetSize(size);
|
||||
restore_button_->SetSize(size);
|
||||
close_button_->SetSize(size);
|
||||
}
|
||||
|
||||
void WinCaptionButtonContainer::ResetWindowControls() {
|
||||
minimize_button_->SetState(views::Button::STATE_NORMAL);
|
||||
maximize_button_->SetState(views::Button::STATE_NORMAL);
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Modified from
|
||||
// chrome/browser/ui/views/frame/glass_browser_caption_button_container.h
|
||||
|
||||
#ifndef SHELL_BROWSER_UI_VIEWS_WIN_CAPTION_BUTTON_CONTAINER_H_
|
||||
#define SHELL_BROWSER_UI_VIEWS_WIN_CAPTION_BUTTON_CONTAINER_H_
|
||||
|
||||
@@ -35,6 +38,9 @@ class WinCaptionButtonContainer : public views::View,
|
||||
// See also ClientView::NonClientHitTest.
|
||||
int NonClientHitTest(const gfx::Point& point) const;
|
||||
|
||||
gfx::Size GetButtonSize() const;
|
||||
void SetButtonSize(gfx::Size size);
|
||||
|
||||
private:
|
||||
// views::View:
|
||||
void AddedToWidget() override;
|
||||
|
||||
@@ -193,13 +193,20 @@ int WinFrameView::TitlebarMaximizedVisualHeight() const {
|
||||
return maximized_height;
|
||||
}
|
||||
|
||||
int WinFrameView::TitlebarHeight(bool restored) const {
|
||||
if (frame()->IsFullscreen() && !restored)
|
||||
// NOTE(@mlaurencin): Usage of IsWebUITabStrip simplified out from Chromium
|
||||
int WinFrameView::TitlebarHeight(int custom_height) const {
|
||||
if (frame()->IsFullscreen() && !IsMaximized())
|
||||
return 0;
|
||||
|
||||
return TitlebarMaximizedVisualHeight() + FrameTopBorderThickness(false);
|
||||
int height = TitlebarMaximizedVisualHeight() +
|
||||
FrameTopBorderThickness(false) - WindowTopY();
|
||||
if (custom_height > TitlebarMaximizedVisualHeight())
|
||||
height = custom_height - WindowTopY();
|
||||
|
||||
return height;
|
||||
}
|
||||
|
||||
// NOTE(@mlaurencin): Usage of IsWebUITabStrip simplified out from Chromium
|
||||
int WinFrameView::WindowTopY() const {
|
||||
// The window top is SM_CYSIZEFRAME pixels when maximized (see the comment in
|
||||
// FrameTopBorderThickness()) and floor(system dsf) pixels when restored.
|
||||
@@ -222,27 +229,35 @@ void WinFrameView::LayoutCaptionButtons() {
|
||||
}
|
||||
|
||||
caption_button_container_->SetVisible(true);
|
||||
|
||||
const gfx::Size preferred_size =
|
||||
caption_button_container_->GetPreferredSize();
|
||||
int height = preferred_size.height();
|
||||
|
||||
height = IsMaximized() ? TitlebarMaximizedVisualHeight()
|
||||
: TitlebarHeight(false) - WindowTopY();
|
||||
int custom_height = window()->titlebar_overlay_height();
|
||||
int height = TitlebarHeight(custom_height);
|
||||
|
||||
// TODO(mlaurencin): This -1 creates a 1 pixel gap between the right
|
||||
// edge of the overlay and the edge of the window, allowing for this edge
|
||||
// portion to return the correct hit test and be manually resized properly.
|
||||
// Alternatives can be explored, but the differences in view structures
|
||||
// between Electron and Chromium may result in this as the best option.
|
||||
// TODO(mlaurencin): This -1 creates a 1 pixel margin between the right
|
||||
// edge of the button container and the edge of the window, allowing for this
|
||||
// edge portion to return the correct hit test and be manually resized
|
||||
// properly. Alternatives can be explored, but the differences in view
|
||||
// structures between Electron and Chromium may result in this as the best
|
||||
// option.
|
||||
int variable_width =
|
||||
IsMaximized() ? preferred_size.width() : preferred_size.width() - 1;
|
||||
caption_button_container_->SetBounds(width() - preferred_size.width(),
|
||||
WindowTopY(), variable_width, height);
|
||||
|
||||
// Needed for heights larger than default
|
||||
caption_button_container_->SetButtonSize(gfx::Size(0, height));
|
||||
}
|
||||
|
||||
void WinFrameView::LayoutWindowControlsOverlay() {
|
||||
int overlay_height = caption_button_container_->size().height();
|
||||
int overlay_height = window()->titlebar_overlay_height();
|
||||
if (overlay_height == 0) {
|
||||
// Accounting for the 1 pixel margin at the top of the button container
|
||||
overlay_height = IsMaximized()
|
||||
? caption_button_container_->size().height()
|
||||
: caption_button_container_->size().height() + 1;
|
||||
}
|
||||
int overlay_width = caption_button_container_->size().width();
|
||||
int bounding_rect_width = width() - overlay_width;
|
||||
auto bounding_rect =
|
||||
|
||||
@@ -67,7 +67,7 @@ class WinFrameView : public FramelessView {
|
||||
|
||||
// Returns the height of the titlebar for popups or other browser types that
|
||||
// don't have tabs.
|
||||
int TitlebarHeight(bool restored) const;
|
||||
int TitlebarHeight(int custom_height) const;
|
||||
|
||||
// Returns the y coordinate for the top of the frame, which in maximized mode
|
||||
// is the top of the screen and in restored mode is 1 pixel below the top of
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user