mirror of
https://github.com/electron/electron.git
synced 2026-04-10 03:01:51 -04:00
Compare commits
28 Commits
v31.0.0-al
...
cherry-pic
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dbaf98e4f3 | ||
|
|
d5c8f2d6d9 | ||
|
|
5b60698dea | ||
|
|
05631ec445 | ||
|
|
36310b8729 | ||
|
|
f5fb44eaf8 | ||
|
|
441dbda833 | ||
|
|
ef097b77ad | ||
|
|
5310b79ffb | ||
|
|
b95d0f7623 | ||
|
|
b41da150ca | ||
|
|
b684a98267 | ||
|
|
7621e7cff7 | ||
|
|
d8f8560b1c | ||
|
|
1cf194faae | ||
|
|
a0fee8f47a | ||
|
|
4e8c28fdf0 | ||
|
|
46adb0a3a9 | ||
|
|
a8db7fe2ef | ||
|
|
0346e0a8bf | ||
|
|
39bf441b3b | ||
|
|
46ef7ef8fb | ||
|
|
07a68c2bf8 | ||
|
|
ed9fec7da4 | ||
|
|
c4aeb17245 | ||
|
|
67ba30402b | ||
|
|
b683754c16 | ||
|
|
0222686e9a |
26
.github/workflows/config/evm.mas.json
vendored
Normal file
26
.github/workflows/config/evm.mas.json
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"root": "/Users/runner/work/electron/electron/",
|
||||
"remotes": {
|
||||
"electron": {
|
||||
"origin": "https://github.com/electron/electron.git"
|
||||
}
|
||||
},
|
||||
"gen": {
|
||||
"args": [
|
||||
"import(\"//electron/build/args/testing.gn\")",
|
||||
"use_remoteexec = true",
|
||||
"target_cpu = \"arm64\"",
|
||||
"is_mas_build = true"
|
||||
],
|
||||
"out": "Default"
|
||||
},
|
||||
"env": {
|
||||
"CHROMIUM_BUILDTOOLS_PATH": "/Users/runner/work/electron/electron/src/buildtools",
|
||||
"GIT_CACHE_PATH": "/Users/runner/work/electron/electron/.git-cache"
|
||||
},
|
||||
"$schema": "file:///home/builduser/.electron_build_tools/evm-config.schema.json",
|
||||
"configValidationLevel": "strict",
|
||||
"reclient": "remote_exec",
|
||||
"goma": "none",
|
||||
"preserveXcode": 5
|
||||
}
|
||||
14
.github/workflows/config/gclient.diff
vendored
Normal file
14
.github/workflows/config/gclient.diff
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
diff --git a/gclient.py b/gclient.py
|
||||
index 59e2b4c5197928bdba1ef69bdbe637d7dfe471c1..b4bae5e48c83c84bd867187afaf40eed16e69851 100755
|
||||
--- a/gclient.py
|
||||
+++ b/gclient.py
|
||||
@@ -739,7 +739,8 @@ class Dependency(gclient_utils.WorkItem, DependencySettings):
|
||||
|
||||
if dep_type == 'cipd':
|
||||
cipd_root = self.GetCipdRoot()
|
||||
- for package in dep_value.get('packages', []):
|
||||
+ packages = dep_value.get('packages', [])
|
||||
+ for package in (x for x in packages if "infra/3pp/tools/swift-format" not in x.get('package')):
|
||||
deps_to_add.append(
|
||||
CipdDependency(parent=self,
|
||||
name=name,
|
||||
584
.github/workflows/macos-build.yml
vendored
Normal file
584
.github/workflows/macos-build.yml
vendored
Normal file
@@ -0,0 +1,584 @@
|
||||
name: Build MacOS
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_mac=True --custom-var=host_os=mac --custom-var=host_cpu=arm64'
|
||||
IS_RELEASE: false
|
||||
# GENERATE_SYMBOLS: true only on release builds
|
||||
GENERATE_SYMBOLS: false
|
||||
AZURE_STORAGE_ACCOUNT: ${{ secrets.AZURE_STORAGE_ACCOUNT }}
|
||||
AZURE_STORAGE_KEY: ${{ secrets.AZURE_STORAGE_KEY }}
|
||||
AZURE_STORAGE_CONTAINER_NAME: ${{ secrets.AZURE_STORAGE_CONTAINER_NAME }}
|
||||
ELECTRON_RBE_JWT: ${{ secrets.ELECTRON_RBE_JWT }}
|
||||
# TODO: this should be set to the correct GN_CONFIG for the build type.
|
||||
GN_CONFIG: //electron/build/args/testing.gn
|
||||
# Disable pre-compiled headers to reduce out size - only useful for rebuilds
|
||||
GN_BUILDFLAG_ARGS: 'enable_precompiled_headers = false'
|
||||
|
||||
jobs:
|
||||
checkout:
|
||||
runs-on: LargeLinuxRunner
|
||||
steps:
|
||||
- name: Checkout Electron
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
path: src/electron
|
||||
- name: Install Azure CLI
|
||||
run: ./script/azure_cli_deb_install.sh
|
||||
- name: Set GIT_CACHE_PATH to make gclient to use the cache
|
||||
run: |
|
||||
echo "GIT_CACHE_PATH=$(pwd)/git-cache" >> $GITHUB_ENV
|
||||
- name: Setup Node.js/npm
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 20.11.x
|
||||
cache: yarn
|
||||
cache-dependency-path: src/electron/yarn.lock
|
||||
- name: Install Dependencies
|
||||
run: |
|
||||
cd src/electron
|
||||
node script/yarn install
|
||||
- name: Get Depot Tools
|
||||
timeout-minutes: 5
|
||||
run: |
|
||||
git clone --depth=1 https://chromium.googlesource.com/chromium/tools/depot_tools.git
|
||||
if [ "`uname`" == "Darwin" ]; then
|
||||
# remove ninjalog_uploader_wrapper.py from autoninja since we don't use it and it causes problems
|
||||
sed -i '' '/ninjalog_uploader_wrapper.py/d' ./depot_tools/autoninja
|
||||
else
|
||||
sed -i '/ninjalog_uploader_wrapper.py/d' ./depot_tools/autoninja
|
||||
# Remove swift-format dep from cipd on macOS until we send a patch upstream.
|
||||
cd depot_tools
|
||||
git apply --3way ../src/electron/.github/workflows/config/gclient.diff
|
||||
fi
|
||||
# Ensure depot_tools does not update.
|
||||
test -d depot_tools && cd depot_tools
|
||||
touch .disable_auto_update
|
||||
- name: Add Depot Tools to PATH
|
||||
run: echo "$(pwd)/depot_tools" >> $GITHUB_PATH
|
||||
- name: Generate DEPS Hash
|
||||
run: |
|
||||
node src/electron/script/generate-deps-hash.js && cat src/electron/.depshash-target
|
||||
echo "DEPSHASH=v1-src-cache-$(shasum src/electron/.depshash | cut -f1 -d' ')" >> $GITHUB_ENV
|
||||
- name: Check If Cache Exists
|
||||
id: check-cache
|
||||
run: |
|
||||
exists_json=$(az storage blob exists \
|
||||
--account-name $AZURE_STORAGE_ACCOUNT \
|
||||
--account-key $AZURE_STORAGE_KEY \
|
||||
--container-name $AZURE_STORAGE_CONTAINER_NAME \
|
||||
--name $DEPSHASH)
|
||||
|
||||
cache_exists=$(echo $exists_json | jq -r '.exists')
|
||||
echo "cache_exists=$cache_exists" >> $GITHUB_OUTPUT
|
||||
|
||||
if (test "$cache_exists" = "true"); then
|
||||
echo "Cache Exists for $DEPSHASH"
|
||||
else
|
||||
echo "Cache Does Not Exist for $DEPSHASH"
|
||||
fi
|
||||
- name: Gclient Sync
|
||||
# If there is no existing src cache, we need to do a full gclient sync.
|
||||
# TODO(codebytere): Add stale patch handling for non-release builds.
|
||||
if: steps.check-cache.outputs.cache_exists == 'false'
|
||||
run: |
|
||||
gclient config \
|
||||
--name "src/electron" \
|
||||
--unmanaged \
|
||||
${GCLIENT_EXTRA_ARGS} \
|
||||
"$GITHUB_SERVER_URL/$GITHUB_REPOSITORY"
|
||||
|
||||
ELECTRON_USE_THREE_WAY_MERGE_FOR_PATCHES=1 gclient sync --with_branch_heads --with_tags -vvvvv
|
||||
if [ "$IS_RELEASE" != "true" ]; then
|
||||
# Re-export all the patches to check if there were changes.
|
||||
python3 src/electron/script/export_all_patches.py src/electron/patches/config.json
|
||||
cd src/electron
|
||||
git update-index --refresh || true
|
||||
if ! git diff-index --quiet HEAD --; then
|
||||
# There are changes to the patches. Make a git commit with the updated patches
|
||||
git add patches
|
||||
GIT_COMMITTER_NAME="PatchUp" GIT_COMMITTER_EMAIL="73610968+patchup[bot]@users.noreply.github.com" git commit -m "chore: update patches" --author="PatchUp <73610968+patchup[bot]@users.noreply.github.com>"
|
||||
# Export it
|
||||
mkdir -p ../../patches
|
||||
git format-patch -1 --stdout --keep-subject --no-stat --full-index > ../../patches/update-patches.patch
|
||||
if (node ./script/push-patch.js 2> /dev/null > /dev/null); then
|
||||
echo
|
||||
echo "======================================================================"
|
||||
echo "Changes to the patches when applying, we have auto-pushed the diff to the current branch"
|
||||
echo "A new CI job will kick off shortly"
|
||||
echo "======================================================================"
|
||||
exit 1
|
||||
else
|
||||
echo
|
||||
echo "======================================================================"
|
||||
echo "There were changes to the patches when applying."
|
||||
echo "Check the CI artifacts for a patch you can apply to fix it."
|
||||
echo "======================================================================"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# delete all .git directories under src/ except for
|
||||
# third_party/angle/ and third_party/dawn/ because of build time generation of files
|
||||
# gen/angle/commit.h depends on third_party/angle/.git/HEAD
|
||||
# https://chromium-review.googlesource.com/c/angle/angle/+/2074924
|
||||
# and dawn/common/Version_autogen.h depends on third_party/dawn/.git/HEAD
|
||||
# https://dawn-review.googlesource.com/c/dawn/+/83901
|
||||
# TODO: maybe better to always leave out */.git/HEAD file for all targets ?
|
||||
- name: Delete .git directories under src to free space
|
||||
if: steps.check-cache.outputs.cache_exists == 'false'
|
||||
run: |
|
||||
cd src
|
||||
( find . -type d -name ".git" -not -path "./third_party/angle/*" -not -path "./third_party/dawn/*" -not -path "./electron/*" ) | xargs rm -rf
|
||||
- name: Minimize Cache Size for Upload
|
||||
if: steps.check-cache.outputs.cache_exists == 'false'
|
||||
run: |
|
||||
rm -rf src/android_webview
|
||||
rm -rf src/ios/chrome
|
||||
rm -rf src/third_party/blink/web_tests
|
||||
rm -rf src/third_party/blink/perf_tests
|
||||
rm -rf src/chrome/test/data/xr/webvr_info
|
||||
rm -rf src/third_party/angle/third_party/VK-GL-CTS/src
|
||||
rm -rf src/third_party/swift-toolchain
|
||||
rm -rf src/third_party/swiftshader/tests/regres/testlists
|
||||
rm -rf src/electron
|
||||
- name: Compress Src Directory
|
||||
if: steps.check-cache.outputs.cache_exists == 'false'
|
||||
run: |
|
||||
echo "Uncompressed src size: $(du -sh src | cut -f1 -d' ')"
|
||||
tar -cvf $DEPSHASH.tar src
|
||||
echo "Compressed src to $(du -sh $DEPSHASH.tar | cut -f1 -d' ')"
|
||||
- name: Upload Compressed Src Cache to Azure
|
||||
if: steps.check-cache.outputs.cache_exists == 'false'
|
||||
run: |
|
||||
az storage blob upload \
|
||||
--account-name $AZURE_STORAGE_ACCOUNT \
|
||||
--account-key $AZURE_STORAGE_KEY \
|
||||
--container-name $AZURE_STORAGE_CONTAINER_NAME \
|
||||
--file $DEPSHASH.tar \
|
||||
--name $DEPSHASH \
|
||||
--debug
|
||||
build:
|
||||
runs-on: macos-13-xlarge
|
||||
needs: checkout
|
||||
steps:
|
||||
- name: Load Build Tools
|
||||
run: |
|
||||
export BUILD_TOOLS_SHA=2bb63e2e7877491b52f972532b52adc979a6ec2f
|
||||
npm i -g @electron/build-tools
|
||||
e init --root=$(pwd) --out=Default testing
|
||||
- name: Checkout Electron
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
path: src/electron
|
||||
- name: Install Azure CLI
|
||||
run: |
|
||||
brew update && brew install azure-cli
|
||||
- name: Setup Node.js/npm
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 20.11.x
|
||||
cache: yarn
|
||||
cache-dependency-path: src/electron/yarn.lock
|
||||
- name: Install Dependencies
|
||||
run: |
|
||||
cd src/electron
|
||||
node script/yarn install
|
||||
- name: Get Depot Tools
|
||||
timeout-minutes: 5
|
||||
run: |
|
||||
git clone --depth=1 https://chromium.googlesource.com/chromium/tools/depot_tools.git
|
||||
if [ "`uname`" == "Darwin" ]; then
|
||||
# remove ninjalog_uploader_wrapper.py from autoninja since we don't use it and it causes problems
|
||||
sed -i '' '/ninjalog_uploader_wrapper.py/d' ./depot_tools/autoninja
|
||||
else
|
||||
sed -i '/ninjalog_uploader_wrapper.py/d' ./depot_tools/autoninja
|
||||
# Remove swift-format dep from cipd on macOS until we send a patch upstream.
|
||||
cd depot_tools
|
||||
git apply --3way ../src/electron/.github/workflows/config/gclient.diff
|
||||
fi
|
||||
# Ensure depot_tools does not update.
|
||||
test -d depot_tools && cd depot_tools
|
||||
touch .disable_auto_update
|
||||
- name: Add Depot Tools to PATH
|
||||
run: echo "$(pwd)/depot_tools" >> $GITHUB_PATH
|
||||
- name: Generate DEPS Hash
|
||||
run: |
|
||||
node src/electron/script/generate-deps-hash.js && cat src/electron/.depshash-target
|
||||
echo "DEPSHASH=v1-src-cache-$(shasum src/electron/.depshash | cut -f1 -d' ')" >> $GITHUB_ENV
|
||||
- name: Download Src Cache
|
||||
# The cache will always exist here as a result of the checkout job
|
||||
# Either it was uploaded to Azure in the checkout job for this commit
|
||||
# or it was uploaded in the checkout job for a previous commit.
|
||||
run: |
|
||||
az storage blob download \
|
||||
--account-name $AZURE_STORAGE_ACCOUNT \
|
||||
--account-key $AZURE_STORAGE_KEY \
|
||||
--container-name $AZURE_STORAGE_CONTAINER_NAME \
|
||||
--name $DEPSHASH \
|
||||
--file $DEPSHASH.tar \
|
||||
- name: Unzip and Ensure Src Cache
|
||||
run: |
|
||||
echo "Downloaded cache is $(du -sh $DEPSHASH.tar | cut -f1)"
|
||||
mkdir temp-cache
|
||||
tar -xvf $DEPSHASH.tar -C temp-cache
|
||||
echo "Unzipped cache is $(du -sh temp-cache/src | cut -f1)"
|
||||
|
||||
if [ -d "temp-cache/src" ]; then
|
||||
echo "Relocating Cache"
|
||||
rm -rf src
|
||||
mv temp-cache/src src
|
||||
|
||||
echo "Deleting zip file"
|
||||
rm -rf $DEPSHASH.tar
|
||||
fi
|
||||
|
||||
if [ ! -d "src/third_party/blink" ]; then
|
||||
echo "Cache was not correctly restored - exiting"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Wiping Electron Directory"
|
||||
rm -rf src/electron
|
||||
- name: Checkout Electron
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
path: src/electron
|
||||
- name: Run Electron Only Hooks
|
||||
run: |
|
||||
echo "Running Electron Only Hooks"
|
||||
gclient runhooks --spec="solutions=[{'name':'src/electron','url':None,'deps_file':'DEPS','custom_vars':{'process_deps':False},'managed':False}]"
|
||||
- name: Regenerate DEPS Hash
|
||||
run: |
|
||||
(cd src/electron && git checkout .) && node src/electron/script/generate-deps-hash.js && cat src/electron/.depshash-target
|
||||
echo "DEPSHASH=$(shasum src/electron/.depshash | cut -f1 -d' ')" >> $GITHUB_ENV
|
||||
- name: Add CHROMIUM_BUILDTOOLS_PATH to env
|
||||
run: echo "CHROMIUM_BUILDTOOLS_PATH=$(pwd)/src/buildtools" >> $GITHUB_ENV
|
||||
- name: Fix Sync
|
||||
# This step is required to correct for differences between "gclient sync"
|
||||
# on Linux and the expected state on macOS. This requires:
|
||||
# 1. Fixing Clang Install (wrong binary)
|
||||
# 2. Fixing esbuild (wrong binary)
|
||||
# 3. Fixing rustc (wrong binary)
|
||||
# 4. Fixing gn (wrong binary)
|
||||
# 5. Fix reclient (wrong binary)
|
||||
# 6. Fixing dsymutil (wrong binary)
|
||||
# 7. Ensuring we are using the correct ninja and adding it to PATH
|
||||
# 8. Fixing angle (wrong remote)
|
||||
run : |
|
||||
SEDOPTION="-i ''"
|
||||
rm -rf src/third_party/llvm-build
|
||||
python3 src/tools/clang/scripts/update.py
|
||||
|
||||
echo 'infra/3pp/tools/esbuild/${platform}' `gclient getdep --deps-file=src/third_party/devtools-frontend/src/DEPS -r 'third_party/esbuild:infra/3pp/tools/esbuild/${platform}'` > esbuild_ensure_file
|
||||
# Remove extra output from calling gclient getdep which always calls update_depot_tools
|
||||
sed -i '' "s/Updating depot_tools... //g" esbuild_ensure_file
|
||||
cipd ensure --root src/third_party/devtools-frontend/src/third_party/esbuild -ensure-file esbuild_ensure_file
|
||||
|
||||
rm -rf src/third_party/rust-toolchain
|
||||
python3 src/tools/rust/update_rust.py
|
||||
|
||||
# Prevent calling gclient getdep which always calls update_depot_tools
|
||||
echo 'gn/gn/mac-${arch}' `gclient getdep --deps-file=src/DEPS -r 'src/buildtools/mac:gn/gn/mac-${arch}'` > gn_ensure_file
|
||||
sed -i '' "s/Updating depot_tools... //g" gn_ensure_file
|
||||
cipd ensure --root src/buildtools/mac -ensure-file gn_ensure_file
|
||||
|
||||
# Prevent calling gclient getdep which always calls update_depot_tools
|
||||
echo 'infra/rbe/client/${platform}' `gclient getdep --deps-file=src/DEPS -r 'src/buildtools/reclient:infra/rbe/client/${platform}'` > gn_ensure_file
|
||||
sed -i '' "s/Updating depot_tools... //g" gn_ensure_file
|
||||
cipd ensure --root src/buildtools/reclient -ensure-file gn_ensure_file
|
||||
python3 src/buildtools/reclient_cfgs/configure_reclient_cfgs.py --rbe_instance "projects/rbe-chrome-untrusted/instances/default_instance" --reproxy_cfg_template reproxy.cfg.template --rewrapper_cfg_project "" --skip_remoteexec_cfg_fetch
|
||||
|
||||
DSYM_SHA_FILE=src/tools/clang/dsymutil/bin/dsymutil.arm64.sha1
|
||||
python3 src/third_party/depot_tools/download_from_google_storage.py --no_resume --no_auth --bucket chromium-browser-clang -s $DSYM_SHA_FILE -o src/tools/clang/dsymutil/bin/dsymutil
|
||||
|
||||
echo 'infra/3pp/tools/ninja/${platform}' `gclient getdep --deps-file=src/DEPS -r 'src/third_party/ninja:infra/3pp/tools/ninja/${platform}'` > ninja_ensure_file
|
||||
sed $SEDOPTION "s/Updating depot_tools... //g" ninja_ensure_file
|
||||
cipd ensure --root src/third_party/ninja -ensure-file ninja_ensure_file
|
||||
|
||||
echo "$(pwd)/src/third_party/ninja" >> $GITHUB_PATH
|
||||
|
||||
cd src/third_party/angle
|
||||
rm -f .git/objects/info/alternates
|
||||
git remote set-url origin https://chromium.googlesource.com/angle/angle.git
|
||||
cp .git/config .git/config.backup
|
||||
git remote remove origin
|
||||
mv .git/config.backup .git/config
|
||||
git fetch
|
||||
- name: Install build-tools & Setup RBE
|
||||
run: |
|
||||
echo "NUMBER_OF_NINJA_PROCESSES=200" >> $GITHUB_ENV
|
||||
cd ~/.electron_build_tools
|
||||
npx yarn --ignore-engines
|
||||
# Pull down credential helper and print status
|
||||
node -e "require('./src/utils/reclient.js').downloadAndPrepare({})"
|
||||
HELPER=$(node -p "require('./src/utils/reclient.js').helperPath({})")
|
||||
$HELPER login
|
||||
echo 'RBE_service='`node -e "console.log(require('./src/utils/reclient.js').serviceAddress)"` >> $GITHUB_ENV
|
||||
echo 'RBE_experimental_credentials_helper='`node -e "console.log(require('./src/utils/reclient.js').helperPath({}))"` >> $GITHUB_ENV
|
||||
echo 'RBE_experimental_credentials_helper_args=print' >> $GITHUB_ENV
|
||||
- name: Build Electron (darwin)
|
||||
run: |
|
||||
cd src/electron
|
||||
# TODO(codebytere): remove this once we figure out why .git/packed-refs is initially missing
|
||||
git pack-refs
|
||||
cd ..
|
||||
|
||||
ulimit -n 10000
|
||||
sudo launchctl limit maxfiles 65536 200000
|
||||
NINJA_SUMMARIZE_BUILD=1 e build -j $NUMBER_OF_NINJA_PROCESSES
|
||||
cp out/Default/.ninja_log out/electron_ninja_log
|
||||
node electron/script/check-symlinks.js
|
||||
- name: Build Electron dist.zip (darwin)
|
||||
run: |
|
||||
cd src
|
||||
e build electron:electron_dist_zip $ADDITIONAL_TARGETS -j $NUMBER_OF_NINJA_PROCESSES
|
||||
if [ "$CHECK_DIST_MANIFEST" == "1" ]; then
|
||||
target_os=mac
|
||||
target_cpu=arm64
|
||||
electron/script/zip_manifests/check-zip-manifest.py out/Default/dist.zip electron/script/zip_manifests/dist_zip.$target_os.$target_cpu.manifest
|
||||
fi
|
||||
- name: Build Mksnapshot (darwin)
|
||||
run: |
|
||||
cd src
|
||||
e build electron:electron_mksnapshot -j $NUMBER_OF_NINJA_PROCESSES
|
||||
gn desc out/Default v8:run_mksnapshot_default args > out/Default/mksnapshot_args
|
||||
# Remove unused args from mksnapshot_args
|
||||
SEDOPTION="-i ''"
|
||||
sed $SEDOPTION '/.*builtins-pgo/d' out/Default/mksnapshot_args
|
||||
sed $SEDOPTION '/--turbo-profiling-input/d' out/Default/mksnapshot_args
|
||||
sed $SEDOPTION '/The gn arg use_goma=true .*/d' out/Default/mksnapshot_args
|
||||
if [ "$SKIP_DIST_ZIP" != "1" ]; then
|
||||
e build electron:electron_mksnapshot_zip -j $NUMBER_OF_NINJA_PROCESSES
|
||||
(cd out/Default; zip mksnapshot.zip mksnapshot_args gen/v8/embedded.S)
|
||||
fi
|
||||
- name: Build Chromedriver (darwin)
|
||||
run: |
|
||||
cd src
|
||||
e build electron:electron_chromedriver -j $NUMBER_OF_NINJA_PROCESSES
|
||||
e build electron:electron_chromedriver_zip
|
||||
- name: Build Node Headers (darwin)
|
||||
run: |
|
||||
cd src
|
||||
e build electron:node_headers
|
||||
- name: Generate & Zip Symbols (darwin)
|
||||
run: |
|
||||
if [ "$GENERATE_SYMBOLS" == "true" ]; then
|
||||
e build electron:electron_symbols
|
||||
fi
|
||||
cd src
|
||||
export BUILD_PATH="$(pwd)/out/Default"
|
||||
e build electron:licenses
|
||||
e build electron:electron_version_file
|
||||
electron/script/zip-symbols.py -b $BUILD_PATH
|
||||
# TODO(vertedinde): handle creating ffmpeg and hunspell for release builds
|
||||
# The current generated_artifacts_<< artifact.key >> name was taken from CircleCI
|
||||
# tp ensure we don't break anything, but we may be able to improve that.
|
||||
- name: Move all Generated Artifacts to Upload Folder
|
||||
run: ./src/electron/script/actions/move-artifacts.sh
|
||||
- name: Upload Generated Artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: generated_artifacts_darwin
|
||||
path: ./generated_artifacts_darwin
|
||||
- name: Persist Build Artifacts
|
||||
uses: actions/cache/save@v4
|
||||
with:
|
||||
path: |
|
||||
src/out/Default/gen/node_headers
|
||||
src/out/Default/overlapped-checker
|
||||
src/electron
|
||||
src/third_party/electron_node
|
||||
src/third_party/nan
|
||||
src/cross-arch-snapshots
|
||||
src/third_party/llvm-build
|
||||
src/build/linux
|
||||
src/buildtools/mac
|
||||
src/buildtools/third_party/libc++
|
||||
src/buildtools/third_party/libc++abi
|
||||
src/third_party/libc++
|
||||
src/third_party/libc++abi
|
||||
src/out/Default/obj/buildtools/third_party
|
||||
src/v8/tools/builtins-pgo
|
||||
key: ${{ runner.os }}-build-artifacts-darwin-${{ github.sha }}
|
||||
- name: Create MAS Config
|
||||
run: |
|
||||
mv src/electron/.github/workflows/config/evm.mas.json $HOME/.electron_build_tools/configs/evm.mas.json
|
||||
echo "MAS_BUILD=true" >> $GITHUB_ENV
|
||||
e use mas
|
||||
- name: Build Electron (mas)
|
||||
run: |
|
||||
rm -rf "src/out/Default/Electron Framework.framework"
|
||||
rm -rf src/out/Default/Electron*.app
|
||||
|
||||
cd src/electron
|
||||
# TODO(codebytere): remove this once we figure out why .git/packed-refs is initially missing
|
||||
git pack-refs
|
||||
cd ..
|
||||
|
||||
ulimit -n 10000
|
||||
sudo launchctl limit maxfiles 65536 200000
|
||||
NINJA_SUMMARIZE_BUILD=1 e build -j $NUMBER_OF_NINJA_PROCESSES
|
||||
cp out/Default/.ninja_log out/electron_ninja_log
|
||||
node electron/script/check-symlinks.js
|
||||
- name: Build Electron dist.zip (mas)
|
||||
run: |
|
||||
cd src
|
||||
e build electron:electron_dist_zip $ADDITIONAL_TARGETS -j $NUMBER_OF_NINJA_PROCESSES
|
||||
if [ "$CHECK_DIST_MANIFEST" == "1" ]; then
|
||||
target_os=mac_mas
|
||||
target_cpu=arm64
|
||||
electron/script/zip_manifests/check-zip-manifest.py out/Default/dist.zip electron/script/zip_manifests/dist_zip.$target_os.$target_cpu.manifest
|
||||
fi
|
||||
- name: Build Mksnapshot (mas)
|
||||
run: |
|
||||
cd src
|
||||
e build electron:electron_mksnapshot -j $NUMBER_OF_NINJA_PROCESSES
|
||||
gn desc out/Default v8:run_mksnapshot_default args > out/Default/mksnapshot_args
|
||||
# Remove unused args from mksnapshot_args
|
||||
SEDOPTION="-i ''"
|
||||
sed $SEDOPTION '/.*builtins-pgo/d' out/Default/mksnapshot_args
|
||||
sed $SEDOPTION '/--turbo-profiling-input/d' out/Default/mksnapshot_args
|
||||
sed $SEDOPTION '/The gn arg use_goma=true .*/d' out/Default/mksnapshot_args
|
||||
if [ "$SKIP_DIST_ZIP" != "1" ]; then
|
||||
e build electron:electron_mksnapshot_zip -j $NUMBER_OF_NINJA_PROCESSES
|
||||
(cd out/Default; zip mksnapshot.zip mksnapshot_args gen/v8/embedded.S)
|
||||
fi
|
||||
- name: Build Chromedriver (mas)
|
||||
run: |
|
||||
cd src
|
||||
e build electron:electron_chromedriver -j $NUMBER_OF_NINJA_PROCESSES
|
||||
e build electron:electron_chromedriver_zip
|
||||
- name: Build Node Headers
|
||||
run: |
|
||||
cd src
|
||||
e build electron:node_headers
|
||||
- name: Generate & Zip Symbols (mas)
|
||||
run: |
|
||||
if [ "$GENERATE_SYMBOLS" == "true" ]; then
|
||||
e build electron:electron_symbols
|
||||
fi
|
||||
cd src
|
||||
export BUILD_PATH="$(pwd)/out/Default"
|
||||
e build electron:licenses
|
||||
e build electron:electron_version_file
|
||||
electron/script/zip-symbols.py -b $BUILD_PATH
|
||||
- name: Move all Generated Artifacts to Upload Folder (mas)
|
||||
run: ./src/electron/script/actions/move-artifacts.sh
|
||||
- name: Upload Generated Artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: generated_artifacts_mas
|
||||
path: ./generated_artifacts_mas
|
||||
- name: Persist Build Artifacts
|
||||
uses: actions/cache/save@v4
|
||||
with:
|
||||
path: |
|
||||
src/out/Default/gen/node_headers
|
||||
src/out/Default/overlapped-checker
|
||||
src/electron
|
||||
src/third_party/electron_node
|
||||
src/third_party/nan
|
||||
src/cross-arch-snapshots
|
||||
src/third_party/llvm-build
|
||||
src/build/linux
|
||||
src/buildtools/mac
|
||||
src/buildtools/third_party/libc++
|
||||
src/buildtools/third_party/libc++abi
|
||||
src/third_party/libc++
|
||||
src/third_party/libc++abi
|
||||
src/out/Default/obj/buildtools/third_party
|
||||
src/v8/tools/builtins-pgo
|
||||
key: ${{ runner.os }}-build-artifacts-mas-${{ github.sha }}
|
||||
test:
|
||||
runs-on: macos-13-xlarge
|
||||
needs: build
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
build-type: [darwin, mas]
|
||||
env:
|
||||
BUILD_TYPE: ${{ matrix.build-type }}
|
||||
steps:
|
||||
- name: Load Build Tools
|
||||
run: |
|
||||
yarn add git://github.com/electron/build-tools.git#2bb63e2e7877491b52f972532b52adc979a6ec2f
|
||||
e init --root=$(pwd) --out=Default testing
|
||||
- name: Checkout Electron
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
path: src/electron
|
||||
- name: Setup Node.js/npm
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 20.11.x
|
||||
cache: yarn
|
||||
cache-dependency-path: src/electron/yarn.lock
|
||||
- name: Install Dependencies
|
||||
run: |
|
||||
cd src/electron
|
||||
node script/yarn install
|
||||
- name: Get Depot Tools
|
||||
timeout-minutes: 5
|
||||
run: |
|
||||
git clone --depth=1 https://chromium.googlesource.com/chromium/tools/depot_tools.git
|
||||
if [ "`uname`" == "Darwin" ]; then
|
||||
# remove ninjalog_uploader_wrapper.py from autoninja since we don't use it and it causes problems
|
||||
sed -i '' '/ninjalog_uploader_wrapper.py/d' ./depot_tools/autoninja
|
||||
else
|
||||
sed -i '/ninjalog_uploader_wrapper.py/d' ./depot_tools/autoninja
|
||||
# Remove swift-format dep from cipd on macOS until we send a patch upstream.
|
||||
cd depot_tools
|
||||
git apply --3way ../src/electron/.github/workflows/config/gclient.diff
|
||||
fi
|
||||
# Ensure depot_tools does not update.
|
||||
test -d depot_tools && cd depot_tools
|
||||
touch .disable_auto_update
|
||||
- name: Add Depot Tools to PATH
|
||||
run: echo "$(pwd)/depot_tools" >> $GITHUB_PATH
|
||||
- name: Download Generated Artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: generated_artifacts_${{ matrix.build-type }}
|
||||
path: ./generated_artifacts_${{ matrix.build-type }}
|
||||
- name: Restore Persisted Build Artifacts
|
||||
uses: actions/cache/restore@v4
|
||||
with:
|
||||
path: |
|
||||
src/out/Default/gen/node_headers
|
||||
src/out/Default/overlapped-checker
|
||||
src/electron
|
||||
src/third_party/electron_node
|
||||
src/third_party/nan
|
||||
src/cross-arch-snapshots
|
||||
src/third_party/llvm-build
|
||||
src/build/linux
|
||||
src/buildtools/mac
|
||||
src/buildtools/third_party/libc++
|
||||
src/buildtools/third_party/libc++abi
|
||||
src/third_party/libc++
|
||||
src/third_party/libc++abi
|
||||
src/out/Default/obj/buildtools/third_party
|
||||
src/v8/tools/builtins-pgo
|
||||
key: ${{ runner.os }}-build-artifacts-${{ matrix.build-type }}-${{ github.sha }}
|
||||
- name: Restore Generated Artifacts
|
||||
run: ./src/electron/script/actions/restore-artifacts.sh
|
||||
- name: Unzip Dist, Mksnapshot & Chromedriver
|
||||
run: |
|
||||
cd src/out/Default
|
||||
unzip -:o dist.zip
|
||||
unzip -:o chromedriver.zip
|
||||
unzip -:o mksnapshot.zip
|
||||
- name: Run Electron Tests
|
||||
env:
|
||||
MOCHA_REPORTER: mocha-multi-reporters
|
||||
ELECTRON_TEST_RESULTS_DIR: junit
|
||||
MOCHA_MULTI_REPORTERS: mocha-junit-reporter, tap
|
||||
ELECTRON_DISABLE_SECURITY_WARNINGS: 1
|
||||
ELECTRON_SKIP_NATIVE_MODULE_TESTS: true
|
||||
run: |
|
||||
cd src/electron
|
||||
node script/yarn test --runners=main --trace-uncaught --enable-logging
|
||||
@@ -41,7 +41,7 @@ etc.
|
||||
|
||||
* Write [remark](https://github.com/remarkjs/remark) markdown style.
|
||||
|
||||
You can run `npm run lint-docs` to ensure that your documentation changes are
|
||||
You can run `npm run lint:docs` to ensure that your documentation changes are
|
||||
formatted correctly.
|
||||
|
||||
## JavaScript
|
||||
|
||||
@@ -36,6 +36,29 @@ BrowserWindow.prototype._init = function (this: BWT) {
|
||||
app.emit('browser-window-focus', event, this);
|
||||
});
|
||||
|
||||
let unresponsiveEvent: NodeJS.Timeout | null = null;
|
||||
const emitUnresponsiveEvent = () => {
|
||||
unresponsiveEvent = null;
|
||||
if (!this.isDestroyed() && this.isEnabled()) { this.emit('unresponsive'); }
|
||||
};
|
||||
this.webContents.on('unresponsive', () => {
|
||||
if (!unresponsiveEvent) { unresponsiveEvent = setTimeout(emitUnresponsiveEvent, 50); }
|
||||
});
|
||||
this.webContents.on('responsive', () => {
|
||||
if (unresponsiveEvent) {
|
||||
clearTimeout(unresponsiveEvent);
|
||||
unresponsiveEvent = null;
|
||||
}
|
||||
this.emit('responsive');
|
||||
});
|
||||
this.on('close', () => {
|
||||
if (!unresponsiveEvent) { unresponsiveEvent = setTimeout(emitUnresponsiveEvent, 5000); }
|
||||
});
|
||||
this.webContents.on('destroyed', () => {
|
||||
if (unresponsiveEvent) clearTimeout(unresponsiveEvent);
|
||||
unresponsiveEvent = null;
|
||||
});
|
||||
|
||||
// Subscribe to visibilityState changes and pass to renderer process.
|
||||
let isVisible = this.isVisible() && !this.isMinimized();
|
||||
const visibilityChanged = () => {
|
||||
|
||||
@@ -128,3 +128,4 @@ fix_getcursorscreenpoint_wrongly_returns_0_0.patch
|
||||
fix_add_support_for_skipping_first_2_no-op_refreshes_in_thumb_cap.patch
|
||||
refactor_expose_file_system_access_blocklist.patch
|
||||
revert_power_update_trace_counter_in_power_monitor.patch
|
||||
cherry-pick-013961609785.patch
|
||||
|
||||
140
patches/chromium/cherry-pick-013961609785.patch
Normal file
140
patches/chromium/cherry-pick-013961609785.patch
Normal file
@@ -0,0 +1,140 @@
|
||||
From 0139616097859b369120628ea843598550929526 Mon Sep 17 00:00:00 2001
|
||||
From: John Stiles <johnstiles@google.com>
|
||||
Date: Thu, 28 Mar 2024 00:51:13 +0000
|
||||
Subject: [PATCH] Detect overflow in JPEG image size calculations.
|
||||
|
||||
Bug: 330756841
|
||||
Change-Id: Ib30493152e08fd2347f76de276c5805d6fef9a7d
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5402199
|
||||
Commit-Queue: John Stiles <johnstiles@google.com>
|
||||
Reviewed-by: Daniel Cheng <dcheng@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/main@{#1279376}
|
||||
---
|
||||
|
||||
diff --git a/ui/gfx/codec/jpeg_codec.cc b/ui/gfx/codec/jpeg_codec.cc
|
||||
index a4de170..595966d 100644
|
||||
--- a/ui/gfx/codec/jpeg_codec.cc
|
||||
+++ b/ui/gfx/codec/jpeg_codec.cc
|
||||
@@ -6,10 +6,12 @@
|
||||
|
||||
#include <setjmp.h>
|
||||
|
||||
+#include <climits>
|
||||
#include <memory>
|
||||
#include <ostream>
|
||||
|
||||
#include "base/notreached.h"
|
||||
+#include "base/numerics/checked_math.h"
|
||||
#include "third_party/skia/include/core/SkBitmap.h"
|
||||
#include "third_party/skia/include/core/SkColorPriv.h"
|
||||
#include "ui/gfx/codec/vector_wstream.h"
|
||||
@@ -244,16 +246,27 @@
|
||||
|
||||
jpeg_start_decompress(cinfo.get());
|
||||
|
||||
- // FIXME(brettw) we may want to allow the capability for callers to request
|
||||
- // how to align row lengths as we do for the compressor.
|
||||
- int row_read_stride = cinfo->output_width * cinfo->output_components;
|
||||
+ // Confirm that the image width * height * component-size fits within an int.
|
||||
+ // Note that image width and height are unsigned ints (JDIMENSION) in memory,
|
||||
+ // but the file format only holds a uint16.
|
||||
+ base::CheckedNumeric<size_t> checked_output_size = cinfo->output_width;
|
||||
+ checked_output_size *= cinfo->output_components;
|
||||
|
||||
- // Create memory for a decoded image and write decoded lines to the memory
|
||||
- // without conversions same as JPEGCodec::Encode().
|
||||
- int row_write_stride = row_read_stride;
|
||||
- output->resize(row_write_stride * cinfo->output_height);
|
||||
+ // This shouldn't ever overflow a `size_t`; it's multiplying a uint16 by four.
|
||||
+ size_t row_write_stride = checked_output_size.ValueOrDie();
|
||||
|
||||
- for (int row = 0; row < static_cast<int>(cinfo->output_height); row++) {
|
||||
+ // Extremely large JPEGs could overflow here if `size_t` is 32 bits.
|
||||
+ checked_output_size *= cinfo->output_height;
|
||||
+ size_t output_size = checked_output_size.ValueOrDefault(INT_MAX);
|
||||
+ if (output_size >= INT_MAX) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ // Create memory for a decoded image.
|
||||
+ output->resize(output_size);
|
||||
+
|
||||
+ // Write decoded lines to the memory.
|
||||
+ for (unsigned int row = 0; row < cinfo->output_height; row++) {
|
||||
unsigned char* rowptr = &(*output)[row * row_write_stride];
|
||||
if (!jpeg_read_scanlines(cinfo.get(), &rowptr, 1))
|
||||
return false;
|
||||
diff --git a/ui/gfx/codec/jpeg_codec_unittest.cc b/ui/gfx/codec/jpeg_codec_unittest.cc
|
||||
index 9f1bee9..b446fe7 100644
|
||||
--- a/ui/gfx/codec/jpeg_codec_unittest.cc
|
||||
+++ b/ui/gfx/codec/jpeg_codec_unittest.cc
|
||||
@@ -61,6 +61,53 @@
|
||||
"\xfa\xff\xda\x00\x0c\x03\x01\x00\x02\x11\x03\x11\x00\x3f\x00\xf9"
|
||||
"\xd2\x8a\x28\xaf\xc3\x0f\xf5\x4c\xff\xd9";
|
||||
|
||||
+// This is a copy of the above JPEG, with the Start-of-Frame header manually
|
||||
+// rewritten to indicate an image size of 25000x25000. An image this large would
|
||||
+// require more than 2GB of RAM to decode, so the decoder will reject the image
|
||||
+// as soon as the header is parsed.
|
||||
+const uint8_t kExtremelyLargeTestImage[] =
|
||||
+ "\xff\xd8\xff\xe0\x00\x10\x4a\x46\x49\x46\x00\x01\x01\x00\x00\x01"
|
||||
+ "\x00\x01\x00\x00\xff\xdb\x00\x43\x00\x03\x02\x02\x03\x02\x02\x03"
|
||||
+ "\x03\x03\x03\x04\x03\x03\x04\x05\x08\x05\x05\x04\x04\x05\x0a\x07"
|
||||
+ "\x07\x06\x08\x0c\x0a\x0c\x0c\x0b\x0a\x0b\x0b\x0d\x0e\x12\x10\x0d"
|
||||
+ "\x0e\x11\x0e\x0b\x0b\x10\x16\x10\x11\x13\x14\x15\x15\x15\x0c\x0f"
|
||||
+ "\x17\x18\x16\x14\x18\x12\x14\x15\x14\xff\xdb\x00\x43\x01\x03\x04"
|
||||
+ "\x04\x05\x04\x05\x09\x05\x05\x09\x14\x0d\x0b\x0d\x14\x14\x14\x14"
|
||||
+ "\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14"
|
||||
+ "\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14"
|
||||
+ "\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\xff\xc0"
|
||||
+ "\x00\x11\x08\x61\xa8\x61\xa8\x03\x01\x22\x00\x02\x11\x01\x03\x11"
|
||||
+ // ^^ ^^ ^^ ^^ image size forced to 25000x25000
|
||||
+ "\x01\xff\xc4\x00\x1f\x00\x00\x01\x05\x01\x01\x01\x01\x01\x01\x00"
|
||||
+ "\x00\x00\x00\x00\x00\x00\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09"
|
||||
+ "\x0a\x0b\xff\xc4\x00\xb5\x10\x00\x02\x01\x03\x03\x02\x04\x03\x05"
|
||||
+ "\x05\x04\x04\x00\x00\x01\x7d\x01\x02\x03\x00\x04\x11\x05\x12\x21"
|
||||
+ "\x31\x41\x06\x13\x51\x61\x07\x22\x71\x14\x32\x81\x91\xa1\x08\x23"
|
||||
+ "\x42\xb1\xc1\x15\x52\xd1\xf0\x24\x33\x62\x72\x82\x09\x0a\x16\x17"
|
||||
+ "\x18\x19\x1a\x25\x26\x27\x28\x29\x2a\x34\x35\x36\x37\x38\x39\x3a"
|
||||
+ "\x43\x44\x45\x46\x47\x48\x49\x4a\x53\x54\x55\x56\x57\x58\x59\x5a"
|
||||
+ "\x63\x64\x65\x66\x67\x68\x69\x6a\x73\x74\x75\x76\x77\x78\x79\x7a"
|
||||
+ "\x83\x84\x85\x86\x87\x88\x89\x8a\x92\x93\x94\x95\x96\x97\x98\x99"
|
||||
+ "\x9a\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xb2\xb3\xb4\xb5\xb6\xb7"
|
||||
+ "\xb8\xb9\xba\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xd2\xd3\xd4\xd5"
|
||||
+ "\xd6\xd7\xd8\xd9\xda\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xf1"
|
||||
+ "\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xff\xc4\x00\x1f\x01\x00\x03"
|
||||
+ "\x01\x01\x01\x01\x01\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x01"
|
||||
+ "\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\xff\xc4\x00\xb5\x11\x00"
|
||||
+ "\x02\x01\x02\x04\x04\x03\x04\x07\x05\x04\x04\x00\x01\x02\x77\x00"
|
||||
+ "\x01\x02\x03\x11\x04\x05\x21\x31\x06\x12\x41\x51\x07\x61\x71\x13"
|
||||
+ "\x22\x32\x81\x08\x14\x42\x91\xa1\xb1\xc1\x09\x23\x33\x52\xf0\x15"
|
||||
+ "\x62\x72\xd1\x0a\x16\x24\x34\xe1\x25\xf1\x17\x18\x19\x1a\x26\x27"
|
||||
+ "\x28\x29\x2a\x35\x36\x37\x38\x39\x3a\x43\x44\x45\x46\x47\x48\x49"
|
||||
+ "\x4a\x53\x54\x55\x56\x57\x58\x59\x5a\x63\x64\x65\x66\x67\x68\x69"
|
||||
+ "\x6a\x73\x74\x75\x76\x77\x78\x79\x7a\x82\x83\x84\x85\x86\x87\x88"
|
||||
+ "\x89\x8a\x92\x93\x94\x95\x96\x97\x98\x99\x9a\xa2\xa3\xa4\xa5\xa6"
|
||||
+ "\xa7\xa8\xa9\xaa\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xc2\xc3\xc4"
|
||||
+ "\xc5\xc6\xc7\xc8\xc9\xca\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xe2"
|
||||
+ "\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9"
|
||||
+ "\xfa\xff\xda\x00\x0c\x03\x01\x00\x02\x11\x03\x11\x00\x3f\x00\xf9"
|
||||
+ "\xd2\x8a\x28\xaf\xc3\x0f\xf5\x4c\xff\xd9";
|
||||
+
|
||||
} // namespace
|
||||
|
||||
namespace gfx {
|
||||
@@ -211,4 +258,15 @@
|
||||
encode_loop.Run();
|
||||
}
|
||||
|
||||
+TEST(JPEGCodec, ExtremelyLargeImage) {
|
||||
+ std::vector<unsigned char> output;
|
||||
+ int outw, outh;
|
||||
+ bool ok = JPEGCodec::Decode(kExtremelyLargeTestImage,
|
||||
+ std::size(kExtremelyLargeTestImage),
|
||||
+ JPEGCodec::FORMAT_RGBA, &output, &outw, &outh);
|
||||
+ EXPECT_FALSE(ok);
|
||||
+ EXPECT_EQ(outw, 25000);
|
||||
+ EXPECT_EQ(outh, 25000);
|
||||
+}
|
||||
+
|
||||
} // namespace gfx
|
||||
40
script/actions/move-artifacts.sh
Executable file
40
script/actions/move-artifacts.sh
Executable file
@@ -0,0 +1,40 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -eo pipefail
|
||||
|
||||
if [ -z "$MAS_BUILD" ]; then
|
||||
BUILD_TYPE="darwin"
|
||||
else
|
||||
BUILD_TYPE="mas"
|
||||
fi
|
||||
|
||||
rm -rf generated_artifacts_${BUILD_TYPE}
|
||||
mkdir generated_artifacts_${BUILD_TYPE}
|
||||
|
||||
mv_if_exist() {
|
||||
if [ -f "$1" ] || [ -d "$1" ]; then
|
||||
echo Storing $1
|
||||
mv $1 generated_artifacts_${BUILD_TYPE}
|
||||
else
|
||||
echo Skipping $1 - It is not present on disk
|
||||
fi
|
||||
}
|
||||
cp_if_exist() {
|
||||
if [ -f "$1" ] || [ -d "$1" ]; then
|
||||
echo Storing $1
|
||||
cp $1 generated_artifacts_${BUILD_TYPE}
|
||||
else
|
||||
echo Skipping $1 - It is not present on disk
|
||||
fi
|
||||
}
|
||||
|
||||
mv_if_exist src/out/Default/dist.zip
|
||||
mv_if_exist src/out/Default/gen/node_headers.tar.gz
|
||||
mv_if_exist src/out/Default/symbols.zip
|
||||
mv_if_exist src/out/Default/mksnapshot.zip
|
||||
mv_if_exist src/out/Default/chromedriver.zip
|
||||
mv_if_exist src/out/ffmpeg/ffmpeg.zip
|
||||
mv_if_exist src/out/Default/hunspell_dictionaries.zip
|
||||
mv_if_exist src/cross-arch-snapshots
|
||||
cp_if_exist src/out/electron_ninja_log
|
||||
cp_if_exist src/out/Default/.ninja_log
|
||||
22
script/actions/restore-artifacts.sh
Executable file
22
script/actions/restore-artifacts.sh
Executable file
@@ -0,0 +1,22 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -eo pipefail
|
||||
|
||||
mv_if_exist() {
|
||||
if [ -f "generated_artifacts_${BUILD_TYPE}/$1" ] || [ -d "generated_artifacts_${BUILD_TYPE}/$1" ]; then
|
||||
echo Restoring $1 to $2
|
||||
mkdir -p $2
|
||||
mv generated_artifacts_${BUILD_TYPE}/$1 $2
|
||||
else
|
||||
echo Skipping $1 - It is not present on disk
|
||||
fi
|
||||
}
|
||||
|
||||
mv_if_exist dist.zip src/out/Default
|
||||
mv_if_exist node_headers.tar.gz src/out/Default/gen
|
||||
mv_if_exist symbols.zip src/out/Default
|
||||
mv_if_exist mksnapshot.zip src/out/Default
|
||||
mv_if_exist chromedriver.zip src/out/Default
|
||||
mv_if_exist ffmpeg.zip src/out/ffmpeg
|
||||
mv_if_exist hunspell_dictionaries.zip src/out/Default
|
||||
mv_if_exist cross-arch-snapshots src
|
||||
91
script/azure_cli_deb_install.sh
Executable file
91
script/azure_cli_deb_install.sh
Executable file
@@ -0,0 +1,91 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
#######################################################################################################################
|
||||
# This script does three fundamental things: #
|
||||
# 1. Add Microsoft's GPG Key has a trusted source of apt packages. #
|
||||
# 2. Add Microsoft's repositories as a source for apt packages. #
|
||||
# 3. Installs the Azure CLI from those repositories. #
|
||||
# Given the nature of this script, it must be executed with elevated privileges, i.e. with `sudo`. #
|
||||
# #
|
||||
# Copied from https://azurecliprod.blob.core.windows.net/$root/deb_install.sh #
|
||||
#######################################################################################################################
|
||||
|
||||
set -e
|
||||
|
||||
if [[ $# -ge 1 && $1 == "-y" ]]; then
|
||||
global_consent=0
|
||||
else
|
||||
global_consent=1
|
||||
fi
|
||||
|
||||
function assert_consent {
|
||||
if [[ $2 -eq 0 ]]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo -n "$1 [Y/n] "
|
||||
read consent
|
||||
if [[ ! "${consent}" == "y" && ! "${consent}" == "Y" && ! "${consent}" == "" ]]; then
|
||||
echo "'${consent}'"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
global_consent=0 # Artificially giving global consent after review-feedback. Remove this line to enable interactive mode
|
||||
|
||||
setup() {
|
||||
|
||||
assert_consent "Add packages necessary to modify your apt-package sources?" ${global_consent}
|
||||
set -v
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
apt-get update
|
||||
apt-get install -y apt-transport-https lsb-release gnupg curl
|
||||
set +v
|
||||
|
||||
assert_consent "Add Microsoft as a trusted package signer?" ${global_consent}
|
||||
set -v
|
||||
curl -sL https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > /etc/apt/trusted.gpg.d/microsoft.gpg
|
||||
set +v
|
||||
|
||||
assert_consent "Add the Azure CLI Repository to your apt sources?" ${global_consent}
|
||||
set -v
|
||||
# Use env var DIST_CODE for the package dist name if provided
|
||||
if [[ -z $DIST_CODE ]]; then
|
||||
CLI_REPO=$(lsb_release -cs)
|
||||
shopt -s nocasematch
|
||||
ERROR_MSG="Unable to find a package for your system. Please check if an existing package in https://packages.microsoft.com/repos/azure-cli/dists/ can be used in your system and install with the dist name: 'curl -sL https://aka.ms/InstallAzureCLIDeb | sudo DIST_CODE=<dist_code_name> bash'"
|
||||
if [[ ! $(curl -sL https://packages.microsoft.com/repos/azure-cli/dists/) =~ $CLI_REPO ]]; then
|
||||
DIST=$(lsb_release -is)
|
||||
if [[ $DIST =~ "Ubuntu" ]]; then
|
||||
CLI_REPO="jammy"
|
||||
elif [[ $DIST =~ "Debian" ]]; then
|
||||
CLI_REPO="bookworm"
|
||||
elif [[ $DIST =~ "LinuxMint" ]]; then
|
||||
CLI_REPO=$(cat /etc/os-release | grep -Po 'UBUNTU_CODENAME=\K.*') || true
|
||||
if [[ -z $CLI_REPO ]]; then
|
||||
echo $ERROR_MSG
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo $ERROR_MSG
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
else
|
||||
CLI_REPO=$DIST_CODE
|
||||
if [[ ! $(curl -sL https://packages.microsoft.com/repos/azure-cli/dists/) =~ $CLI_REPO ]]; then
|
||||
echo "Unable to find an azure-cli package with DIST_CODE=$CLI_REPO in https://packages.microsoft.com/repos/azure-cli/dists/."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
echo "deb [arch=$(dpkg --print-architecture)] https://packages.microsoft.com/repos/azure-cli/ ${CLI_REPO} main" \
|
||||
> /etc/apt/sources.list.d/azure-cli.list
|
||||
apt-get update
|
||||
set +v
|
||||
|
||||
assert_consent "Install the Azure CLI?" ${global_consent}
|
||||
apt-get install -y azure-cli
|
||||
|
||||
}
|
||||
|
||||
setup # ensure the whole file is downloaded before executing
|
||||
@@ -485,6 +485,24 @@ const getNotes = async (fromRef, toRef, newVersion) => {
|
||||
return notes;
|
||||
};
|
||||
|
||||
const compareVersions = (v1, v2) => {
|
||||
const [split1, split2] = [v1.split('.'), v2.split('.')];
|
||||
|
||||
if (split1.length !== split2.length) {
|
||||
throw new Error(`Expected version strings to have same number of sections: ${split1} and ${split2}`);
|
||||
}
|
||||
for (let i = 0; i < split1.length; i++) {
|
||||
const p1 = parseInt(split1[i], 10);
|
||||
const p2 = parseInt(split2[i], 10);
|
||||
|
||||
if (p1 > p2) return 1;
|
||||
else if (p1 < p2) return -1;
|
||||
// Continue checking the value if this portion is equal
|
||||
}
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
const removeSupercededStackUpdates = (commits) => {
|
||||
const updateRegex = /^Updated ([a-zA-Z.]+) to v?([\d.]+)/;
|
||||
const notupdates = [];
|
||||
@@ -496,8 +514,9 @@ const removeSupercededStackUpdates = (commits) => {
|
||||
notupdates.push(commit);
|
||||
continue;
|
||||
}
|
||||
|
||||
const [, dep, version] = match;
|
||||
if (!newest[dep] || newest[dep].version < version) {
|
||||
if (!newest[dep] || compareVersions(version, newest[dep].version) > 0) {
|
||||
newest[dep] = { commit, version };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,14 +33,12 @@ base::FilePath GetHelperAppPath(const base::FilePath& frameworks_path,
|
||||
base::PathService::Get(base::FILE_EXE, &path);
|
||||
|
||||
std::string helper_name = "Helper";
|
||||
if (base::EndsWith(path.value(), content::kMacHelperSuffix_renderer,
|
||||
base::CompareCase::SENSITIVE)) {
|
||||
if (const auto& val = path.value();
|
||||
val.ends_with(content::kMacHelperSuffix_renderer)) {
|
||||
helper_name += content::kMacHelperSuffix_renderer;
|
||||
} else if (base::EndsWith(path.value(), content::kMacHelperSuffix_gpu,
|
||||
base::CompareCase::SENSITIVE)) {
|
||||
} else if (val.ends_with(content::kMacHelperSuffix_gpu)) {
|
||||
helper_name += content::kMacHelperSuffix_gpu;
|
||||
} else if (base::EndsWith(path.value(), content::kMacHelperSuffix_plugin,
|
||||
base::CompareCase::SENSITIVE)) {
|
||||
} else if (val.ends_with(content::kMacHelperSuffix_plugin)) {
|
||||
helper_name += content::kMacHelperSuffix_plugin;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
#include "base/containers/contains.h"
|
||||
#include "base/task/single_thread_task_runner.h"
|
||||
#include "content/public/common/color_parser.h"
|
||||
#include "electron/buildflags/buildflags.h"
|
||||
#include "gin/dictionary.h"
|
||||
#include "shell/browser/api/electron_api_menu.h"
|
||||
@@ -36,6 +37,7 @@
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
#include "shell/browser/ui/views/win_frame_view.h"
|
||||
#include "shell/browser/ui/win/taskbar_host.h"
|
||||
#include "ui/base/win/shell.h"
|
||||
#endif
|
||||
@@ -1039,6 +1041,63 @@ void BaseWindow::SetAppDetails(const gin_helper::Dictionary& options) {
|
||||
relaunch_command, relaunch_display_name,
|
||||
window_->GetAcceleratedWidget());
|
||||
}
|
||||
|
||||
void BaseWindow::SetTitleBarOverlay(const gin_helper::Dictionary& options,
|
||||
gin_helper::Arguments* args) {
|
||||
// Ensure WCO is already enabled on this window
|
||||
if (!window_->titlebar_overlay_enabled()) {
|
||||
args->ThrowError("Titlebar overlay is not enabled");
|
||||
return;
|
||||
}
|
||||
|
||||
auto* window = static_cast<NativeWindowViews*>(window_.get());
|
||||
bool updated = false;
|
||||
|
||||
// Check and update the button color
|
||||
std::string btn_color;
|
||||
if (options.Get(options::kOverlayButtonColor, &btn_color)) {
|
||||
// Parse the string as a CSS color
|
||||
SkColor color;
|
||||
if (!content::ParseCssColorString(btn_color, &color)) {
|
||||
args->ThrowError("Could not parse color as CSS color");
|
||||
return;
|
||||
}
|
||||
|
||||
// Update the view
|
||||
window->set_overlay_button_color(color);
|
||||
updated = true;
|
||||
}
|
||||
|
||||
// Check and update the symbol color
|
||||
std::string symbol_color;
|
||||
if (options.Get(options::kOverlaySymbolColor, &symbol_color)) {
|
||||
// Parse the string as a CSS color
|
||||
SkColor color;
|
||||
if (!content::ParseCssColorString(symbol_color, &color)) {
|
||||
args->ThrowError("Could not parse symbol color as CSS color");
|
||||
return;
|
||||
}
|
||||
|
||||
// Update the view
|
||||
window->set_overlay_symbol_color(color);
|
||||
updated = true;
|
||||
}
|
||||
|
||||
// Check and update the height
|
||||
int height = 0;
|
||||
if (options.Get(options::kOverlayHeight, &height)) {
|
||||
window->set_titlebar_overlay_height(height);
|
||||
updated = true;
|
||||
}
|
||||
|
||||
// If anything was updated, invalidate the layout and schedule a paint of the
|
||||
// window's frame view
|
||||
if (updated) {
|
||||
auto* frame_view = static_cast<WinFrameView*>(
|
||||
window->widget()->non_client_view()->frame_view());
|
||||
frame_view->InvalidateCaptionButtons();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int32_t BaseWindow::GetID() const {
|
||||
@@ -1227,6 +1286,7 @@ void BaseWindow::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("setThumbnailClip", &BaseWindow::SetThumbnailClip)
|
||||
.SetMethod("setThumbnailToolTip", &BaseWindow::SetThumbnailToolTip)
|
||||
.SetMethod("setAppDetails", &BaseWindow::SetAppDetails)
|
||||
.SetMethod("setTitleBarOverlay", &BaseWindow::SetTitleBarOverlay)
|
||||
#endif
|
||||
.SetProperty("id", &BaseWindow::GetID);
|
||||
}
|
||||
|
||||
@@ -241,6 +241,8 @@ class BaseWindow : public gin_helper::TrackableObject<BaseWindow>,
|
||||
bool SetThumbnailClip(const gfx::Rect& region);
|
||||
bool SetThumbnailToolTip(const std::string& tooltip);
|
||||
void SetAppDetails(const gin_helper::Dictionary& options);
|
||||
void SetTitleBarOverlay(const gin_helper::Dictionary& options,
|
||||
gin_helper::Arguments* args);
|
||||
#endif
|
||||
int32_t GetID() const;
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#include "content/browser/web_contents/web_contents_impl.h" // nogncheck
|
||||
#include "content/public/browser/render_process_host.h"
|
||||
#include "content/public/browser/render_view_host.h"
|
||||
#include "content/public/common/color_parser.h"
|
||||
#include "shell/browser/api/electron_api_web_contents_view.h"
|
||||
#include "shell/browser/browser.h"
|
||||
#include "shell/browser/web_contents_preferences.h"
|
||||
@@ -27,10 +26,6 @@
|
||||
#include "shell/browser/native_window_views.h"
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
#include "shell/browser/ui/views/win_frame_view.h"
|
||||
#endif
|
||||
|
||||
namespace electron::api {
|
||||
|
||||
BrowserWindow::BrowserWindow(gin::Arguments* args,
|
||||
@@ -117,19 +112,6 @@ BrowserWindow::~BrowserWindow() {
|
||||
|
||||
void BrowserWindow::BeforeUnloadDialogCancelled() {
|
||||
WindowList::WindowCloseCancelled(window());
|
||||
// Cancel unresponsive event when window close is cancelled.
|
||||
window_unresponsive_closure_.Cancel();
|
||||
}
|
||||
|
||||
void BrowserWindow::OnRendererUnresponsive(content::RenderProcessHost*) {
|
||||
// Schedule the unresponsive shortly later, since we may receive the
|
||||
// responsive event soon. This could happen after the whole application had
|
||||
// blocked for a while.
|
||||
// Also notice that when closing this event would be ignored because we have
|
||||
// explicitly started a close timeout counter. This is on purpose because we
|
||||
// don't want the unresponsive event to be sent too early when user is closing
|
||||
// the window.
|
||||
ScheduleUnresponsiveEvent(50);
|
||||
}
|
||||
|
||||
void BrowserWindow::WebContentsDestroyed() {
|
||||
@@ -137,11 +119,6 @@ void BrowserWindow::WebContentsDestroyed() {
|
||||
CloseImmediately();
|
||||
}
|
||||
|
||||
void BrowserWindow::OnRendererResponsive(content::RenderProcessHost*) {
|
||||
window_unresponsive_closure_.Cancel();
|
||||
Emit("responsive");
|
||||
}
|
||||
|
||||
void BrowserWindow::OnSetContentBounds(const gfx::Rect& rect) {
|
||||
// window.resizeTo(...)
|
||||
// window.moveTo(...)
|
||||
@@ -177,13 +154,6 @@ void BrowserWindow::OnCloseButtonClicked(bool* prevent_default) {
|
||||
// first, and when the web page is closed the window will also be closed.
|
||||
*prevent_default = true;
|
||||
|
||||
// Assume the window is not responding if it doesn't cancel the close and is
|
||||
// not closed in 5s, in this way we can quickly show the unresponsive
|
||||
// dialog when the window is busy executing some script without waiting for
|
||||
// the unresponsive timeout.
|
||||
if (window_unresponsive_closure_.IsCancelled())
|
||||
ScheduleUnresponsiveEvent(5000);
|
||||
|
||||
// Already closed by renderer.
|
||||
if (!web_contents() || !api_web_contents_)
|
||||
return;
|
||||
@@ -250,9 +220,6 @@ void BrowserWindow::CloseImmediately() {
|
||||
}
|
||||
|
||||
BaseWindow::CloseImmediately();
|
||||
|
||||
// Do not sent "unresponsive" event after window is closed.
|
||||
window_unresponsive_closure_.Cancel();
|
||||
}
|
||||
|
||||
void BrowserWindow::Focus() {
|
||||
@@ -303,83 +270,6 @@ v8::Local<v8::Value> BrowserWindow::GetWebContents(v8::Isolate* isolate) {
|
||||
return v8::Local<v8::Value>::New(isolate, web_contents_);
|
||||
}
|
||||
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
void BrowserWindow::SetTitleBarOverlay(const gin_helper::Dictionary& options,
|
||||
gin_helper::Arguments* args) {
|
||||
// Ensure WCO is already enabled on this window
|
||||
if (!window_->titlebar_overlay_enabled()) {
|
||||
args->ThrowError("Titlebar overlay is not enabled");
|
||||
return;
|
||||
}
|
||||
|
||||
auto* window = static_cast<NativeWindowViews*>(window_.get());
|
||||
bool updated = false;
|
||||
|
||||
// Check and update the button color
|
||||
std::string btn_color;
|
||||
if (options.Get(options::kOverlayButtonColor, &btn_color)) {
|
||||
// Parse the string as a CSS color
|
||||
SkColor color;
|
||||
if (!content::ParseCssColorString(btn_color, &color)) {
|
||||
args->ThrowError("Could not parse color as CSS color");
|
||||
return;
|
||||
}
|
||||
|
||||
// Update the view
|
||||
window->set_overlay_button_color(color);
|
||||
updated = true;
|
||||
}
|
||||
|
||||
// Check and update the symbol color
|
||||
std::string symbol_color;
|
||||
if (options.Get(options::kOverlaySymbolColor, &symbol_color)) {
|
||||
// Parse the string as a CSS color
|
||||
SkColor color;
|
||||
if (!content::ParseCssColorString(symbol_color, &color)) {
|
||||
args->ThrowError("Could not parse symbol color as CSS color");
|
||||
return;
|
||||
}
|
||||
|
||||
// Update the view
|
||||
window->set_overlay_symbol_color(color);
|
||||
updated = true;
|
||||
}
|
||||
|
||||
// Check and update the height
|
||||
int height = 0;
|
||||
if (options.Get(options::kOverlayHeight, &height)) {
|
||||
window->set_titlebar_overlay_height(height);
|
||||
updated = true;
|
||||
}
|
||||
|
||||
// If anything was updated, invalidate the layout and schedule a paint of the
|
||||
// window's frame view
|
||||
if (updated) {
|
||||
auto* frame_view = static_cast<WinFrameView*>(
|
||||
window->widget()->non_client_view()->frame_view());
|
||||
frame_view->InvalidateCaptionButtons();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void BrowserWindow::ScheduleUnresponsiveEvent(int ms) {
|
||||
if (!window_unresponsive_closure_.IsCancelled())
|
||||
return;
|
||||
|
||||
window_unresponsive_closure_.Reset(base::BindRepeating(
|
||||
&BrowserWindow::NotifyWindowUnresponsive, GetWeakPtr()));
|
||||
base::SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
|
||||
FROM_HERE, window_unresponsive_closure_.callback(),
|
||||
base::Milliseconds(ms));
|
||||
}
|
||||
|
||||
void BrowserWindow::NotifyWindowUnresponsive() {
|
||||
window_unresponsive_closure_.Cancel();
|
||||
if (!window_->IsClosed() && window_->IsEnabled()) {
|
||||
Emit("unresponsive");
|
||||
}
|
||||
}
|
||||
|
||||
void BrowserWindow::OnWindowShow() {
|
||||
web_contents()->WasShown();
|
||||
BaseWindow::OnWindowShow();
|
||||
@@ -419,9 +309,6 @@ void BrowserWindow::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("focusOnWebView", &BrowserWindow::FocusOnWebView)
|
||||
.SetMethod("blurWebView", &BrowserWindow::BlurWebView)
|
||||
.SetMethod("isWebViewFocused", &BrowserWindow::IsWebViewFocused)
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
.SetMethod("setTitleBarOverlay", &BrowserWindow::SetTitleBarOverlay)
|
||||
#endif
|
||||
.SetProperty("webContents", &BrowserWindow::GetWebContents);
|
||||
}
|
||||
|
||||
|
||||
@@ -43,9 +43,6 @@ class BrowserWindow : public BaseWindow,
|
||||
|
||||
// content::WebContentsObserver:
|
||||
void BeforeUnloadDialogCancelled() override;
|
||||
void OnRendererUnresponsive(content::RenderProcessHost*) override;
|
||||
void OnRendererResponsive(
|
||||
content::RenderProcessHost* render_process_host) override;
|
||||
void WebContentsDestroyed() override;
|
||||
|
||||
// ExtendedWebContentsObserver:
|
||||
@@ -76,24 +73,10 @@ class BrowserWindow : public BaseWindow,
|
||||
void BlurWebView();
|
||||
bool IsWebViewFocused();
|
||||
v8::Local<v8::Value> GetWebContents(v8::Isolate* isolate);
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
void SetTitleBarOverlay(const gin_helper::Dictionary& options,
|
||||
gin_helper::Arguments* args);
|
||||
#endif
|
||||
|
||||
private:
|
||||
// Helpers.
|
||||
|
||||
// Schedule a notification unresponsive event.
|
||||
void ScheduleUnresponsiveEvent(int ms);
|
||||
|
||||
// Dispatch unresponsive event to observers.
|
||||
void NotifyWindowUnresponsive();
|
||||
|
||||
// Closure that would be called when window is unresponsive when closing,
|
||||
// it should be cancelled when we can prove that the window is responsive.
|
||||
base::CancelableRepeatingClosure window_unresponsive_closure_;
|
||||
|
||||
v8::Global<v8::Value> web_contents_;
|
||||
v8::Global<v8::Value> web_contents_view_;
|
||||
base::WeakPtr<api::WebContents> api_web_contents_;
|
||||
|
||||
@@ -1545,8 +1545,7 @@ gin::Handle<Session> Session::FromPartition(v8::Isolate* isolate,
|
||||
if (partition.empty()) {
|
||||
browser_context =
|
||||
ElectronBrowserContext::From("", false, std::move(options));
|
||||
} else if (base::StartsWith(partition, kPersistPrefix,
|
||||
base::CompareCase::SENSITIVE)) {
|
||||
} else if (partition.starts_with(kPersistPrefix)) {
|
||||
std::string name = partition.substr(8);
|
||||
browser_context =
|
||||
ElectronBrowserContext::From(name, false, std::move(options));
|
||||
|
||||
@@ -106,12 +106,9 @@ bool Browser::IsDefaultProtocolClient(const std::string& protocol,
|
||||
const std::vector<std::string> argv = {kXdgSettings, "check",
|
||||
kXdgSettingsDefaultSchemeHandler,
|
||||
protocol, desktop_name};
|
||||
const auto output = GetXdgAppOutput(argv);
|
||||
if (!output)
|
||||
return false;
|
||||
|
||||
// Allow any reply that starts with "yes".
|
||||
return base::StartsWith(output.value(), "yes", base::CompareCase::SENSITIVE);
|
||||
const std::optional<std::string> output = GetXdgAppOutput(argv);
|
||||
return output && output->starts_with("yes");
|
||||
}
|
||||
|
||||
// Todo implement
|
||||
|
||||
@@ -456,7 +456,15 @@ void ElectronBrowserClient::AppendExtraCommandLineSwitches(
|
||||
base::CommandLine* command_line,
|
||||
int process_id) {
|
||||
// Make sure we're about to launch a known executable
|
||||
#if BUILDFLAG(IS_LINUX)
|
||||
// On Linux, do not perform this check for /proc/self/exe. It will always
|
||||
// point to the currently running executable so this check is not
|
||||
// necessary, and if the executable has been deleted it will return a fake
|
||||
// name that causes this check to fail.
|
||||
if (command_line->GetProgram() != base::FilePath(base::kProcSelfExe)) {
|
||||
#else
|
||||
{
|
||||
#endif
|
||||
ScopedAllowBlockingForElectron allow_blocking;
|
||||
base::FilePath child_path;
|
||||
base::FilePath program =
|
||||
|
||||
@@ -242,6 +242,67 @@ std::string MakePartitionName(const std::string& input) {
|
||||
return {};
|
||||
}
|
||||
|
||||
bool DoesDeviceMatch(const base::Value& device,
|
||||
const base::Value& device_to_compare,
|
||||
const blink::PermissionType permission_type) {
|
||||
if (permission_type ==
|
||||
static_cast<blink::PermissionType>(
|
||||
WebContentsPermissionHelper::PermissionType::HID) ||
|
||||
permission_type ==
|
||||
static_cast<blink::PermissionType>(
|
||||
WebContentsPermissionHelper::PermissionType::USB)) {
|
||||
if (device.GetDict().FindInt(kDeviceVendorIdKey) !=
|
||||
device_to_compare.GetDict().FindInt(kDeviceVendorIdKey) ||
|
||||
device.GetDict().FindInt(kDeviceProductIdKey) !=
|
||||
device_to_compare.GetDict().FindInt(kDeviceProductIdKey)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto* serial_number =
|
||||
device_to_compare.GetDict().FindString(kDeviceSerialNumberKey);
|
||||
const auto* device_serial_number =
|
||||
device.GetDict().FindString(kDeviceSerialNumberKey);
|
||||
|
||||
if (serial_number && device_serial_number &&
|
||||
*device_serial_number == *serial_number)
|
||||
return true;
|
||||
} else if (permission_type ==
|
||||
static_cast<blink::PermissionType>(
|
||||
WebContentsPermissionHelper::PermissionType::SERIAL)) {
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
const auto* instance_id = device.GetDict().FindString(kDeviceInstanceIdKey);
|
||||
const auto* port_instance_id =
|
||||
device_to_compare.GetDict().FindString(kDeviceInstanceIdKey);
|
||||
if (instance_id && port_instance_id && *instance_id == *port_instance_id)
|
||||
return true;
|
||||
#else
|
||||
const auto* serial_number = device.GetDict().FindString(kSerialNumberKey);
|
||||
const auto* port_serial_number =
|
||||
device_to_compare.GetDict().FindString(kSerialNumberKey);
|
||||
if (device.GetDict().FindInt(kVendorIdKey) !=
|
||||
device_to_compare.GetDict().FindInt(kVendorIdKey) ||
|
||||
device.GetDict().FindInt(kProductIdKey) !=
|
||||
device_to_compare.GetDict().FindInt(kProductIdKey) ||
|
||||
(serial_number && port_serial_number &&
|
||||
*port_serial_number != *serial_number)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
const auto* usb_driver_key = device.GetDict().FindString(kUsbDriverKey);
|
||||
const auto* port_usb_driver_key =
|
||||
device_to_compare.GetDict().FindString(kUsbDriverKey);
|
||||
if (usb_driver_key && port_usb_driver_key &&
|
||||
*usb_driver_key != *port_usb_driver_key) {
|
||||
return false;
|
||||
}
|
||||
#endif // BUILDFLAG(IS_MAC)
|
||||
return true;
|
||||
#endif // BUILDFLAG(IS_WIN)
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// static
|
||||
@@ -723,7 +784,7 @@ void ElectronBrowserContext::GrantDevicePermission(
|
||||
void ElectronBrowserContext::RevokeDevicePermission(
|
||||
const url::Origin& origin,
|
||||
const base::Value& device,
|
||||
blink::PermissionType permission_type) {
|
||||
const blink::PermissionType permission_type) {
|
||||
const auto& current_devices_it = granted_devices_.find(permission_type);
|
||||
if (current_devices_it == granted_devices_.end())
|
||||
return;
|
||||
@@ -732,76 +793,10 @@ void ElectronBrowserContext::RevokeDevicePermission(
|
||||
if (origin_devices_it == current_devices_it->second.end())
|
||||
return;
|
||||
|
||||
for (auto it = origin_devices_it->second.begin();
|
||||
it != origin_devices_it->second.end();) {
|
||||
if (DoesDeviceMatch(device, it->get(), permission_type)) {
|
||||
it = origin_devices_it->second.erase(it);
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ElectronBrowserContext::DoesDeviceMatch(
|
||||
const base::Value& device,
|
||||
const base::Value* device_to_compare,
|
||||
blink::PermissionType permission_type) {
|
||||
if (permission_type ==
|
||||
static_cast<blink::PermissionType>(
|
||||
WebContentsPermissionHelper::PermissionType::HID) ||
|
||||
permission_type ==
|
||||
static_cast<blink::PermissionType>(
|
||||
WebContentsPermissionHelper::PermissionType::USB)) {
|
||||
if (device.GetDict().FindInt(kDeviceVendorIdKey) !=
|
||||
device_to_compare->GetDict().FindInt(kDeviceVendorIdKey) ||
|
||||
device.GetDict().FindInt(kDeviceProductIdKey) !=
|
||||
device_to_compare->GetDict().FindInt(kDeviceProductIdKey)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto* serial_number =
|
||||
device_to_compare->GetDict().FindString(kDeviceSerialNumberKey);
|
||||
const auto* device_serial_number =
|
||||
device.GetDict().FindString(kDeviceSerialNumberKey);
|
||||
|
||||
if (serial_number && device_serial_number &&
|
||||
*device_serial_number == *serial_number)
|
||||
return true;
|
||||
} else if (permission_type ==
|
||||
static_cast<blink::PermissionType>(
|
||||
WebContentsPermissionHelper::PermissionType::SERIAL)) {
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
const auto* instance_id = device.GetDict().FindString(kDeviceInstanceIdKey);
|
||||
const auto* port_instance_id =
|
||||
device_to_compare->GetDict().FindString(kDeviceInstanceIdKey);
|
||||
if (instance_id && port_instance_id && *instance_id == *port_instance_id)
|
||||
return true;
|
||||
#else
|
||||
const auto* serial_number = device.GetDict().FindString(kSerialNumberKey);
|
||||
const auto* port_serial_number =
|
||||
device_to_compare->GetDict().FindString(kSerialNumberKey);
|
||||
if (device.GetDict().FindInt(kVendorIdKey) !=
|
||||
device_to_compare->GetDict().FindInt(kVendorIdKey) ||
|
||||
device.GetDict().FindInt(kProductIdKey) !=
|
||||
device_to_compare->GetDict().FindInt(kProductIdKey) ||
|
||||
(serial_number && port_serial_number &&
|
||||
*port_serial_number != *serial_number)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
const auto* usb_driver_key = device.GetDict().FindString(kUsbDriverKey);
|
||||
const auto* port_usb_driver_key =
|
||||
device_to_compare->GetDict().FindString(kUsbDriverKey);
|
||||
if (usb_driver_key && port_usb_driver_key &&
|
||||
*usb_driver_key != *port_usb_driver_key) {
|
||||
return false;
|
||||
}
|
||||
#endif // BUILDFLAG(IS_MAC)
|
||||
return true;
|
||||
#endif // BUILDFLAG(IS_WIN)
|
||||
}
|
||||
return false;
|
||||
std::erase_if(origin_devices_it->second,
|
||||
[&device, &permission_type](auto const& val) {
|
||||
return DoesDeviceMatch(device, *val, permission_type);
|
||||
});
|
||||
}
|
||||
|
||||
bool ElectronBrowserContext::CheckDevicePermission(
|
||||
@@ -817,7 +812,7 @@ bool ElectronBrowserContext::CheckDevicePermission(
|
||||
return false;
|
||||
|
||||
for (const auto& device_to_compare : origin_devices_it->second) {
|
||||
if (DoesDeviceMatch(device, device_to_compare.get(), permission_type))
|
||||
if (DoesDeviceMatch(device, *device_to_compare, permission_type))
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -221,10 +221,6 @@ class ElectronBrowserContext : public content::BrowserContext {
|
||||
// Initialize pref registry.
|
||||
void InitPrefs();
|
||||
|
||||
bool DoesDeviceMatch(const base::Value& device,
|
||||
const base::Value* device_to_compare,
|
||||
blink::PermissionType permission_type);
|
||||
|
||||
scoped_refptr<ValueMapPrefStore> in_memory_pref_store_;
|
||||
std::unique_ptr<CookieChangeNotifier> cookie_change_notifier_;
|
||||
std::unique_ptr<PrefService> prefs_;
|
||||
|
||||
@@ -51,21 +51,10 @@ unity_launcher_entry_set_progress_visible_func entry_set_progress_visible =
|
||||
nullptr;
|
||||
|
||||
void EnsureLibUnityLoaded() {
|
||||
using base::nix::GetDesktopEnvironment;
|
||||
|
||||
if (attempted_load)
|
||||
return;
|
||||
attempted_load = true;
|
||||
|
||||
auto env = base::Environment::Create();
|
||||
base::nix::DesktopEnvironment desktop_env = GetDesktopEnvironment(env.get());
|
||||
|
||||
// The "icon-tasks" KDE task manager also honors Unity Launcher API.
|
||||
if (desktop_env != base::nix::DESKTOP_ENVIRONMENT_UNITY &&
|
||||
desktop_env != base::nix::DESKTOP_ENVIRONMENT_KDE4 &&
|
||||
desktop_env != base::nix::DESKTOP_ENVIRONMENT_KDE5)
|
||||
return;
|
||||
|
||||
// Ubuntu still hasn't given us a nice libunity.so symlink.
|
||||
void* unity_lib = dlopen("libunity.so.4", RTLD_LAZY);
|
||||
if (!unity_lib)
|
||||
|
||||
@@ -122,11 +122,9 @@ void UsbChooserController::GotUsbDeviceList(
|
||||
v8::HandleScope scope(isolate);
|
||||
|
||||
// "select-usb-device" should respect |filters|.
|
||||
devices.erase(std::remove_if(devices.begin(), devices.end(),
|
||||
[this](const auto& device_info) {
|
||||
return !DisplayDevice(*device_info);
|
||||
}),
|
||||
devices.end());
|
||||
std::erase_if(devices, [this](const auto& device_info) {
|
||||
return !DisplayDevice(*device_info);
|
||||
});
|
||||
|
||||
v8::Local<v8::Object> details = gin::DataObjectBuilder(isolate)
|
||||
.Set("deviceList", devices)
|
||||
|
||||
@@ -107,8 +107,7 @@ WebContentsPreferences::WebContentsPreferences(
|
||||
}
|
||||
|
||||
WebContentsPreferences::~WebContentsPreferences() {
|
||||
Instances().erase(std::remove(Instances().begin(), Instances().end(), this),
|
||||
Instances().end());
|
||||
std::erase(Instances(), this);
|
||||
}
|
||||
|
||||
void WebContentsPreferences::Clear() {
|
||||
|
||||
@@ -59,8 +59,7 @@ void WindowList::AddWindow(NativeWindow* window) {
|
||||
// static
|
||||
void WindowList::RemoveWindow(NativeWindow* window) {
|
||||
WindowVector& windows = GetInstance()->windows_;
|
||||
windows.erase(std::remove(windows.begin(), windows.end(), window),
|
||||
windows.end());
|
||||
std::erase(windows, window);
|
||||
|
||||
for (WindowListObserver& observer : GetObservers())
|
||||
observer.OnWindowRemoved(window);
|
||||
|
||||
@@ -83,10 +83,7 @@ void ElectronBindings::BindTo(v8::Isolate* isolate,
|
||||
}
|
||||
|
||||
void ElectronBindings::EnvironmentDestroyed(node::Environment* env) {
|
||||
auto it =
|
||||
std::find(pending_next_ticks_.begin(), pending_next_ticks_.end(), env);
|
||||
if (it != pending_next_ticks_.end())
|
||||
pending_next_ticks_.erase(it);
|
||||
std::erase(pending_next_ticks_, env);
|
||||
}
|
||||
|
||||
void ElectronBindings::ActivateUVLoop(v8::Isolate* isolate) {
|
||||
|
||||
@@ -19,8 +19,7 @@ CleanedUpAtExit::CleanedUpAtExit() {
|
||||
GetDoomed().emplace_back(this);
|
||||
}
|
||||
CleanedUpAtExit::~CleanedUpAtExit() {
|
||||
auto& doomed = GetDoomed();
|
||||
doomed.erase(std::remove(doomed.begin(), doomed.end(), this), doomed.end());
|
||||
std::erase(GetDoomed(), this);
|
||||
}
|
||||
|
||||
// static
|
||||
|
||||
@@ -31,13 +31,10 @@ base::FilePath MainApplicationBundlePath() {
|
||||
|
||||
// Up to Contents.
|
||||
if (!HasMainProcessKey() &&
|
||||
(base::EndsWith(path.value(), " Helper", base::CompareCase::SENSITIVE) ||
|
||||
base::EndsWith(path.value(), content::kMacHelperSuffix_plugin,
|
||||
base::CompareCase::SENSITIVE) ||
|
||||
base::EndsWith(path.value(), content::kMacHelperSuffix_renderer,
|
||||
base::CompareCase::SENSITIVE) ||
|
||||
base::EndsWith(path.value(), content::kMacHelperSuffix_gpu,
|
||||
base::CompareCase::SENSITIVE))) {
|
||||
(path.value().ends_with(" Helper") ||
|
||||
path.value().ends_with(content::kMacHelperSuffix_plugin) ||
|
||||
path.value().ends_with(content::kMacHelperSuffix_renderer) ||
|
||||
path.value().ends_with(content::kMacHelperSuffix_gpu))) {
|
||||
// The running executable is the helper. Go up five steps:
|
||||
// Contents/Frameworks/Helper.app/Contents/MacOS/Helper
|
||||
// ^ to here ^ from here
|
||||
|
||||
@@ -211,4 +211,51 @@ describe('release notes', () => {
|
||||
expect(results.breaking[0].hash).to.equal(testCommit.sha1);
|
||||
});
|
||||
});
|
||||
// test that when you have multiple stack updates only the
|
||||
// latest will be kept
|
||||
describe('superseding stack updates', () => {
|
||||
const oldBranch = '27-x-y';
|
||||
const newBranch = '28-x-y';
|
||||
|
||||
const version = 'v28.0.0';
|
||||
|
||||
it('with different major versions', async function () {
|
||||
const mostRecentCommit = new Commit('9d0e6d09f0be0abbeae46dd3d66afd96d2daacaa', 'chore: bump chromium to 119.0.6043.0');
|
||||
|
||||
const sharedChromiumHistory = [
|
||||
new Commit('029127a8b6f7c511fca4612748ad5b50e43aadaa', 'chore: bump chromium to 118.0.5993.0') // merge-base
|
||||
];
|
||||
const chromiumPatchUpdates = [
|
||||
new Commit('d9ba26273ad3e7a34c905eccbd5dabda4eb7b402', 'chore: bump chromium to 118.0.5991.0'),
|
||||
mostRecentCommit,
|
||||
new Commit('d6c8ff2e7050f30dffd784915bcbd2a9f993cdb2', 'chore: bump chromium to 119.0.6029.0')
|
||||
];
|
||||
|
||||
gitFake.setBranch(oldBranch, sharedChromiumHistory);
|
||||
gitFake.setBranch(newBranch, [...sharedChromiumHistory, ...chromiumPatchUpdates]);
|
||||
|
||||
const results: any = await notes.get(oldBranch, newBranch, version);
|
||||
expect(results.other).to.have.lengthOf(1);
|
||||
expect(results.other[0].hash).to.equal(mostRecentCommit.sha1);
|
||||
});
|
||||
it('with different build versions', async function () {
|
||||
const mostRecentCommit = new Commit('8f7a48879ef8633a76279803637cdee7f7c6cd4f', 'chore: bump chromium to 119.0.6045.0');
|
||||
|
||||
const sharedChromiumHistory = [
|
||||
new Commit('029127a8b6f7c511fca4612748ad5b50e43aadaa', 'chore: bump chromium to 118.0.5993.0') // merge-base
|
||||
];
|
||||
const chromiumPatchUpdates = [
|
||||
mostRecentCommit,
|
||||
new Commit('9d0e6d09f0be0abbeae46dd3d66afd96d2daacaa', 'chore: bump chromium to 119.0.6043.0'),
|
||||
new Commit('d6c8ff2e7050f30dffd784915bcbd2a9f993cdb2', 'chore: bump chromium to 119.0.6029.0')
|
||||
];
|
||||
|
||||
gitFake.setBranch(oldBranch, sharedChromiumHistory);
|
||||
gitFake.setBranch(newBranch, [...sharedChromiumHistory, ...chromiumPatchUpdates]);
|
||||
|
||||
const results: any = await notes.get(oldBranch, newBranch, version);
|
||||
expect(results.other).to.have.lengthOf(1);
|
||||
expect(results.other[0].hash).to.equal(mostRecentCommit.sha1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -220,9 +220,9 @@
|
||||
vscode-uri "^3.0.7"
|
||||
|
||||
"@electron/typescript-definitions@^8.15.2":
|
||||
version "8.15.2"
|
||||
resolved "https://registry.yarnpkg.com/@electron/typescript-definitions/-/typescript-definitions-8.15.2.tgz#1152e3d3731d236b50a3dee5a108176ce43fd703"
|
||||
integrity sha512-6vlWnnNfZrg9QFOGgoLaQZ/nTCg+Y1laz02pUsRRmCJIpJZOY3HnWnIuav7e8g5IIwHMVc8JSohR+YRgiRk/eA==
|
||||
version "8.15.6"
|
||||
resolved "https://registry.yarnpkg.com/@electron/typescript-definitions/-/typescript-definitions-8.15.6.tgz#a578ee3de6e6dcfdb5765da58f303900a34b2d06"
|
||||
integrity sha512-9YR2jG7AdRLvZMhQLgTljZzkoaKNP1wbQq+/qjBCCCCCbUpECvMRk1/UeuZErZEmddhSYanQZgXiftF1T072uQ==
|
||||
dependencies:
|
||||
"@types/node" "^11.13.7"
|
||||
chalk "^2.4.2"
|
||||
|
||||
Reference in New Issue
Block a user