mirror of
https://github.com/electron/electron.git
synced 2026-02-19 03:14:51 -05:00
Compare commits
48 Commits
re-enable-
...
v9.0.0-bet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7fd2d39f72 | ||
|
|
64880c75a3 | ||
|
|
cc94689db1 | ||
|
|
806e483049 | ||
|
|
8129e92d2b | ||
|
|
660706ba2c | ||
|
|
2feca9d35a | ||
|
|
3a4118703a | ||
|
|
bd669f72ee | ||
|
|
1f3c3eee83 | ||
|
|
6e84ebee8e | ||
|
|
f22376ef32 | ||
|
|
324b49a5eb | ||
|
|
0e9727e8d5 | ||
|
|
44ee90e5cf | ||
|
|
2b9ef75d82 | ||
|
|
4dc2b4d55f | ||
|
|
69f77d309d | ||
|
|
9cd1744a2b | ||
|
|
c6e411173e | ||
|
|
8b11adc6f2 | ||
|
|
57ec30e459 | ||
|
|
c4a836f95a | ||
|
|
9b2de2583e | ||
|
|
7b2bfb4a0f | ||
|
|
0e31826043 | ||
|
|
7b3c073b3e | ||
|
|
2dc900b95d | ||
|
|
f41423501a | ||
|
|
07d9728b63 | ||
|
|
d4c90e80a5 | ||
|
|
91141028e6 | ||
|
|
9d69d4b9ef | ||
|
|
d57d5c544e | ||
|
|
74d4dab157 | ||
|
|
94246dabe3 | ||
|
|
4fe91e56ac | ||
|
|
0d7440d676 | ||
|
|
60edd2d3b1 | ||
|
|
d4d06660f3 | ||
|
|
8d8f15121b | ||
|
|
1f8cb5144d | ||
|
|
667ee359a1 | ||
|
|
4b009159ba | ||
|
|
89f66bd00c | ||
|
|
2d542c6028 | ||
|
|
68346fec55 | ||
|
|
23f32ca9f3 |
@@ -41,6 +41,14 @@ parameters:
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
run-linux-publish:
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
run-macos-publish:
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
# The config expects the following environment variables to be set:
|
||||
# - "SLACK_WEBHOOK" Slack hook URL to send notifications.
|
||||
#
|
||||
@@ -65,12 +73,12 @@ machine-linux-2xlarge: &machine-linux-2xlarge
|
||||
|
||||
machine-mac: &machine-mac
|
||||
macos:
|
||||
xcode: "10.3.0"
|
||||
xcode: "11.1.0"
|
||||
|
||||
machine-mac-large: &machine-mac-large
|
||||
resource_class: large
|
||||
macos:
|
||||
xcode: "10.3.0"
|
||||
xcode: "11.1.0"
|
||||
|
||||
# Build configurations options.
|
||||
env-testing-build: &env-testing-build
|
||||
@@ -228,15 +236,6 @@ step-setup-env-for-build: &step-setup-env-for-build
|
||||
command: |
|
||||
# To find `gn` executable.
|
||||
echo 'export CHROMIUM_BUILDTOOLS_PATH="'"$PWD"'/src/buildtools"' >> $BASH_ENV
|
||||
# Setup Goma if applicable
|
||||
if [ ! -z "$RAW_GOMA_AUTH" ] && [ "`uname`" == "Linux" ]; then
|
||||
export USE_SCCACHE="false"
|
||||
echo 'export USE_SCCACHE=false' >> $BASH_ENV
|
||||
echo 'export USE_GOMA=true' >> $BASH_ENV
|
||||
echo 'export NUMBER_OF_NINJA_PROCESSES=300' >> $BASH_ENV
|
||||
echo $RAW_GOMA_AUTH > ~/.goma_oauth2_config
|
||||
src/electron/external_binaries/goma/goma_ctl.py ensure_start
|
||||
fi
|
||||
|
||||
if [ "$USE_SCCACHE" == "true" ]; then
|
||||
# https://github.com/mozilla/sccache
|
||||
@@ -249,6 +248,29 @@ step-setup-env-for-build: &step-setup-env-for-build
|
||||
fi
|
||||
fi
|
||||
|
||||
step-setup-goma-for-build: &step-setup-goma-for-build
|
||||
run:
|
||||
name: Setup Goma
|
||||
command: |
|
||||
echo 'export USE_GOMA=true' >> $BASH_ENV
|
||||
if [ "`uname`" == "Linux" ]; then
|
||||
echo 'export NUMBER_OF_NINJA_PROCESSES=300' >> $BASH_ENV
|
||||
else
|
||||
echo 'export NUMBER_OF_NINJA_PROCESSES=25' >> $BASH_ENV
|
||||
fi
|
||||
if [ ! -z "$RAW_GOMA_AUTH" ]; then
|
||||
echo $RAW_GOMA_AUTH > ~/.goma_oauth2_config
|
||||
fi
|
||||
git clone https://github.com/electron/build-tools.git
|
||||
cd build-tools
|
||||
npm install
|
||||
mkdir third_party
|
||||
node -e "require('./src/utils/goma.js').downloadAndPrepare()"
|
||||
node -e "require('./src/utils/goma.js').ensure()"
|
||||
echo 'export GN_GOMA_FILE='`node -e "console.log(require('./src/utils/goma.js').gnFilePath)"` >> $BASH_ENV
|
||||
echo 'export LOCAL_GOMA_DIR='`node -e "console.log(require('./src/utils/goma.js').dir)"` >> $BASH_ENV
|
||||
cd ..
|
||||
|
||||
step-restore-brew-cache: &step-restore-brew-cache
|
||||
restore_cache:
|
||||
paths:
|
||||
@@ -339,7 +361,7 @@ step-gn-gen-default: &step-gn-gen-default
|
||||
command: |
|
||||
cd src
|
||||
if [ "$USE_GOMA" == "true" ]; then
|
||||
gn gen out/Default --args="import(\"$GN_CONFIG\") import(\"//electron/build/args/goma.gn\") $GN_EXTRA_ARGS $GN_BUILDFLAG_ARGS"
|
||||
gn gen out/Default --args="import(\"$GN_CONFIG\") import(\"$GN_GOMA_FILE\") $GN_EXTRA_ARGS $GN_BUILDFLAG_ARGS"
|
||||
else
|
||||
gn gen out/Default --args="import(\"$GN_CONFIG\") cc_wrapper=\"$SCCACHE_PATH\" $GN_EXTRA_ARGS $GN_BUILDFLAG_ARGS"
|
||||
fi
|
||||
@@ -432,15 +454,17 @@ step-electron-dist-store: &step-electron-dist-store
|
||||
path: src/out/Default/dist.zip
|
||||
destination: dist.zip
|
||||
|
||||
step-electron-chromedriver-gn-gen: &step-electron-chromedriver-gn-gen
|
||||
step-electron-maybe-chromedriver-gn-gen: &step-electron-maybe-chromedriver-gn-gen
|
||||
run:
|
||||
name: chromedriver GN gen
|
||||
command: |
|
||||
cd src
|
||||
if [ "$USE_GOMA" == "true" ]; then
|
||||
gn gen out/chromedriver --args="import(\"$GN_CONFIG\") import(\"//electron/build/args/goma.gn\") is_component_ffmpeg=false proprietary_codecs=false $GN_EXTRA_ARGS $GN_BUILDFLAG_ARGS"
|
||||
else
|
||||
gn gen out/chromedriver --args="import(\"$GN_CONFIG\") cc_wrapper=\"$SCCACHE_PATH\" is_component_ffmpeg=false proprietary_codecs=false $GN_EXTRA_ARGS $GN_BUILDFLAG_ARGS"
|
||||
if [ "$TARGET_ARCH" == "arm" ] || [ "$TARGET_ARCH" == "arm64" ]; then
|
||||
if [ "$USE_GOMA" == "true" ]; then
|
||||
gn gen out/chromedriver --args="import(\"$GN_CONFIG\") import(\"//electron/build/args/goma.gn\") is_component_ffmpeg=false proprietary_codecs=false $GN_EXTRA_ARGS $GN_BUILDFLAG_ARGS"
|
||||
else
|
||||
gn gen out/chromedriver --args="import(\"$GN_CONFIG\") cc_wrapper=\"$SCCACHE_PATH\" is_component_ffmpeg=false proprietary_codecs=false $GN_EXTRA_ARGS $GN_BUILDFLAG_ARGS"
|
||||
fi
|
||||
fi
|
||||
|
||||
step-electron-chromedriver-build: &step-electron-chromedriver-build
|
||||
@@ -448,13 +472,23 @@ step-electron-chromedriver-build: &step-electron-chromedriver-build
|
||||
name: Build chromedriver.zip
|
||||
command: |
|
||||
cd src
|
||||
ninja -C out/chromedriver electron:electron_chromedriver -j $NUMBER_OF_NINJA_PROCESSES
|
||||
electron/script/strip-binaries.py --target-cpu="$TARGET_ARCH" --file $PWD/out/chromedriver/chromedriver
|
||||
ninja -C out/chromedriver electron:electron_chromedriver_zip
|
||||
if [ "$TARGET_ARCH" == "arm" ] || [ "$TARGET_ARCH" == "arm64" ]; then
|
||||
export CHROMEDRIVER_DIR="out/chromedriver"
|
||||
else
|
||||
export CHROMEDRIVER_DIR="out/Default"
|
||||
fi
|
||||
ninja -C $CHROMEDRIVER_DIR electron:electron_chromedriver -j $NUMBER_OF_NINJA_PROCESSES
|
||||
if [ "`uname`" == "Linux" ]; then
|
||||
electron/script/strip-binaries.py --target-cpu="$TARGET_ARCH" --file $PWD/$CHROMEDRIVER_DIR/chromedriver
|
||||
fi
|
||||
ninja -C $CHROMEDRIVER_DIR electron:electron_chromedriver_zip
|
||||
if [ "$TARGET_ARCH" == "arm" ] || [ "$TARGET_ARCH" == "arm64" ]; then
|
||||
cp out/chromedriver/chromedriver.zip out/Default
|
||||
fi
|
||||
|
||||
step-electron-chromedriver-store: &step-electron-chromedriver-store
|
||||
store_artifacts:
|
||||
path: src/out/chromedriver/chromedriver.zip
|
||||
path: src/out/Default/chromedriver.zip
|
||||
destination: chromedriver.zip
|
||||
|
||||
step-nodejs-headers-build: &step-nodejs-headers-build
|
||||
@@ -481,6 +515,7 @@ step-electron-publish: &step-electron-publish
|
||||
if [ "`uname`" == "Darwin" ]; then
|
||||
rm -rf src/out/Default/obj
|
||||
fi
|
||||
|
||||
cd src/electron
|
||||
if [ "$UPLOAD_TO_S3" == "1" ]; then
|
||||
echo 'Uploading Electron release distribution to S3'
|
||||
@@ -497,7 +532,7 @@ step-persist-data-for-tests: &step-persist-data-for-tests
|
||||
# Build artifacts
|
||||
- src/out/Default/dist.zip
|
||||
- src/out/Default/mksnapshot.zip
|
||||
- src/out/chromedriver/chromedriver.zip
|
||||
- src/out/Default/chromedriver.zip
|
||||
- src/out/Default/shell_browser_ui_unittests
|
||||
- src/out/Default/gen/node_headers
|
||||
- src/out/ffmpeg/ffmpeg.zip
|
||||
@@ -532,7 +567,7 @@ step-chromedriver-unzip: &step-chromedriver-unzip
|
||||
run:
|
||||
name: Unzip chromedriver.zip
|
||||
command: |
|
||||
cd src/out/chromedriver
|
||||
cd src/out/Default
|
||||
unzip -o chromedriver.zip
|
||||
|
||||
step-ffmpeg-gn-gen: &step-ffmpeg-gn-gen
|
||||
@@ -577,7 +612,7 @@ step-verify-chromedriver: &step-verify-chromedriver
|
||||
name: Verify ChromeDriver
|
||||
command: |
|
||||
cd src
|
||||
python electron/script/verify-chromedriver.py --source-root "$PWD" --build-dir out/chromedriver
|
||||
python electron/script/verify-chromedriver.py --source-root "$PWD" --build-dir out/Default
|
||||
|
||||
step-setup-linux-for-headless-testing: &step-setup-linux-for-headless-testing
|
||||
run:
|
||||
@@ -595,7 +630,7 @@ step-show-sccache-stats: &step-show-sccache-stats
|
||||
$SCCACHE_PATH -s
|
||||
fi
|
||||
if [ "$USE_GOMA" == "true" ]; then
|
||||
src/electron/external_binaries/goma/goma_ctl.py stat
|
||||
$LOCAL_GOMA_DIR/goma_ctl.py stat
|
||||
fi
|
||||
|
||||
step-mksnapshot-build: &step-mksnapshot-build
|
||||
@@ -833,7 +868,7 @@ step-check-for-doc-only-change: &step-check-for-doc-only-change
|
||||
command: |
|
||||
cd src/electron
|
||||
node script/yarn install --frozen-lockfile
|
||||
if node script/doc-only-change.js --prNumber=$CIRCLE_PR_NUMBER --prURL=$CIRCLE_PULL_REQUEST; then
|
||||
if node script/doc-only-change.js --prNumber=$CIRCLE_PR_NUMBER --prURL=$CIRCLE_PULL_REQUEST --prBranch=$CIRCLE_BRANCH; then
|
||||
#PR is doc only change; save file with value true to indicate doc only change
|
||||
echo "true" > .skip-ci-build
|
||||
else
|
||||
@@ -869,7 +904,7 @@ step-ts-compile: &step-ts-compile
|
||||
command: |
|
||||
cd src
|
||||
ninja -C out/Default electron:default_app_js -j $NUMBER_OF_NINJA_PROCESSES
|
||||
ninja -C out/Default electron:atom_js2c -j $NUMBER_OF_NINJA_PROCESSES
|
||||
ninja -C out/Default electron:electron_js2c -j $NUMBER_OF_NINJA_PROCESSES
|
||||
|
||||
# Lists of steps.
|
||||
steps-lint: &steps-lint
|
||||
@@ -965,69 +1000,6 @@ steps-electron-gn-check: &steps-electron-gn-check
|
||||
- *step-gn-gen-default
|
||||
- *step-gn-check
|
||||
|
||||
steps-electron-build: &steps-electron-build
|
||||
steps:
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- *step-maybe-early-exit-doc-only-change
|
||||
- *step-depot-tools-add-to-path
|
||||
- *step-setup-env-for-build
|
||||
- *step-restore-brew-cache
|
||||
- *step-get-more-space-on-mac
|
||||
- *step-install-npm-deps-on-mac
|
||||
- *step-fix-sync-on-mac
|
||||
- *step-delete-git-directories
|
||||
- *step-gn-gen-default
|
||||
|
||||
# Electron app
|
||||
- *step-electron-build
|
||||
- *step-maybe-electron-dist-strip
|
||||
- *step-electron-dist-build
|
||||
- *step-electron-dist-store
|
||||
- *step-ninja-summary
|
||||
|
||||
# Native test targets
|
||||
- *step-native-unittests-build
|
||||
- *step-native-unittests-store
|
||||
|
||||
# Node.js headers
|
||||
- *step-nodejs-headers-build
|
||||
- *step-nodejs-headers-store
|
||||
|
||||
- *step-show-sccache-stats
|
||||
|
||||
# mksnapshot
|
||||
- *step-mksnapshot-build
|
||||
- *step-mksnapshot-store
|
||||
- *step-maybe-cross-arch-snapshot
|
||||
- *step-maybe-cross-arch-snapshot-store
|
||||
|
||||
# chromedriver
|
||||
- *step-electron-chromedriver-gn-gen
|
||||
- *step-electron-chromedriver-build
|
||||
- *step-electron-chromedriver-store
|
||||
|
||||
# ffmpeg
|
||||
- *step-ffmpeg-gn-gen
|
||||
- *step-ffmpeg-build
|
||||
- *step-ffmpeg-store
|
||||
|
||||
# hunspell
|
||||
- *step-hunspell-build
|
||||
- *step-hunspell-store
|
||||
|
||||
# Save all data needed for a further tests run.
|
||||
- *step-persist-data-for-tests
|
||||
|
||||
- *step-maybe-generate-breakpad-symbols
|
||||
- *step-maybe-zip-symbols
|
||||
- *step-symbols-store
|
||||
|
||||
# Trigger tests on arm hardware if needed
|
||||
- *step-maybe-trigger-arm-test
|
||||
|
||||
- *step-maybe-notify-slack-failure
|
||||
|
||||
steps-electron-ts-compile-for-doc-change: &steps-electron-ts-compile-for-doc-change
|
||||
steps:
|
||||
# Checkout - Copied ffrom steps-checkout
|
||||
@@ -1067,56 +1039,6 @@ steps-electron-ts-compile-for-doc-change: &steps-electron-ts-compile-for-doc-cha
|
||||
#Compile ts/js to verify doc change didn't break anything
|
||||
- *step-ts-compile
|
||||
|
||||
steps-electron-build-for-publish: &steps-electron-build-for-publish
|
||||
steps:
|
||||
- *step-checkout-electron
|
||||
- *step-depot-tools-get
|
||||
- *step-depot-tools-add-to-path
|
||||
- *step-restore-brew-cache
|
||||
- *step-get-more-space-on-mac
|
||||
- *step-gclient-sync
|
||||
- *step-setup-env-for-build
|
||||
- *step-delete-git-directories
|
||||
- *step-minimize-workspace-size-from-checkout
|
||||
- *step-gn-gen-default
|
||||
|
||||
# Electron app
|
||||
- *step-electron-build
|
||||
- *step-maybe-generate-breakpad-symbols
|
||||
- *step-maybe-electron-dist-strip
|
||||
- *step-electron-dist-build
|
||||
- *step-electron-dist-store
|
||||
- *step-maybe-zip-symbols
|
||||
- *step-symbols-store
|
||||
|
||||
# mksnapshot
|
||||
- *step-mksnapshot-build
|
||||
- *step-mksnapshot-store
|
||||
|
||||
# chromedriver
|
||||
- *step-electron-chromedriver-gn-gen
|
||||
- *step-electron-chromedriver-build
|
||||
- *step-electron-chromedriver-store
|
||||
|
||||
# Node.js headers
|
||||
- *step-nodejs-headers-build
|
||||
- *step-nodejs-headers-store
|
||||
|
||||
# ffmpeg
|
||||
- *step-ffmpeg-gn-gen
|
||||
- *step-ffmpeg-build
|
||||
- *step-ffmpeg-store
|
||||
|
||||
# hunspell
|
||||
- *step-hunspell-build
|
||||
- *step-hunspell-store
|
||||
|
||||
# typescript defs
|
||||
- *step-maybe-generate-typescript-defs
|
||||
|
||||
# Publish
|
||||
- *step-electron-publish
|
||||
|
||||
steps-chromedriver-build: &steps-chromedriver-build
|
||||
steps:
|
||||
- attach_workspace:
|
||||
@@ -1125,7 +1047,7 @@ steps-chromedriver-build: &steps-chromedriver-build
|
||||
- *step-setup-env-for-build
|
||||
- *step-fix-sync-on-mac
|
||||
|
||||
- *step-electron-chromedriver-gn-gen
|
||||
- *step-electron-maybe-chromedriver-gn-gen
|
||||
- *step-electron-chromedriver-build
|
||||
- *step-electron-chromedriver-store
|
||||
|
||||
@@ -1272,7 +1194,7 @@ steps-test-node: &steps-test-node
|
||||
name: Run Node Tests
|
||||
command: |
|
||||
cd src
|
||||
node electron/script/node-spec-runner.js junit
|
||||
node electron/script/node-spec-runner.js --default --jUnitDir=junit
|
||||
- store_test_results:
|
||||
path: src/junit
|
||||
|
||||
@@ -1341,6 +1263,12 @@ commands:
|
||||
use-out-cache:
|
||||
type: boolean
|
||||
default: true
|
||||
restore-src-cache:
|
||||
type: boolean
|
||||
default: true
|
||||
preserve-vendor-dirs:
|
||||
type: boolean
|
||||
default: false
|
||||
steps:
|
||||
- when:
|
||||
condition: << parameters.attach >>
|
||||
@@ -1366,17 +1294,38 @@ commands:
|
||||
- *step-get-more-space-on-mac
|
||||
- *step-generate-deps-hash
|
||||
- *step-touch-sync-done
|
||||
- maybe-restore-portaled-src-cache
|
||||
- when:
|
||||
condition: << parameters.restore-src-cache >>
|
||||
steps:
|
||||
- maybe-restore-portaled-src-cache
|
||||
- *step-maybe-restore-git-cache
|
||||
- *step-set-git-cache-path
|
||||
# This sync call only runs if .circle-sync-done is an EMPTY file
|
||||
- *step-gclient-sync
|
||||
# These next few steps reset Electron to the correct commit regardless of which cache was restored
|
||||
- when:
|
||||
condition: << parameters.preserve-vendor-dirs >>
|
||||
steps:
|
||||
- run:
|
||||
name: Preserve vendor dirs for release
|
||||
command: |
|
||||
mv src/electron/vendor/boto .
|
||||
mv src/electron/vendor/requests .
|
||||
- run:
|
||||
name: Wipe Electron
|
||||
command: rm -rf src/electron
|
||||
- *step-checkout-electron
|
||||
- *step-run-electron-only-hooks
|
||||
- when:
|
||||
condition: << parameters.preserve-vendor-dirs >>
|
||||
steps:
|
||||
- run:
|
||||
name: Preserve vendor dirs for release
|
||||
command: |
|
||||
rm -rf src/electron/vendor/boto
|
||||
rm -rf src/electron/vendor/requests
|
||||
mv boto src/electron/vendor
|
||||
mv requests src/electron/vendor/requests
|
||||
- *step-generate-deps-hash-cleanly
|
||||
- *step-mark-sync-done
|
||||
- *step-minimize-workspace-size-from-checkout
|
||||
@@ -1394,10 +1343,10 @@ commands:
|
||||
steps:
|
||||
- *step-depot-tools-add-to-path
|
||||
- *step-setup-env-for-build
|
||||
- *step-setup-goma-for-build
|
||||
- *step-get-more-space-on-mac
|
||||
- *step-fix-sync-on-mac
|
||||
- *step-delete-git-directories
|
||||
- *step-gn-gen-default
|
||||
|
||||
# Electron app
|
||||
- when:
|
||||
@@ -1429,7 +1378,7 @@ commands:
|
||||
- *step-maybe-cross-arch-snapshot-store
|
||||
|
||||
# chromedriver
|
||||
- *step-electron-chromedriver-gn-gen
|
||||
- *step-electron-maybe-chromedriver-gn-gen
|
||||
- *step-electron-chromedriver-build
|
||||
- *step-electron-chromedriver-store
|
||||
|
||||
@@ -1475,10 +1424,80 @@ commands:
|
||||
steps:
|
||||
- *step-save-out-cache
|
||||
|
||||
# Trigger tests on arm hardware if needed
|
||||
- *step-maybe-trigger-arm-test
|
||||
# Trigger tests on arm hardware if needed
|
||||
- *step-maybe-trigger-arm-test
|
||||
|
||||
- *step-maybe-notify-slack-failure
|
||||
- *step-maybe-notify-slack-failure
|
||||
|
||||
electron-publish:
|
||||
parameters:
|
||||
attach:
|
||||
type: boolean
|
||||
default: false
|
||||
checkout:
|
||||
type: boolean
|
||||
default: true
|
||||
steps:
|
||||
- when:
|
||||
condition: << parameters.attach >>
|
||||
steps:
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- when:
|
||||
condition: << parameters.checkout >>
|
||||
steps:
|
||||
- *step-depot-tools-get
|
||||
- *step-depot-tools-add-to-path
|
||||
- *step-restore-brew-cache
|
||||
- *step-get-more-space-on-mac
|
||||
- when:
|
||||
condition: << parameters.checkout >>
|
||||
steps:
|
||||
- *step-checkout-electron
|
||||
- *step-gclient-sync
|
||||
- *step-delete-git-directories
|
||||
- *step-minimize-workspace-size-from-checkout
|
||||
- *step-fix-sync-on-mac
|
||||
- *step-setup-env-for-build
|
||||
- *step-gn-gen-default
|
||||
|
||||
# Electron app
|
||||
- *step-electron-build
|
||||
- *step-show-sccache-stats
|
||||
- *step-maybe-generate-breakpad-symbols
|
||||
- *step-maybe-electron-dist-strip
|
||||
- *step-electron-dist-build
|
||||
- *step-electron-dist-store
|
||||
- *step-maybe-zip-symbols
|
||||
- *step-symbols-store
|
||||
|
||||
# mksnapshot
|
||||
- *step-mksnapshot-build
|
||||
- *step-mksnapshot-store
|
||||
|
||||
# chromedriver
|
||||
- *step-electron-maybe-chromedriver-gn-gen
|
||||
- *step-electron-chromedriver-build
|
||||
- *step-electron-chromedriver-store
|
||||
|
||||
# Node.js headers
|
||||
- *step-nodejs-headers-build
|
||||
- *step-nodejs-headers-store
|
||||
|
||||
# ffmpeg
|
||||
- *step-ffmpeg-gn-gen
|
||||
- *step-ffmpeg-build
|
||||
- *step-ffmpeg-store
|
||||
|
||||
# hunspell
|
||||
- *step-hunspell-build
|
||||
- *step-hunspell-store
|
||||
|
||||
# typescript defs
|
||||
- *step-maybe-generate-typescript-defs
|
||||
|
||||
# Publish
|
||||
- *step-electron-publish
|
||||
|
||||
# List of all jobs.
|
||||
jobs:
|
||||
@@ -1497,6 +1516,20 @@ jobs:
|
||||
<<: *steps-electron-ts-compile-for-doc-change
|
||||
|
||||
# Layer 1: Checkout.
|
||||
linux-checkout:
|
||||
<<: *machine-linux-2xlarge
|
||||
environment:
|
||||
<<: *env-linux-2xlarge
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True --custom-var=checkout_boto=True --custom-var=checkout_requests=True'
|
||||
steps:
|
||||
- electron-build:
|
||||
persist: false
|
||||
build: false
|
||||
checkout: true
|
||||
persist-checkout: true
|
||||
restore-src-cache: false
|
||||
preserve-vendor-dirs: true
|
||||
|
||||
linux-checkout-fast:
|
||||
<<: *machine-linux-2xlarge
|
||||
environment:
|
||||
@@ -1540,6 +1573,22 @@ jobs:
|
||||
checkout: true
|
||||
persist-checkout: true
|
||||
|
||||
mac-checkout:
|
||||
<<: *machine-linux-2xlarge
|
||||
environment:
|
||||
<<: *env-linux-2xlarge
|
||||
<<: *env-testing-build
|
||||
<<: *env-macos-build
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_mac=True --custom-var=host_os=mac --custom-var=checkout_boto=True --custom-var=checkout_requests=True'
|
||||
steps:
|
||||
- electron-build:
|
||||
persist: false
|
||||
build: false
|
||||
checkout: true
|
||||
persist-checkout: true
|
||||
restore-src-cache: false
|
||||
preserve-vendor-dirs: true
|
||||
|
||||
mac-checkout-fast:
|
||||
<<: *machine-linux-2xlarge
|
||||
environment:
|
||||
@@ -1569,7 +1618,6 @@ jobs:
|
||||
environment:
|
||||
<<: *env-linux-2xlarge
|
||||
<<: *env-testing-build
|
||||
<<: *env-enable-sccache
|
||||
<<: *env-ninja-status
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
|
||||
steps:
|
||||
@@ -1583,7 +1631,6 @@ jobs:
|
||||
environment:
|
||||
<<: *env-linux-2xlarge
|
||||
<<: *env-testing-build
|
||||
<<: *env-enable-sccache
|
||||
<<: *env-ninja-status
|
||||
<<: *env-disable-run-as-node
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
|
||||
@@ -1605,7 +1652,6 @@ jobs:
|
||||
environment:
|
||||
<<: *env-linux-medium
|
||||
<<: *env-release-build
|
||||
<<: *env-enable-sccache
|
||||
<<: *env-send-slack-notifications
|
||||
<<: *steps-chromedriver-build
|
||||
|
||||
@@ -1614,12 +1660,27 @@ jobs:
|
||||
environment:
|
||||
<<: *env-linux-2xlarge-release
|
||||
<<: *env-release-build
|
||||
<<: *env-enable-sccache
|
||||
<<: *env-send-slack-notifications
|
||||
<<: *env-ninja-status
|
||||
<<: *steps-electron-build
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
|
||||
steps:
|
||||
- electron-build:
|
||||
persist: true
|
||||
checkout: true
|
||||
|
||||
linux-x64-publish:
|
||||
<<: *machine-linux-2xlarge
|
||||
environment:
|
||||
<<: *env-linux-2xlarge-release
|
||||
<<: *env-release-build
|
||||
<<: *env-enable-sccache
|
||||
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
|
||||
steps:
|
||||
- electron-publish:
|
||||
attach: false
|
||||
checkout: true
|
||||
|
||||
linux-x64-publish-skip-checkout:
|
||||
<<: *machine-linux-2xlarge
|
||||
environment:
|
||||
<<: *env-linux-2xlarge-release
|
||||
@@ -1627,7 +1688,10 @@ jobs:
|
||||
<<: *env-release-build
|
||||
<<: *env-enable-sccache
|
||||
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
|
||||
<<: *steps-electron-build-for-publish
|
||||
steps:
|
||||
- electron-publish:
|
||||
attach: true
|
||||
checkout: false
|
||||
|
||||
linux-ia32-testing:
|
||||
<<: *machine-linux-2xlarge
|
||||
@@ -1635,7 +1699,6 @@ jobs:
|
||||
<<: *env-linux-2xlarge
|
||||
<<: *env-ia32
|
||||
<<: *env-testing-build
|
||||
<<: *env-enable-sccache
|
||||
<<: *env-ninja-status
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
|
||||
steps:
|
||||
@@ -1650,7 +1713,6 @@ jobs:
|
||||
<<: *env-linux-medium
|
||||
<<: *env-ia32
|
||||
<<: *env-release-build
|
||||
<<: *env-enable-sccache
|
||||
<<: *env-send-slack-notifications
|
||||
<<: *steps-chromedriver-build
|
||||
|
||||
@@ -1660,12 +1722,29 @@ jobs:
|
||||
<<: *env-linux-2xlarge-release
|
||||
<<: *env-ia32
|
||||
<<: *env-release-build
|
||||
<<: *env-enable-sccache
|
||||
<<: *env-send-slack-notifications
|
||||
<<: *env-ninja-status
|
||||
<<: *steps-electron-build
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
|
||||
steps:
|
||||
- electron-build:
|
||||
persist: true
|
||||
checkout: true
|
||||
|
||||
linux-ia32-publish:
|
||||
<<: *machine-linux-2xlarge
|
||||
environment:
|
||||
<<: *env-linux-2xlarge-release
|
||||
<<: *env-ia32
|
||||
<<: *env-release-build
|
||||
<<: *env-enable-sccache
|
||||
<<: *env-32bit-release
|
||||
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
|
||||
steps:
|
||||
- electron-publish:
|
||||
attach: false
|
||||
checkout: true
|
||||
|
||||
linux-ia32-publish-skip-checkout:
|
||||
<<: *machine-linux-2xlarge
|
||||
environment:
|
||||
<<: *env-linux-2xlarge-release
|
||||
@@ -1675,7 +1754,10 @@ jobs:
|
||||
<<: *env-enable-sccache
|
||||
<<: *env-32bit-release
|
||||
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
|
||||
<<: *steps-electron-build-for-publish
|
||||
steps:
|
||||
- electron-publish:
|
||||
attach: true
|
||||
checkout: false
|
||||
|
||||
linux-arm-testing:
|
||||
<<: *machine-linux-2xlarge
|
||||
@@ -1683,7 +1765,6 @@ jobs:
|
||||
<<: *env-linux-2xlarge
|
||||
<<: *env-arm
|
||||
<<: *env-testing-build
|
||||
<<: *env-enable-sccache
|
||||
<<: *env-ninja-status
|
||||
TRIGGER_ARM_TEST: true
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
|
||||
@@ -1699,7 +1780,6 @@ jobs:
|
||||
<<: *env-linux-medium
|
||||
<<: *env-arm
|
||||
<<: *env-release-build
|
||||
<<: *env-enable-sccache
|
||||
<<: *env-send-slack-notifications
|
||||
<<: *steps-chromedriver-build
|
||||
|
||||
@@ -1709,12 +1789,29 @@ jobs:
|
||||
<<: *env-linux-2xlarge-release
|
||||
<<: *env-arm
|
||||
<<: *env-release-build
|
||||
<<: *env-enable-sccache
|
||||
<<: *env-send-slack-notifications
|
||||
<<: *env-ninja-status
|
||||
<<: *steps-electron-build
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
|
||||
steps:
|
||||
- electron-build:
|
||||
persist: false
|
||||
checkout: true
|
||||
|
||||
linux-arm-publish:
|
||||
<<: *machine-linux-2xlarge
|
||||
environment:
|
||||
<<: *env-linux-2xlarge-release
|
||||
<<: *env-arm
|
||||
<<: *env-release-build
|
||||
<<: *env-enable-sccache
|
||||
<<: *env-32bit-release
|
||||
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
|
||||
steps:
|
||||
- electron-publish:
|
||||
attach: false
|
||||
checkout: true
|
||||
|
||||
linux-arm-publish-skip-checkout:
|
||||
<<: *machine-linux-2xlarge
|
||||
environment:
|
||||
<<: *env-linux-2xlarge-release
|
||||
@@ -1724,7 +1821,10 @@ jobs:
|
||||
<<: *env-32bit-release
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_boto=True --custom-var=checkout_requests=True'
|
||||
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
|
||||
<<: *steps-electron-build-for-publish
|
||||
steps:
|
||||
- electron-publish:
|
||||
attach: true
|
||||
checkout: false
|
||||
|
||||
linux-arm64-testing:
|
||||
<<: *machine-linux-2xlarge
|
||||
@@ -1732,7 +1832,6 @@ jobs:
|
||||
<<: *env-linux-2xlarge
|
||||
<<: *env-arm64
|
||||
<<: *env-testing-build
|
||||
<<: *env-enable-sccache
|
||||
<<: *env-ninja-status
|
||||
TRIGGER_ARM_TEST: true
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
|
||||
@@ -1756,7 +1855,6 @@ jobs:
|
||||
<<: *env-linux-medium
|
||||
<<: *env-arm64
|
||||
<<: *env-release-build
|
||||
<<: *env-enable-sccache
|
||||
<<: *env-send-slack-notifications
|
||||
<<: *steps-chromedriver-build
|
||||
|
||||
@@ -1766,12 +1864,28 @@ jobs:
|
||||
<<: *env-linux-2xlarge-release
|
||||
<<: *env-arm64
|
||||
<<: *env-release-build
|
||||
<<: *env-enable-sccache
|
||||
<<: *env-send-slack-notifications
|
||||
<<: *env-ninja-status
|
||||
<<: *steps-electron-build
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
|
||||
steps:
|
||||
- electron-build:
|
||||
persist: false
|
||||
checkout: true
|
||||
|
||||
linux-arm64-publish:
|
||||
<<: *machine-linux-2xlarge
|
||||
environment:
|
||||
<<: *env-linux-2xlarge-release
|
||||
<<: *env-arm64
|
||||
<<: *env-release-build
|
||||
<<: *env-enable-sccache
|
||||
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
|
||||
steps:
|
||||
- electron-publish:
|
||||
attach: false
|
||||
checkout: true
|
||||
|
||||
linux-arm64-publish-skip-checkout:
|
||||
<<: *machine-linux-2xlarge
|
||||
environment:
|
||||
<<: *env-linux-2xlarge-release
|
||||
@@ -1780,14 +1894,16 @@ jobs:
|
||||
<<: *env-enable-sccache
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm64=True --custom-var=checkout_boto=True --custom-var=checkout_requests=True'
|
||||
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
|
||||
<<: *steps-electron-build-for-publish
|
||||
steps:
|
||||
- electron-publish:
|
||||
attach: true
|
||||
checkout: false
|
||||
|
||||
osx-testing:
|
||||
<<: *machine-mac-large
|
||||
environment:
|
||||
<<: *env-mac-large
|
||||
<<: *env-testing-build
|
||||
<<: *env-enable-sccache
|
||||
<<: *env-ninja-status
|
||||
<<: *env-macos-build
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_mac=True --custom-var=host_os=mac'
|
||||
@@ -1810,7 +1926,6 @@ jobs:
|
||||
environment:
|
||||
<<: *env-machine-mac
|
||||
<<: *env-release-build
|
||||
<<: *env-enable-sccache
|
||||
<<: *env-send-slack-notifications
|
||||
<<: *steps-chromedriver-build
|
||||
|
||||
@@ -1819,11 +1934,28 @@ jobs:
|
||||
environment:
|
||||
<<: *env-mac-large
|
||||
<<: *env-release-build
|
||||
<<: *env-enable-sccache
|
||||
<<: *env-ninja-status
|
||||
<<: *steps-electron-build
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_mac=True --custom-var=host_os=mac'
|
||||
steps:
|
||||
- electron-build:
|
||||
persist: true
|
||||
checkout: false
|
||||
checkout-and-assume-cache: true
|
||||
attach: false
|
||||
|
||||
osx-publish:
|
||||
<<: *machine-mac-large
|
||||
environment:
|
||||
<<: *env-mac-large-release
|
||||
<<: *env-release-build
|
||||
<<: *env-enable-sccache
|
||||
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
|
||||
steps:
|
||||
- electron-publish:
|
||||
attach: false
|
||||
checkout: true
|
||||
|
||||
osx-publish-skip-checkout:
|
||||
<<: *machine-mac-large
|
||||
environment:
|
||||
<<: *env-mac-large-release
|
||||
@@ -1831,7 +1963,10 @@ jobs:
|
||||
<<: *env-enable-sccache
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_boto=True --custom-var=checkout_requests=True'
|
||||
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
|
||||
<<: *steps-electron-build-for-publish
|
||||
steps:
|
||||
- electron-publish:
|
||||
attach: true
|
||||
checkout: false
|
||||
|
||||
mas-testing:
|
||||
<<: *machine-mac-large
|
||||
@@ -1839,7 +1974,6 @@ jobs:
|
||||
<<: *env-mac-large
|
||||
<<: *env-mas
|
||||
<<: *env-testing-build
|
||||
<<: *env-enable-sccache
|
||||
<<: *env-ninja-status
|
||||
<<: *env-macos-build
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_mac=True --custom-var=host_os=mac'
|
||||
@@ -1863,7 +1997,6 @@ jobs:
|
||||
environment:
|
||||
<<: *env-machine-mac
|
||||
<<: *env-release-build
|
||||
<<: *env-enable-sccache
|
||||
<<: *env-send-slack-notifications
|
||||
<<: *steps-chromedriver-build
|
||||
|
||||
@@ -1873,11 +2006,29 @@ jobs:
|
||||
<<: *env-mac-large
|
||||
<<: *env-mas
|
||||
<<: *env-release-build
|
||||
<<: *env-enable-sccache
|
||||
<<: *env-ninja-status
|
||||
<<: *steps-electron-build
|
||||
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_mac=True --custom-var=host_os=mac'
|
||||
steps:
|
||||
- electron-build:
|
||||
persist: true
|
||||
checkout: false
|
||||
checkout-and-assume-cache: true
|
||||
attach: false
|
||||
|
||||
mas-publish:
|
||||
<<: *machine-mac-large
|
||||
environment:
|
||||
<<: *env-mac-large-release
|
||||
<<: *env-mas
|
||||
<<: *env-release-build
|
||||
<<: *env-enable-sccache
|
||||
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
|
||||
steps:
|
||||
- electron-publish:
|
||||
attach: false
|
||||
checkout: true
|
||||
|
||||
mas-publish-skip-checkout:
|
||||
<<: *machine-mac-large
|
||||
environment:
|
||||
<<: *env-mac-large-release
|
||||
@@ -1886,7 +2037,10 @@ jobs:
|
||||
<<: *env-enable-sccache
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_boto=True --custom-var=checkout_requests=True'
|
||||
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
|
||||
<<: *steps-electron-build-for-publish
|
||||
steps:
|
||||
- electron-publish:
|
||||
attach: true
|
||||
checkout: false
|
||||
|
||||
# Layer 3: Tests.
|
||||
linux-x64-unittests:
|
||||
@@ -1894,7 +2048,6 @@ jobs:
|
||||
environment:
|
||||
<<: *env-linux-2xlarge
|
||||
<<: *env-unittests
|
||||
<<: *env-enable-sccache
|
||||
<<: *env-headless-testing
|
||||
<<: *steps-native-tests
|
||||
|
||||
@@ -1903,7 +2056,6 @@ jobs:
|
||||
environment:
|
||||
<<: *env-linux-2xlarge
|
||||
<<: *env-unittests
|
||||
<<: *env-enable-sccache
|
||||
<<: *env-headless-testing
|
||||
TESTS_ARGS: '--only-disabled-tests'
|
||||
<<: *steps-native-tests
|
||||
@@ -1913,7 +2065,6 @@ jobs:
|
||||
environment:
|
||||
<<: *env-linux-2xlarge
|
||||
<<: *env-unittests
|
||||
<<: *env-enable-sccache
|
||||
<<: *env-headless-testing
|
||||
TESTS_ARGS: '--include-disabled-tests'
|
||||
<<: *steps-native-tests
|
||||
@@ -1924,7 +2075,6 @@ jobs:
|
||||
<<: *env-linux-2xlarge
|
||||
<<: *env-browsertests
|
||||
<<: *env-testing-build
|
||||
<<: *env-enable-sccache
|
||||
<<: *env-headless-testing
|
||||
<<: *steps-native-tests
|
||||
|
||||
@@ -2180,6 +2330,27 @@ workflows:
|
||||
# will need to be updated and there will most likely need to be changes to
|
||||
# sudowoodo
|
||||
|
||||
publish-linux:
|
||||
when: << pipeline.parameters.run-linux-publish >>
|
||||
jobs:
|
||||
- linux-checkout
|
||||
- linux-x64-publish-skip-checkout:
|
||||
requires:
|
||||
- linux-checkout
|
||||
context: release-env
|
||||
- linux-ia32-publish-skip-checkout:
|
||||
requires:
|
||||
- linux-checkout
|
||||
context: release-env
|
||||
- linux-arm-publish-skip-checkout:
|
||||
requires:
|
||||
- linux-checkout
|
||||
context: release-env
|
||||
- linux-arm64-publish-skip-checkout:
|
||||
requires:
|
||||
- linux-checkout
|
||||
context: release-env
|
||||
|
||||
publish-x64-linux:
|
||||
when: << pipeline.parameters.run-linux-x64-publish >>
|
||||
jobs:
|
||||
@@ -2216,6 +2387,17 @@ workflows:
|
||||
- mas-publish:
|
||||
context: release-env
|
||||
|
||||
publish-macos:
|
||||
when: << pipeline.parameters.run-macos-publish >>
|
||||
jobs:
|
||||
- mac-checkout
|
||||
- osx-publish-skip-checkout:
|
||||
requires:
|
||||
- mac-checkout
|
||||
- mas-publish-skip-checkout:
|
||||
requires:
|
||||
- mac-checkout
|
||||
|
||||
lint:
|
||||
when: << pipeline.parameters.run-lint >>
|
||||
jobs:
|
||||
@@ -2302,10 +2484,9 @@ workflows:
|
||||
- *chromium-upgrade-branches
|
||||
jobs:
|
||||
- linux-checkout-fast
|
||||
- linux-checkout-and-save-cache
|
||||
|
||||
- linux-x64-release:
|
||||
requires:
|
||||
- linux-checkout-fast
|
||||
- linux-x64-release
|
||||
- linux-x64-release-tests:
|
||||
requires:
|
||||
- linux-x64-release
|
||||
@@ -2329,9 +2510,7 @@ workflows:
|
||||
- linux-x64-verify-ffmpeg
|
||||
- linux-x64-chromedriver
|
||||
|
||||
- linux-ia32-release:
|
||||
requires:
|
||||
- linux-checkout-fast
|
||||
- linux-ia32-release
|
||||
- linux-ia32-release-tests:
|
||||
requires:
|
||||
- linux-ia32-release
|
||||
@@ -2355,9 +2534,7 @@ workflows:
|
||||
- linux-ia32-verify-ffmpeg
|
||||
- linux-ia32-chromedriver
|
||||
|
||||
- linux-arm-release:
|
||||
requires:
|
||||
- linux-checkout-fast
|
||||
- linux-arm-release
|
||||
- linux-arm-chromedriver:
|
||||
requires:
|
||||
- linux-checkout-fast
|
||||
@@ -2366,10 +2543,7 @@ workflows:
|
||||
- linux-arm-release
|
||||
- linux-arm-chromedriver
|
||||
|
||||
|
||||
- linux-arm64-release:
|
||||
requires:
|
||||
- linux-checkout-fast
|
||||
- linux-arm64-release
|
||||
- linux-arm64-chromedriver:
|
||||
requires:
|
||||
- linux-checkout-fast
|
||||
@@ -2389,10 +2563,11 @@ workflows:
|
||||
- *chromium-upgrade-branches
|
||||
jobs:
|
||||
- mac-checkout-fast
|
||||
- mac-checkout-and-save-cache
|
||||
|
||||
- osx-release:
|
||||
requires:
|
||||
- mac-checkout-fast
|
||||
- mac-checkout-and-save-cache
|
||||
- osx-release-tests:
|
||||
requires:
|
||||
- osx-release
|
||||
@@ -2418,7 +2593,7 @@ workflows:
|
||||
|
||||
- mas-release:
|
||||
requires:
|
||||
- mac-checkout-fast
|
||||
- mac-checkout-and-save-cache
|
||||
- mas-release-tests:
|
||||
requires:
|
||||
- mas-release
|
||||
|
||||
14
BUILD.gn
14
BUILD.gn
@@ -629,8 +629,6 @@ source_set("electron_lib") {
|
||||
deps += [ "//components/printing/common:mojo_interfaces" ]
|
||||
}
|
||||
|
||||
deps += [ "shell/common/extensions/api:extensions_features" ]
|
||||
deps += [ "shell/common/extensions/api" ]
|
||||
deps += [
|
||||
"//components/pref_registry",
|
||||
"//components/user_prefs",
|
||||
@@ -642,12 +640,22 @@ source_set("electron_lib") {
|
||||
]
|
||||
if (enable_electron_extensions) {
|
||||
sources += filenames.lib_sources_extensions
|
||||
deps += [
|
||||
"shell/browser/extensions/api:api_registration",
|
||||
"shell/common/extensions/api",
|
||||
"shell/common/extensions/api:extensions_features",
|
||||
"//chrome/browser/resources:component_extension_resources",
|
||||
"//components/zoom",
|
||||
]
|
||||
}
|
||||
|
||||
if (enable_pdf) {
|
||||
# Printing depends on some //pdf code, so it needs to be built even if the
|
||||
# pdf viewer isn't enabled.
|
||||
deps += [ "//pdf" ]
|
||||
deps += [
|
||||
"//pdf",
|
||||
"//pdf:features",
|
||||
]
|
||||
}
|
||||
if (enable_pdf_viewer) {
|
||||
deps += [
|
||||
|
||||
@@ -1 +1 @@
|
||||
9.0.0-nightly.20200205
|
||||
9.0.0-beta.3
|
||||
24
appveyor.yml
24
appveyor.yml
@@ -118,19 +118,29 @@ build_script:
|
||||
}
|
||||
}
|
||||
- ps: >-
|
||||
if (Test-Path 'env:RAW_GOMA_AUTH') {
|
||||
$env:GOMA_OAUTH2_CONFIG_FILE = "$pwd\.goma_oauth2_config"
|
||||
$env:RAW_GOMA_AUTH | Set-Content $env:GOMA_OAUTH2_CONFIG_FILE
|
||||
.\src\electron\script\start-goma.ps1 -gomaDir "$pwd\src\electron\external_binaries\goma"
|
||||
if ($env:GN_CONFIG -ne 'release') {
|
||||
if (Test-Path 'env:RAW_GOMA_AUTH') {
|
||||
$env:GOMA_OAUTH2_CONFIG_FILE = "$pwd\.goma_oauth2_config"
|
||||
$env:RAW_GOMA_AUTH | Set-Content $env:GOMA_OAUTH2_CONFIG_FILE
|
||||
}
|
||||
git clone https://github.com/electron/build-tools.git
|
||||
cd build-tools
|
||||
npm install
|
||||
mkdir third_party
|
||||
node -e "require('./src/utils/goma.js').downloadAndPrepare()"
|
||||
$env:GN_GOMA_FILE = node -e "console.log(require('./src/utils/goma.js').gnFilePath)"
|
||||
$env:LOCAL_GOMA_DIR = node -e "console.log(require('./src/utils/goma.js').dir)"
|
||||
cd ..
|
||||
.\src\electron\script\start-goma.ps1 -gomaDir $env:LOCAL_GOMA_DIR
|
||||
}
|
||||
- cd src
|
||||
- set BUILD_CONFIG_PATH=//electron/build/args/%GN_CONFIG%.gn
|
||||
- if DEFINED RAW_GOMA_AUTH (gn gen out/Default "--args=import(\"%BUILD_CONFIG_PATH%\") import(\"//electron/build/args/goma.gn\") %GN_EXTRA_ARGS% ") else (gn gen out/Default "--args=import(\"%BUILD_CONFIG_PATH%\") %GN_EXTRA_ARGS% cc_wrapper=\"%SCCACHE_PATH%\"")
|
||||
- if DEFINED GN_GOMA_FILE (gn gen out/Default "--args=import(\"%BUILD_CONFIG_PATH%\") import(\"%GN_GOMA_FILE%\") %GN_EXTRA_ARGS% ") else (gn gen out/Default "--args=import(\"%BUILD_CONFIG_PATH%\") %GN_EXTRA_ARGS% cc_wrapper=\"%SCCACHE_PATH%\"")
|
||||
- gn check out/Default //electron:electron_lib
|
||||
- gn check out/Default //electron:electron_app
|
||||
- gn check out/Default //electron:manifests
|
||||
- gn check out/Default //electron/shell/common/api:mojo
|
||||
- if DEFINED RAW_GOMA_AUTH (ninja -j 300 -C out/Default electron:electron_app) else (ninja -C out/Default electron:electron_app)
|
||||
- if DEFINED GN_GOMA_FILE (ninja -j 300 -C out/Default electron:electron_app) else (ninja -C out/Default electron:electron_app)
|
||||
- if "%GN_CONFIG%"=="testing" ( python C:\depot_tools\post_build_ninja_summary.py -C out\Default )
|
||||
- gn gen out/ffmpeg "--args=import(\"//electron/build/args/ffmpeg.gn\") %GN_EXTRA_ARGS%"
|
||||
- ninja -C out/ffmpeg electron:electron_ffmpeg_zip
|
||||
@@ -140,7 +150,7 @@ build_script:
|
||||
- ninja -C out/Default electron:hunspell_dictionaries_zip
|
||||
- ninja -C out/Default electron:electron_chromedriver_zip
|
||||
- ninja -C out/Default third_party/electron_node:headers
|
||||
- if DEFINED RAW_GOMA_AUTH (python electron\external_binaries\goma\goma_ctl.py stat)
|
||||
- if "%GN_CONFIG%"=="testing" ( python %LOCAL_GOMA_DIR%\goma_ctl.py stat )
|
||||
- python electron/build/profile_toolchain.py --output-json=out/Default/windows_toolchain_profile.json
|
||||
- appveyor PushArtifact out/Default/windows_toolchain_profile.json
|
||||
- appveyor PushArtifact out/Default/dist.zip
|
||||
|
||||
@@ -2,7 +2,7 @@ is_electron_build = true
|
||||
root_extra_deps = [ "//electron" ]
|
||||
|
||||
# Registry of NMVs --> https://github.com/nodejs/node/blob/master/doc/abi_version_registry.json
|
||||
node_module_version = 76
|
||||
node_module_version = 80
|
||||
|
||||
v8_promise_internal_field_count = 1
|
||||
v8_typed_array_max_size_in_heap = 0
|
||||
|
||||
@@ -14,7 +14,7 @@ declare_args() {
|
||||
|
||||
enable_view_api = false
|
||||
|
||||
enable_pdf_viewer = false
|
||||
enable_pdf_viewer = true
|
||||
|
||||
enable_tts = true
|
||||
|
||||
|
||||
@@ -233,6 +233,12 @@ static_library("chrome") {
|
||||
|
||||
if (enable_electron_extensions) {
|
||||
sources += [
|
||||
"//chrome/browser/extensions/chrome_url_request_util.cc",
|
||||
"//chrome/browser/extensions/chrome_url_request_util.h",
|
||||
"//chrome/browser/pdf/pdf_extension_util.cc",
|
||||
"//chrome/browser/pdf/pdf_extension_util.h",
|
||||
"//chrome/browser/plugins/plugin_response_interceptor_url_loader_throttle.cc",
|
||||
"//chrome/browser/plugins/plugin_response_interceptor_url_loader_throttle.h",
|
||||
"//chrome/renderer/extensions/extension_hooks_delegate.cc",
|
||||
"//chrome/renderer/extensions/extension_hooks_delegate.h",
|
||||
"//chrome/renderer/extensions/tabs_hooks_delegate.cc",
|
||||
|
||||
@@ -703,34 +703,34 @@ Clears the recent documents list.
|
||||
|
||||
### `app.setAsDefaultProtocolClient(protocol[, path, args])`
|
||||
|
||||
* `protocol` String - The name of your protocol, without `://`. If you want your
|
||||
app to handle `electron://` links, call this method with `electron` as the
|
||||
parameter.
|
||||
* `path` String (optional) _Windows_ - Defaults to `process.execPath`
|
||||
* `args` String[] (optional) _Windows_ - Defaults to an empty array
|
||||
* `protocol` String - The name of your protocol, without `://`. For example,
|
||||
if you want your app to handle `electron://` links, call this method with
|
||||
`electron` as the parameter.
|
||||
* `path` String (optional) _Windows_ - The path to the Electron executable.
|
||||
Defaults to `process.execPath`
|
||||
* `args` String[] (optional) _Windows_ - Arguments passed to the executable.
|
||||
Defaults to an empty array
|
||||
|
||||
Returns `Boolean` - Whether the call succeeded.
|
||||
|
||||
This method sets the current executable as the default handler for a protocol
|
||||
(aka URI scheme). It allows you to integrate your app deeper into the operating
|
||||
system. Once registered, all links with `your-protocol://` will be opened with
|
||||
the current executable. The whole link, including protocol, will be passed to
|
||||
your application as a parameter.
|
||||
|
||||
On Windows, you can provide optional parameters path, the path to your executable,
|
||||
and args, an array of arguments to be passed to your executable when it launches.
|
||||
Sets the current executable as the default handler for a protocol (aka URI
|
||||
scheme). It allows you to integrate your app deeper into the operating system.
|
||||
Once registered, all links with `your-protocol://` will be opened with the
|
||||
current executable. The whole link, including protocol, will be passed to your
|
||||
application as a parameter.
|
||||
|
||||
**Note:** On macOS, you can only register protocols that have been added to
|
||||
your app's `info.plist`, which can not be modified at runtime. You can however
|
||||
change the file with a simple text editor or script during build time.
|
||||
Please refer to [Apple's documentation][CFBundleURLTypes] for details.
|
||||
your app's `info.plist`, which cannot be modified at runtime. However, you can
|
||||
change the file during build time via [Electron Forge][electron-forge],
|
||||
[Electron Packager][electron-packager], or by editing `info.plist` with a text
|
||||
editor. Please refer to [Apple's documentation][CFBundleURLTypes] for details.
|
||||
|
||||
**Note:** In a Windows Store environment (when packaged as an `appx`) this API
|
||||
will return `true` for all calls but the registry key it sets won't be accessible
|
||||
by other applications. In order to register your Windows Store application
|
||||
as a default protocol handler you must [declare the protocol in your manifest](https://docs.microsoft.com/en-us/uwp/schemas/appxpackage/uapmanifestschema/element-uap-protocol).
|
||||
|
||||
The API uses the Windows Registry and LSSetDefaultHandlerForURLScheme internally.
|
||||
The API uses the Windows Registry and `LSSetDefaultHandlerForURLScheme` internally.
|
||||
|
||||
### `app.removeAsDefaultProtocolClient(protocol[, path, args])` _macOS_ _Windows_
|
||||
|
||||
@@ -749,10 +749,8 @@ protocol (aka URI scheme). If so, it will remove the app as the default handler.
|
||||
* `path` String (optional) _Windows_ - Defaults to `process.execPath`
|
||||
* `args` String[] (optional) _Windows_ - Defaults to an empty array
|
||||
|
||||
Returns `Boolean`
|
||||
|
||||
This method checks if the current executable is the default handler for a protocol
|
||||
(aka URI scheme). If so, it will return true. Otherwise, it will return false.
|
||||
Returns `Boolean` - Whether the current executable is the default handler for a
|
||||
protocol (aka URI scheme).
|
||||
|
||||
**Note:** On macOS, you can use this method to check if the app has been
|
||||
registered as the default protocol handler for a protocol. You can also verify
|
||||
@@ -760,7 +758,7 @@ this by checking `~/Library/Preferences/com.apple.LaunchServices.plist` on the
|
||||
macOS machine. Please refer to
|
||||
[Apple's documentation][LSCopyDefaultHandlerForURLScheme] for details.
|
||||
|
||||
The API uses the Windows Registry and LSCopyDefaultHandlerForURLScheme internally.
|
||||
The API uses the Windows Registry and `LSCopyDefaultHandlerForURLScheme` internally.
|
||||
|
||||
### `app.getApplicationNameForProtocol(url)`
|
||||
|
||||
@@ -1327,6 +1325,8 @@ A `Boolean` property that returns `true` if the app is packaged, `false` otherw
|
||||
[dock-menu]:https://developer.apple.com/macos/human-interface-guidelines/menus/dock-menus/
|
||||
[tasks]:https://msdn.microsoft.com/en-us/library/windows/desktop/dd378460(v=vs.85).aspx#tasks
|
||||
[app-user-model-id]: https://msdn.microsoft.com/en-us/library/windows/desktop/dd378459(v=vs.85).aspx
|
||||
[electron-forge]: https://www.electronforge.io/
|
||||
[electron-packager]: https://github.com/electron/electron-packager
|
||||
[CFBundleURLTypes]: https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html#//apple_ref/doc/uid/TP40009249-102207-TPXREF115
|
||||
[LSCopyDefaultHandlerForURLScheme]: https://developer.apple.com/library/mac/documentation/Carbon/Reference/LaunchServicesReference/#//apple_ref/c/func/LSCopyDefaultHandlerForURLScheme
|
||||
[handoff]: https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/Handoff/HandoffFundamentals/HandoffFundamentals.html
|
||||
|
||||
@@ -53,16 +53,23 @@ Unsupported options are:
|
||||
|
||||
### `GOOGLE_API_KEY`
|
||||
|
||||
You can provide an API key for making requests to Google's geocoding webservice. To do this, place the following code in your main process
|
||||
file, before opening any browser windows that will make geocoding requests:
|
||||
Geolocation support in Electron requires the use of Google Cloud Platform's
|
||||
geolocation webservice. To enable this feature, acquire a
|
||||
[Google API key](https://developers.google.com/maps/documentation/geolocation/get-api-key)
|
||||
and place the following code in your main process file, before opening any
|
||||
browser windows that will make geolocation requests:
|
||||
|
||||
```javascript
|
||||
process.env.GOOGLE_API_KEY = 'YOUR_KEY_HERE'
|
||||
```
|
||||
|
||||
For instructions on how to acquire a Google API key, visit [this page](https://developers.google.com/maps/documentation/javascript/get-api-key).
|
||||
By default, a newly generated Google API key may not be allowed to make
|
||||
geocoding requests. To enable geocoding requests, visit [this page](https://developers.google.com/maps/documentation/geocoding/get-api-key).
|
||||
By default, a newly generated Google API key may not be allowed to make geolocation requests.
|
||||
To enable the geolocation webservice for your project, enable it through the
|
||||
[API library](https://console.cloud.google.com/apis/library).
|
||||
|
||||
N.B. You will need to add a
|
||||
[Billing Account](https://cloud.google.com/billing/docs/how-to/payment-methods#add_a_payment_method)
|
||||
to the project associated to the API key for the geolocation webservice to work.
|
||||
|
||||
### `ELECTRON_NO_ASAR`
|
||||
|
||||
|
||||
@@ -487,6 +487,11 @@ to host here.
|
||||
|
||||
**Note:** On macOS the OS spellchecker is used and therefore we do not download any dictionary files. This API is a no-op on macOS.
|
||||
|
||||
#### `ses.listWordsInSpellCheckerDictionary()`
|
||||
|
||||
Returns `Promise<String[]>` - An array of all words in app's custom dictionary.
|
||||
Resolves when the full dictionary is loaded from disk.
|
||||
|
||||
#### `ses.addWordToSpellCheckerDictionary(word)`
|
||||
|
||||
* `word` String - The word you want to add to the dictionary
|
||||
|
||||
@@ -404,8 +404,6 @@ Returns `Boolean` - whether or not this device has the ability to use Touch ID.
|
||||
|
||||
**NOTE:** This API will return `false` on macOS systems older than Sierra 10.12.2.
|
||||
|
||||
**[Deprecated](modernization/property-updates.md)**
|
||||
|
||||
### `systemPreferences.promptTouchID(reason)` _macOS_
|
||||
|
||||
* `reason` String - The reason you are asking for Touch ID authentication
|
||||
|
||||
@@ -146,6 +146,7 @@ response are visible by the time this listener is fired.
|
||||
* `timestamp` Double
|
||||
* `statusLine` String
|
||||
* `statusCode` Integer
|
||||
* `requestHeaders` Record<string, string>
|
||||
* `responseHeaders` Record<string, string[]> (optional)
|
||||
* `callback` Function
|
||||
* `headersReceivedResponse` Object
|
||||
@@ -228,6 +229,7 @@ redirect is about to occur.
|
||||
* `fromCache` Boolean
|
||||
* `statusCode` Integer
|
||||
* `statusLine` String
|
||||
* `error` String
|
||||
|
||||
The `listener` will be called with `listener(details)` when a request is
|
||||
completed.
|
||||
|
||||
@@ -92,10 +92,14 @@ template("electron_extra_paks") {
|
||||
}
|
||||
if (enable_electron_extensions) {
|
||||
sources += [
|
||||
"$root_gen_dir/chrome/component_extension_resources.pak",
|
||||
"$root_gen_dir/extensions/extensions_renderer_resources.pak",
|
||||
"$root_gen_dir/extensions/extensions_resources.pak",
|
||||
]
|
||||
deps += [ "//extensions:extensions_resources" ]
|
||||
deps += [
|
||||
"//chrome/browser/resources:component_extension_resources",
|
||||
"//extensions:extensions_resources",
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
<part file="electron_strings.grdp" />
|
||||
</messages>
|
||||
<includes>
|
||||
<include name="IDR_CONTENT_SHELL_DEVTOOLS_DISCOVERY_PAGE" file="${target_gen_dir}\shell_devtools_discovery_page.html" use_base_dir="false" type="BINDATA" />
|
||||
<include name="IDR_CONTENT_SHELL_DEVTOOLS_DISCOVERY_PAGE" file="${target_gen_dir}/shell_devtools_discovery_page.html" use_base_dir="false" type="BINDATA" />
|
||||
<include name="IDR_PDF_MANIFEST" file="../chrome/browser/resources/pdf/manifest.json" type="BINDATA" />
|
||||
</includes>
|
||||
</release>
|
||||
</grit>
|
||||
|
||||
@@ -234,12 +234,15 @@ filenames = {
|
||||
"shell/browser/net/node_stream_loader.h",
|
||||
"shell/browser/net/proxying_url_loader_factory.cc",
|
||||
"shell/browser/net/proxying_url_loader_factory.h",
|
||||
"shell/browser/net/proxying_websocket.cc",
|
||||
"shell/browser/net/proxying_websocket.h",
|
||||
"shell/browser/net/resolve_proxy_helper.cc",
|
||||
"shell/browser/net/resolve_proxy_helper.h",
|
||||
"shell/browser/net/system_network_context_manager.cc",
|
||||
"shell/browser/net/system_network_context_manager.h",
|
||||
"shell/browser/net/url_pipe_loader.cc",
|
||||
"shell/browser/net/url_pipe_loader.h",
|
||||
"shell/browser/net/web_request_api_interface.h",
|
||||
"shell/browser/network_hints_handler_impl.cc",
|
||||
"shell/browser/network_hints_handler_impl.h",
|
||||
"shell/browser/node_debugger.cc",
|
||||
@@ -276,6 +279,8 @@ filenames = {
|
||||
"shell/browser/notifications/win/win32_notification.h",
|
||||
"shell/browser/notifications/win/windows_toast_notification.cc",
|
||||
"shell/browser/notifications/win/windows_toast_notification.h",
|
||||
"shell/browser/plugins/plugin_utils.cc",
|
||||
"shell/browser/plugins/plugin_utils.h",
|
||||
"shell/browser/pref_store_delegate.cc",
|
||||
"shell/browser/pref_store_delegate.h",
|
||||
"shell/browser/relauncher.cc",
|
||||
@@ -551,6 +556,7 @@ filenames = {
|
||||
"shell/common/skia_util.h",
|
||||
"shell/common/v8_value_converter.cc",
|
||||
"shell/common/v8_value_converter.h",
|
||||
"shell/common/world_ids.h",
|
||||
"shell/renderer/api/context_bridge/render_frame_context_bridge_store.cc",
|
||||
"shell/renderer/api/context_bridge/render_frame_context_bridge_store.h",
|
||||
"shell/renderer/api/electron_api_context_bridge.cc",
|
||||
@@ -591,14 +597,18 @@ filenames = {
|
||||
]
|
||||
|
||||
lib_sources_extensions = [
|
||||
"shell/browser/extensions/api/resources_private/resources_private_api.cc",
|
||||
"shell/browser/extensions/api/resources_private/resources_private_api.h",
|
||||
"shell/browser/extensions/api/runtime/electron_runtime_api_delegate.cc",
|
||||
"shell/browser/extensions/api/runtime/electron_runtime_api_delegate.h",
|
||||
"shell/browser/extensions/api/tabs/tabs_api.cc",
|
||||
"shell/browser/extensions/api/tabs/tabs_api.h",
|
||||
"shell/browser/extensions/electron_extensions_browser_client.cc",
|
||||
"shell/browser/extensions/electron_extensions_browser_client.h",
|
||||
"shell/browser/extensions/api/streams_private/streams_private_api.cc",
|
||||
"shell/browser/extensions/api/streams_private/streams_private_api.h",
|
||||
"shell/browser/extensions/electron_browser_context_keyed_service_factories.cc",
|
||||
"shell/browser/extensions/electron_browser_context_keyed_service_factories.h",
|
||||
"shell/browser/extensions/electron_component_extension_resource_manager.cc",
|
||||
"shell/browser/extensions/electron_component_extension_resource_manager.h",
|
||||
"shell/browser/extensions/electron_display_info_provider.cc",
|
||||
"shell/browser/extensions/electron_display_info_provider.h",
|
||||
"shell/browser/extensions/electron_extension_host_delegate.cc",
|
||||
@@ -611,24 +621,26 @@ filenames = {
|
||||
"shell/browser/extensions/electron_extension_system_factory.h",
|
||||
"shell/browser/extensions/electron_extension_web_contents_observer.cc",
|
||||
"shell/browser/extensions/electron_extension_web_contents_observer.h",
|
||||
"shell/browser/extensions/electron_navigation_ui_data.cc",
|
||||
"shell/browser/extensions/electron_navigation_ui_data.h",
|
||||
"shell/browser/extensions/electron_process_manager_delegate.cc",
|
||||
"shell/browser/extensions/electron_process_manager_delegate.h",
|
||||
"shell/browser/extensions/electron_extensions_api_client.cc",
|
||||
"shell/browser/extensions/electron_extensions_api_client.h",
|
||||
"shell/browser/extensions/electron_extensions_browser_api_provider.cc",
|
||||
"shell/browser/extensions/electron_extensions_browser_api_provider.h",
|
||||
"shell/browser/extensions/electron_extensions_browser_client.cc",
|
||||
"shell/browser/extensions/electron_extensions_browser_client.h",
|
||||
"shell/browser/extensions/electron_messaging_delegate.cc",
|
||||
"shell/browser/extensions/electron_messaging_delegate.h",
|
||||
"shell/browser/extensions/electron_navigation_ui_data.cc",
|
||||
"shell/browser/extensions/electron_navigation_ui_data.h",
|
||||
"shell/browser/extensions/electron_process_manager_delegate.cc",
|
||||
"shell/browser/extensions/electron_process_manager_delegate.h",
|
||||
"shell/common/extensions/electron_extensions_api_provider.cc",
|
||||
"shell/common/extensions/electron_extensions_api_provider.h",
|
||||
"shell/common/extensions/electron_extensions_client.cc",
|
||||
"shell/common/extensions/electron_extensions_client.h",
|
||||
"shell/renderer/extensions/electron_extensions_renderer_client.cc",
|
||||
"shell/renderer/extensions/electron_extensions_renderer_client.h",
|
||||
"shell/renderer/extensions/electron_extensions_dispatcher_delegate.cc",
|
||||
"shell/renderer/extensions/electron_extensions_dispatcher_delegate.h",
|
||||
"shell/renderer/extensions/electron_extensions_renderer_client.cc",
|
||||
"shell/renderer/extensions/electron_extensions_renderer_client.h",
|
||||
]
|
||||
|
||||
app_sources = [
|
||||
|
||||
@@ -18,8 +18,10 @@ require('@electron/internal/common/init')
|
||||
if (process.platform === 'win32') {
|
||||
// Redirect node's console to use our own implementations, since node can not
|
||||
// handle console output when running as GUI program.
|
||||
const consoleLog = (format: any, ...args: any[]) => {
|
||||
return process.log(util.format(format, ...args) + '\n')
|
||||
const consoleLog = (...args: any[]) => {
|
||||
// @ts-ignore this typing is incorrect; 'format' is an optional parameter
|
||||
// See https://nodejs.org/api/util.html#util_util_format_format_args
|
||||
return process.log(util.format(...args) + '\n')
|
||||
}
|
||||
const streamWrite: NodeJS.WritableStream['write'] = function (chunk: Buffer | string, encoding?: any, callback?: Function) {
|
||||
if (Buffer.isBuffer(chunk)) {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
const binding = process.electronBinding('crash_reporter')
|
||||
|
||||
class CrashReporter {
|
||||
contructor () {
|
||||
constructor () {
|
||||
this.productName = null
|
||||
this.crashesDirectory = null
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@ const remoteObjectCache = v8Util.createIDWeakMap()
|
||||
const contextId = v8Util.getHiddenValue(global, 'contextId')
|
||||
|
||||
ipcRendererInternal.invoke('ELECTRON_BROWSER_GET_LAST_WEB_PREFERENCES').then(preferences => {
|
||||
console.log(preferences)
|
||||
if (!preferences.enableRemoteModule) {
|
||||
console.warn('%cElectron Deprecation Warning', 'font-weight: bold', "The 'remote' module is deprecated and will be disabled by default in a future version of Electron. To ensure a smooth upgrade and silence this warning, specify {enableRemoteModule: true} in the WebPreferences for this window.")
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "electron",
|
||||
"version": "9.0.0-nightly.20200205",
|
||||
"version": "9.0.0-beta.3",
|
||||
"repository": "https://github.com/electron/electron",
|
||||
"description": "Build cross platform desktop apps with JavaScript, HTML, and CSS",
|
||||
"devDependencies": {
|
||||
|
||||
@@ -31,11 +31,12 @@ scroll_bounce_flag.patch
|
||||
mas-cfisobjc.patch
|
||||
mas-cgdisplayusesforcetogray.patch
|
||||
mas-audiodeviceduck.patch
|
||||
mas_disable_remote_layer.patch
|
||||
mas_disable_remote_accessibility.patch
|
||||
mas_disable_custom_window_frame.patch
|
||||
chrome_key_systems.patch
|
||||
allow_nested_error_trackers.patch
|
||||
blink_initialization_order.patch
|
||||
add_didinstallconditionalfeatures.patch
|
||||
ssl_security_state_tab_helper.patch
|
||||
desktop_media_list.patch
|
||||
proxy_config_monitor.patch
|
||||
@@ -81,3 +82,6 @@ feat_allow_disabling_blink_scheduler_throttling_per_renderview.patch
|
||||
accessible_pane_view.patch
|
||||
fixme_grit_conflicts.patch
|
||||
fix_use_the_new_mediaplaypause_key_listener_for_internal_chrome.patch
|
||||
use_electron_resources_in_pdf_util.patch
|
||||
hack_plugin_response_interceptor_to_point_to_electron.patch
|
||||
fix_route_mouse_event_navigations_through_the_web_contents_delegate.patch
|
||||
|
||||
137
patches/chromium/add_didinstallconditionalfeatures.patch
Normal file
137
patches/chromium/add_didinstallconditionalfeatures.patch
Normal file
@@ -0,0 +1,137 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jeremy Apthorp <nornagon@nornagon.net>
|
||||
Date: Wed, 15 Jan 2020 16:35:18 -0800
|
||||
Subject: add DidInstallConditionalFeatures
|
||||
|
||||
This adds a hook on script context creation _after conditional features
|
||||
have been installed_. Electron uses this to run preload scripts and
|
||||
various other initialization. This is necessary because at the time
|
||||
DidCreateScriptContext is called, not all JS APIs are available in the
|
||||
context, which can cause some preload scripts to trip.
|
||||
|
||||
diff --git a/content/public/renderer/render_frame_observer.h b/content/public/renderer/render_frame_observer.h
|
||||
index 68654a3e7d5ec6caddccb667f9f8fa2feabfa71b..650ce53e112bd65e1901a09480452855a0c16dda 100644
|
||||
--- a/content/public/renderer/render_frame_observer.h
|
||||
+++ b/content/public/renderer/render_frame_observer.h
|
||||
@@ -115,6 +115,8 @@ class CONTENT_EXPORT RenderFrameObserver : public IPC::Listener,
|
||||
virtual void DidHandleOnloadEvents() {}
|
||||
virtual void DidCreateScriptContext(v8::Local<v8::Context> context,
|
||||
int32_t world_id) {}
|
||||
+ virtual void DidInstallConditionalFeatures(v8::Local<v8::Context> context,
|
||||
+ int32_t world_id) {}
|
||||
virtual void WillReleaseScriptContext(v8::Local<v8::Context> context,
|
||||
int32_t world_id) {}
|
||||
virtual void DidClearWindowObject() {}
|
||||
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
|
||||
index 6730d6f6eb8448452991ebf5968a8c5a398b6a88..b87f9c7ac0f31ec33f03c36131c3255c8a31c22c 100644
|
||||
--- a/content/renderer/render_frame_impl.cc
|
||||
+++ b/content/renderer/render_frame_impl.cc
|
||||
@@ -5187,6 +5187,12 @@ void RenderFrameImpl::DidCreateScriptContext(v8::Local<v8::Context> context,
|
||||
observer.DidCreateScriptContext(context, world_id);
|
||||
}
|
||||
|
||||
+void RenderFrameImpl::DidInstallConditionalFeatures(
|
||||
+ v8::Local<v8::Context> context, int world_id) {
|
||||
+ for (auto& observer : observers_)
|
||||
+ observer.DidInstallConditionalFeatures(context, world_id);
|
||||
+}
|
||||
+
|
||||
void RenderFrameImpl::WillReleaseScriptContext(v8::Local<v8::Context> context,
|
||||
int world_id) {
|
||||
for (auto& observer : observers_)
|
||||
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h
|
||||
index bc896201057832415b5d54dc8987bb74bf7aa778..5c96af71646722b1108a8d6eafba1adaddf0a05a 100644
|
||||
--- a/content/renderer/render_frame_impl.h
|
||||
+++ b/content/renderer/render_frame_impl.h
|
||||
@@ -773,6 +773,8 @@ class CONTENT_EXPORT RenderFrameImpl
|
||||
bool ShouldTrackUseCounter(const blink::WebURL& url) override;
|
||||
void DidCreateScriptContext(v8::Local<v8::Context> context,
|
||||
int world_id) override;
|
||||
+ void DidInstallConditionalFeatures(v8::Local<v8::Context> context,
|
||||
+ int world_id) override;
|
||||
void WillReleaseScriptContext(v8::Local<v8::Context> context,
|
||||
int world_id) override;
|
||||
void DidChangeScrollOffset() override;
|
||||
diff --git a/third_party/blink/public/web/web_local_frame_client.h b/third_party/blink/public/web/web_local_frame_client.h
|
||||
index 30638c31e30d98bb23292115b25b528ff8e8f62c..e0f2f786b75f861851d1194f57b253a173053299 100644
|
||||
--- a/third_party/blink/public/web/web_local_frame_client.h
|
||||
+++ b/third_party/blink/public/web/web_local_frame_client.h
|
||||
@@ -652,6 +652,9 @@ class BLINK_EXPORT WebLocalFrameClient {
|
||||
virtual void DidCreateScriptContext(v8::Local<v8::Context>,
|
||||
int32_t world_id) {}
|
||||
|
||||
+ virtual void DidInstallConditionalFeatures(v8::Local<v8::Context>,
|
||||
+ int32_t world_id) {}
|
||||
+
|
||||
// WebKit is about to release its reference to a v8 context for a frame.
|
||||
virtual void WillReleaseScriptContext(v8::Local<v8::Context>,
|
||||
int32_t world_id) {}
|
||||
diff --git a/third_party/blink/renderer/bindings/core/v8/local_window_proxy.cc b/third_party/blink/renderer/bindings/core/v8/local_window_proxy.cc
|
||||
index 8095edd988c171a8ad7382d1c2f9fa63ee9e5ffc..510dae593d2a0e2ce13a2879dde5c31e01d21c21 100644
|
||||
--- a/third_party/blink/renderer/bindings/core/v8/local_window_proxy.cc
|
||||
+++ b/third_party/blink/renderer/bindings/core/v8/local_window_proxy.cc
|
||||
@@ -231,6 +231,7 @@ void LocalWindowProxy::Initialize() {
|
||||
}
|
||||
|
||||
InstallConditionalFeatures();
|
||||
+ GetFrame()->Client()->DidInstallConditionalFeatures(context, world_->GetWorldId());
|
||||
|
||||
if (World().IsMainWorld()) {
|
||||
GetFrame()->Loader().DispatchDidClearWindowObjectInMainWorld();
|
||||
diff --git a/third_party/blink/renderer/core/exported/local_frame_client_impl.cc b/third_party/blink/renderer/core/exported/local_frame_client_impl.cc
|
||||
index f8c512c9db0b88904a562b7d4195790d4b0f86a6..d31ef9bd5b98f584a3296638662ae0d27aa37b65 100644
|
||||
--- a/third_party/blink/renderer/core/exported/local_frame_client_impl.cc
|
||||
+++ b/third_party/blink/renderer/core/exported/local_frame_client_impl.cc
|
||||
@@ -267,6 +267,13 @@ void LocalFrameClientImpl::DidCreateScriptContext(
|
||||
web_frame_->Client()->DidCreateScriptContext(context, world_id);
|
||||
}
|
||||
|
||||
+void LocalFrameClientImpl::DidInstallConditionalFeatures(
|
||||
+ v8::Local<v8::Context> context,
|
||||
+ int32_t world_id) {
|
||||
+ if (web_frame_->Client())
|
||||
+ web_frame_->Client()->DidInstallConditionalFeatures(context, world_id);
|
||||
+}
|
||||
+
|
||||
void LocalFrameClientImpl::WillReleaseScriptContext(
|
||||
v8::Local<v8::Context> context,
|
||||
int32_t world_id) {
|
||||
diff --git a/third_party/blink/renderer/core/exported/local_frame_client_impl.h b/third_party/blink/renderer/core/exported/local_frame_client_impl.h
|
||||
index a055f4b0cc1ccc30752b65d6dc54e638e9b63001..0e6501adbf6f9696429c3fa95357de399ee30a9d 100644
|
||||
--- a/third_party/blink/renderer/core/exported/local_frame_client_impl.h
|
||||
+++ b/third_party/blink/renderer/core/exported/local_frame_client_impl.h
|
||||
@@ -79,6 +79,8 @@ class LocalFrameClientImpl final : public LocalFrameClient {
|
||||
|
||||
void DidCreateScriptContext(v8::Local<v8::Context>,
|
||||
int32_t world_id) override;
|
||||
+ void DidInstallConditionalFeatures(v8::Local<v8::Context>,
|
||||
+ int32_t world_id) override;
|
||||
void WillReleaseScriptContext(v8::Local<v8::Context>,
|
||||
int32_t world_id) override;
|
||||
|
||||
diff --git a/third_party/blink/renderer/core/frame/local_frame_client.h b/third_party/blink/renderer/core/frame/local_frame_client.h
|
||||
index 1d6facb9ec63abebc5b79a57860765bc8b3f6638..0b58cb679ed34c54e39af661d4a432d482db8c3c 100644
|
||||
--- a/third_party/blink/renderer/core/frame/local_frame_client.h
|
||||
+++ b/third_party/blink/renderer/core/frame/local_frame_client.h
|
||||
@@ -303,6 +303,8 @@ class CORE_EXPORT LocalFrameClient : public FrameClient {
|
||||
|
||||
virtual void DidCreateScriptContext(v8::Local<v8::Context>,
|
||||
int32_t world_id) = 0;
|
||||
+ virtual void DidInstallConditionalFeatures(v8::Local<v8::Context>,
|
||||
+ int32_t world_id) = 0;
|
||||
virtual void WillReleaseScriptContext(v8::Local<v8::Context>,
|
||||
int32_t world_id) = 0;
|
||||
virtual bool AllowScriptExtensions() = 0;
|
||||
diff --git a/third_party/blink/renderer/core/loader/empty_clients.h b/third_party/blink/renderer/core/loader/empty_clients.h
|
||||
index f3f00e7d6ac44d77dd75997abf8b93eb59476eb3..2010792697b3443dd6f5058bed5ccd0026c4a152 100644
|
||||
--- a/third_party/blink/renderer/core/loader/empty_clients.h
|
||||
+++ b/third_party/blink/renderer/core/loader/empty_clients.h
|
||||
@@ -370,6 +370,8 @@ class CORE_EXPORT EmptyLocalFrameClient : public LocalFrameClient {
|
||||
|
||||
void DidCreateScriptContext(v8::Local<v8::Context>,
|
||||
int32_t world_id) override {}
|
||||
+ void DidInstallConditionalFeatures(v8::Local<v8::Context>,
|
||||
+ int32_t world_id) override {}
|
||||
void WillReleaseScriptContext(v8::Local<v8::Context>,
|
||||
int32_t world_id) override {}
|
||||
bool AllowScriptExtensions() override { return false; }
|
||||
@@ -1,28 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Samuel Attard <samuel.r.attard@gmail.com>
|
||||
Date: Thu, 20 Sep 2018 17:50:24 -0700
|
||||
Subject: blink_initialization_order.patch
|
||||
|
||||
Backport of https://chromium-review.googlesource.com/c/chromium/src/+/1030530
|
||||
to fix the order of V8 and Blink initialization. Also fixes order
|
||||
of DidCreateScriptContext notification with initialization of window globals
|
||||
to fix electron/electron#13787. The backport landed in Chromium 67 but the
|
||||
DidCreateScriptContext re-ordering needs to be upstreamed or kept indefinitely
|
||||
|
||||
diff --git a/third_party/blink/renderer/bindings/core/v8/local_window_proxy.cc b/third_party/blink/renderer/bindings/core/v8/local_window_proxy.cc
|
||||
index c845acb8321e94c916798826a168e06df34ffff4..941ca9d3905c0c2f36606655bf60e9e9bd1f9196 100644
|
||||
--- a/third_party/blink/renderer/bindings/core/v8/local_window_proxy.cc
|
||||
+++ b/third_party/blink/renderer/bindings/core/v8/local_window_proxy.cc
|
||||
@@ -211,11 +211,10 @@ void LocalWindowProxy::Initialize() {
|
||||
GetFrame()->IsMainFrame());
|
||||
MainThreadDebugger::Instance()->ContextCreated(script_state_, GetFrame(),
|
||||
origin);
|
||||
+ InstallConditionalFeatures();
|
||||
GetFrame()->Client()->DidCreateScriptContext(context, world_->GetWorldId());
|
||||
}
|
||||
|
||||
- InstallConditionalFeatures();
|
||||
-
|
||||
if (World().IsMainWorld()) {
|
||||
GetFrame()->Loader().DispatchDidClearWindowObjectInMainWorld();
|
||||
}
|
||||
@@ -6,6 +6,18 @@ Subject: chore: use electron resources not chrome for spellchecker
|
||||
spellchecker uses a few IDS_ resources. We need to load these from
|
||||
Electrons grit header instead of Chromes
|
||||
|
||||
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
|
||||
index d730660c086f..ba9b098d848e 100644
|
||||
--- a/chrome/browser/BUILD.gn
|
||||
+++ b/chrome/browser/BUILD.gn
|
||||
@@ -5049,6 +5049,7 @@ jumbo_split_static_library("browser") {
|
||||
deps += [
|
||||
"//components/spellcheck/browser",
|
||||
"//components/spellcheck/common",
|
||||
+ "//electron:resources",
|
||||
]
|
||||
|
||||
if (!is_android) {
|
||||
diff --git a/chrome/browser/spellchecker/spellcheck_factory.cc b/chrome/browser/spellchecker/spellcheck_factory.cc
|
||||
index 48ac0a24efde0cb7d3ba71c8b8bdf5178f606e80..e2beefc276098fdc8f1cdab2e0edb8fae4ee67ca 100644
|
||||
--- a/chrome/browser/spellchecker/spellcheck_factory.cc
|
||||
@@ -19,6 +31,18 @@ index 48ac0a24efde0cb7d3ba71c8b8bdf5178f606e80..e2beefc276098fdc8f1cdab2e0edb8fa
|
||||
#include "components/keyed_service/content/browser_context_dependency_manager.h"
|
||||
#include "components/pref_registry/pref_registry_syncable.h"
|
||||
#include "components/prefs/pref_service.h"
|
||||
diff --git a/components/language/core/browser/BUILD.gn b/components/language/core/browser/BUILD.gn
|
||||
index f28230ea94fe..c10eea103852 100644
|
||||
--- a/components/language/core/browser/BUILD.gn
|
||||
+++ b/components/language/core/browser/BUILD.gn
|
||||
@@ -31,6 +31,7 @@ static_library("browser") {
|
||||
"//components/pref_registry",
|
||||
"//components/prefs",
|
||||
"//components/strings",
|
||||
+ "//electron:resources",
|
||||
"//ui/base",
|
||||
]
|
||||
}
|
||||
diff --git a/components/language/core/browser/language_prefs.cc b/components/language/core/browser/language_prefs.cc
|
||||
index 7e06f689632ae67e3e17d7985c6e7b6ea0057f3c..0b4676f4c40b4a0eda927a51016ec91ec230291d 100644
|
||||
--- a/components/language/core/browser/language_prefs.cc
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Samuel Attard <sattard@slack-corp.com>
|
||||
Date: Fri, 14 Feb 2020 13:35:47 -0800
|
||||
Subject: fix: route mouse event navigations through the web_contents delegate
|
||||
|
||||
This ensures that embedders can handle browser-side mouse navigations
|
||||
themselves. We need this so that we can correctly ensure that processes
|
||||
are not restarted for in-document navigations.
|
||||
|
||||
Refs: https://chromium-review.googlesource.com/c/chromium/src/+/1769525
|
||||
|
||||
This patch can be removed once app.allowRendererProcessReuse is forced
|
||||
to true as then Chromiums assumptions around processes become correct.
|
||||
|
||||
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
|
||||
index 70d735dcc38734edaaf6221cd40c49beb6d2e37e..9cd7368966c20b9e9306c41e455c002d686d3013 100644
|
||||
--- a/content/browser/web_contents/web_contents_impl.cc
|
||||
+++ b/content/browser/web_contents/web_contents_impl.cc
|
||||
@@ -2347,11 +2347,13 @@ bool WebContentsImpl::HandleMouseEvent(const blink::WebMouseEvent& event) {
|
||||
WebContentsImpl* outermost = GetOutermostWebContents();
|
||||
if (event.button == blink::WebPointerProperties::Button::kBack &&
|
||||
outermost->controller_.CanGoBack()) {
|
||||
- outermost->controller_.GoBack();
|
||||
+ if (delegate_->OnGoToEntryOffset(-1))
|
||||
+ outermost->controller_.GoBack();
|
||||
return true;
|
||||
} else if (event.button == blink::WebPointerProperties::Button::kForward &&
|
||||
outermost->controller_.CanGoForward()) {
|
||||
- outermost->controller_.GoForward();
|
||||
+ if (delegate_->OnGoToEntryOffset(1))
|
||||
+ outermost->controller_.GoForward();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jeremy Apthorp <nornagon@nornagon.net>
|
||||
Date: Mon, 10 Feb 2020 11:52:23 -0800
|
||||
Subject: hack plugin response interceptor to point to electron
|
||||
|
||||
chrome's streams_private_api does prerender and other things and would
|
||||
require a largeish patch to get working, so just redirect it to our
|
||||
implementation instead.
|
||||
|
||||
diff --git a/chrome/browser/plugins/plugin_response_interceptor_url_loader_throttle.cc b/chrome/browser/plugins/plugin_response_interceptor_url_loader_throttle.cc
|
||||
index 1c9aeb8fa71d054159c2ccccccbe57aa474d417e..0bd6412f2c79f77f936720b1a0795b50ecefd26c 100644
|
||||
--- a/chrome/browser/plugins/plugin_response_interceptor_url_loader_throttle.cc
|
||||
+++ b/chrome/browser/plugins/plugin_response_interceptor_url_loader_throttle.cc
|
||||
@@ -8,8 +8,8 @@
|
||||
#include "base/feature_list.h"
|
||||
#include "base/guid.h"
|
||||
#include "base/task/post_task.h"
|
||||
-#include "chrome/browser/extensions/api/streams_private/streams_private_api.h"
|
||||
-#include "chrome/browser/plugins/plugin_utils.h"
|
||||
+#include "electron/shell/browser/extensions/api/streams_private/streams_private_api.h"
|
||||
+#include "electron/shell/browser/plugins/plugin_utils.h"
|
||||
#include "content/public/browser/browser_task_traits.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/download_utils.h"
|
||||
137
patches/chromium/mas_disable_remote_layer.patch
Normal file
137
patches/chromium/mas_disable_remote_layer.patch
Normal file
@@ -0,0 +1,137 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Cheng Zhao <zcbenz@gmail.com>
|
||||
Date: Thu, 20 Sep 2018 17:48:49 -0700
|
||||
Subject: mas_disable_remote_layer.patch
|
||||
|
||||
Disable remote layer APIs (CAContext and CALayerHost) for MAS build.
|
||||
|
||||
Accordin to ccameron:
|
||||
|
||||
For apps that spend a lot of time watching video (especially fullscreen video),
|
||||
the power/battery usage will likely increase 1.5x to 2x. For something that is,
|
||||
e.g, scrolling, it'll be smaller, more like 1.15x or 1.25x.
|
||||
|
||||
In terms of performance, the impact will likely be fairly small -- any app that
|
||||
could hit 60fps before will likely still be able to hit 60fps. There may even be
|
||||
cases where performance improves when disabling remote CoreAnimation (remote
|
||||
CoreAnimation is really only about battery usage).
|
||||
|
||||
diff --git a/gpu/ipc/service/image_transport_surface_overlay_mac.mm b/gpu/ipc/service/image_transport_surface_overlay_mac.mm
|
||||
index c1af03a268dc..b883883ad52b 100644
|
||||
--- a/gpu/ipc/service/image_transport_surface_overlay_mac.mm
|
||||
+++ b/gpu/ipc/service/image_transport_surface_overlay_mac.mm
|
||||
@@ -63,6 +63,7 @@
|
||||
template <typename BaseClass>
|
||||
bool ImageTransportSurfaceOverlayMacBase<BaseClass>::Initialize(
|
||||
gl::GLSurfaceFormat format) {
|
||||
+#ifndef MAS_BUILD
|
||||
// Create the CAContext to send this to the GPU process, and the layer for
|
||||
// the context.
|
||||
if (use_remote_layer_api_) {
|
||||
@@ -71,6 +72,7 @@
|
||||
[CAContext contextWithCGSConnection:connection_id options:@{}] retain]);
|
||||
[ca_context_ setLayer:ca_layer_tree_coordinator_->GetCALayerForDisplay()];
|
||||
}
|
||||
+#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -139,7 +141,9 @@
|
||||
"GLImpl", static_cast<int>(gl::GetGLImplementation()),
|
||||
"width", pixel_size_.width());
|
||||
if (use_remote_layer_api_) {
|
||||
+#ifndef MAS_BUILD
|
||||
params.ca_layer_params.ca_context_id = [ca_context_ contextId];
|
||||
+#endif
|
||||
} else {
|
||||
IOSurfaceRef io_surface =
|
||||
ca_layer_tree_coordinator_->GetIOSurfaceForDisplay();
|
||||
diff --git a/gpu/ipc/service/image_transport_surface_overlay_mac.h b/gpu/ipc/service/image_transport_surface_overlay_mac.h
|
||||
index f65ad035e90c..9edb62e713e8 100644
|
||||
--- a/gpu/ipc/service/image_transport_surface_overlay_mac.h
|
||||
+++ b/gpu/ipc/service/image_transport_surface_overlay_mac.h
|
||||
@@ -20,7 +20,9 @@
|
||||
#include "ui/gl/gl_surface_egl.h"
|
||||
#endif
|
||||
|
||||
+#ifndef MAS_BUILD
|
||||
@class CAContext;
|
||||
+#endif
|
||||
@class CALayer;
|
||||
|
||||
namespace ui {
|
||||
@@ -97,7 +99,9 @@ class ImageTransportSurfaceOverlayMacBase : public BaseClass,
|
||||
base::WeakPtr<ImageTransportSurfaceDelegate> delegate_;
|
||||
|
||||
bool use_remote_layer_api_;
|
||||
+#ifndef MAS_BUILD
|
||||
base::scoped_nsobject<CAContext> ca_context_;
|
||||
+#endif
|
||||
std::unique_ptr<ui::CALayerTreeCoordinator> ca_layer_tree_coordinator_;
|
||||
|
||||
gfx::Size pixel_size_;
|
||||
diff --git a/ui/accelerated_widget_mac/display_ca_layer_tree.mm b/ui/accelerated_widget_mac/display_ca_layer_tree.mm
|
||||
index 60abe639bd9c..c38eed5fbdef 100644
|
||||
--- a/ui/accelerated_widget_mac/display_ca_layer_tree.mm
|
||||
+++ b/ui/accelerated_widget_mac/display_ca_layer_tree.mm
|
||||
@@ -98,6 +98,7 @@ - (void)setContentsChanged;
|
||||
}
|
||||
|
||||
void DisplayCALayerTree::GotCALayerFrame(uint32_t ca_context_id) {
|
||||
+#ifndef MAS_BUILD
|
||||
// Early-out if the remote layer has not changed.
|
||||
if ([remote_layer_ contextId] == ca_context_id)
|
||||
return;
|
||||
@@ -122,6 +123,9 @@ - (void)setContentsChanged;
|
||||
[io_surface_layer_ removeFromSuperlayer];
|
||||
io_surface_layer_.reset();
|
||||
}
|
||||
+#else
|
||||
+ NOTREACHED() << "Remote layer is being used in MAS build";
|
||||
+#endif
|
||||
}
|
||||
|
||||
void DisplayCALayerTree::GotIOSurfaceFrame(
|
||||
diff --git a/ui/base/cocoa/remote_layer_api.h b/ui/base/cocoa/remote_layer_api.h
|
||||
index 2057fe69d1bb..2aba330fc488 100644
|
||||
--- a/ui/base/cocoa/remote_layer_api.h
|
||||
+++ b/ui/base/cocoa/remote_layer_api.h
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
#include "ui/base/ui_base_export.h"
|
||||
|
||||
+#ifndef MAS_BUILD
|
||||
// The CGSConnectionID is used to create the CAContext in the process that is
|
||||
// going to share the CALayers that it is rendering to another process to
|
||||
// display.
|
||||
@@ -50,6 +51,8 @@ typedef uint32_t CAContextID;
|
||||
|
||||
#endif // __OBJC__
|
||||
|
||||
+#endif // MAS_BUILD
|
||||
+
|
||||
namespace ui {
|
||||
|
||||
// This function will check if all of the interfaces listed above are supported
|
||||
diff --git a/ui/base/cocoa/remote_layer_api.mm b/ui/base/cocoa/remote_layer_api.mm
|
||||
index bbaf9f466f49..8c846ce9523a 100644
|
||||
--- a/ui/base/cocoa/remote_layer_api.mm
|
||||
+++ b/ui/base/cocoa/remote_layer_api.mm
|
||||
@@ -12,6 +12,7 @@
|
||||
namespace ui {
|
||||
|
||||
bool RemoteLayerAPISupported() {
|
||||
+#ifndef MAS_BUILD
|
||||
static bool disabled_at_command_line =
|
||||
base::CommandLine::ForCurrentProcess()->HasSwitch(
|
||||
switches::kDisableRemoteCoreAnimation);
|
||||
@@ -46,6 +47,9 @@ bool RemoteLayerAPISupported() {
|
||||
|
||||
// If everything is there, we should be able to use the API.
|
||||
return true;
|
||||
+#else
|
||||
+ return false;
|
||||
+#endif // MAS_BUILD
|
||||
}
|
||||
|
||||
} // namespace
|
||||
22
patches/chromium/use_electron_resources_in_pdf_util.patch
Normal file
22
patches/chromium/use_electron_resources_in_pdf_util.patch
Normal file
@@ -0,0 +1,22 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jeremy Apthorp <nornagon@nornagon.net>
|
||||
Date: Mon, 10 Feb 2020 10:37:48 -0800
|
||||
Subject: use electron resources in pdf_util
|
||||
|
||||
Without this, the ID for IDR_PDF_MANIFEST will be wrong on linux
|
||||
and cause a DCHECK(), since the resource will be loaded as an empty
|
||||
string.
|
||||
|
||||
diff --git a/chrome/browser/pdf/pdf_extension_util.cc b/chrome/browser/pdf/pdf_extension_util.cc
|
||||
index 877d0ba2f48359243527ddebf1d91132b3d5c455..cd69de498c4968ade0ffabf45b72d4d63b70b10f 100644
|
||||
--- a/chrome/browser/pdf/pdf_extension_util.cc
|
||||
+++ b/chrome/browser/pdf/pdf_extension_util.cc
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
#include "base/strings/string_util.h"
|
||||
#include "chrome/common/chrome_content_client.h"
|
||||
-#include "chrome/grit/browser_resources.h"
|
||||
+#include "electron/grit/electron_resources.h"
|
||||
#include "ui/base/resource/resource_bundle.h"
|
||||
|
||||
namespace pdf_extension_util {
|
||||
@@ -9,7 +9,11 @@ async function checkIfDocOnlyChange () {
|
||||
try {
|
||||
let pullRequestNumber = args.prNumber
|
||||
if (!pullRequestNumber || isNaN(pullRequestNumber)) {
|
||||
if (args.prBranch) {
|
||||
if (args.prURL) {
|
||||
// CircleCI doesn't provide the PR number for branch builds, but it does provide the PR URL
|
||||
const pullRequestParts = args.prURL.split('/')
|
||||
pullRequestNumber = pullRequestParts[pullRequestParts.length - 1]
|
||||
} else if (args.prBranch) {
|
||||
// AppVeyor doesn't provide a PR number for branch builds - figure it out from the branch
|
||||
const prsForBranch = await octokit.pulls.list({
|
||||
owner: 'electron',
|
||||
@@ -23,10 +27,6 @@ async function checkIfDocOnlyChange () {
|
||||
// If there are 0 PRs or more than one PR on a branch, just assume that this is more than a doc change
|
||||
process.exit(1)
|
||||
}
|
||||
} else if (args.prURL) {
|
||||
// CircleCI doesn't provide the PR number for branch builds, but it does provide the PR URL
|
||||
const pullRequestParts = args.prURL.split('/')
|
||||
pullRequestNumber = pullRequestParts[pullRequestParts.length - 1]
|
||||
}
|
||||
}
|
||||
const filesChanged = await octokit.pulls.listFiles({
|
||||
|
||||
@@ -120,8 +120,8 @@ def extract_zip(zip_path, destination):
|
||||
def make_zip(zip_file_path, files, dirs):
|
||||
safe_unlink(zip_file_path)
|
||||
if sys.platform == 'darwin':
|
||||
files += dirs
|
||||
execute(['zip', '-r', '-y', zip_file_path] + files)
|
||||
allfiles = files + dirs
|
||||
execute(['zip', '-r', '-y', zip_file_path] + allfiles)
|
||||
else:
|
||||
zip_file = zipfile.ZipFile(zip_file_path, "w", zipfile.ZIP_DEFLATED,
|
||||
allowZip64=True)
|
||||
|
||||
@@ -2,10 +2,16 @@ const cp = require('child_process')
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
|
||||
const args = require('minimist')(process.argv.slice(2), {
|
||||
boolean: ['default'],
|
||||
string: ['jUnitDir']
|
||||
})
|
||||
|
||||
const BASE = path.resolve(__dirname, '../..')
|
||||
const DISABLED_TESTS = require('./node-disabled-tests.json')
|
||||
const NODE_DIR = path.resolve(BASE, 'third_party', 'electron_node')
|
||||
const NPX_CMD = process.platform === 'win32' ? 'npx.cmd' : 'npx'
|
||||
const JUNIT_DIR = process.argv[2] ? path.resolve(process.argv[2]) : null
|
||||
const JUNIT_DIR = args.jUnitDir ? path.resolve(args.jUnitDir) : null
|
||||
const TAP_FILE_NAME = 'test.tap'
|
||||
|
||||
const utils = require('./lib/utils')
|
||||
@@ -15,10 +21,43 @@ if (!process.mainModule) {
|
||||
throw new Error('Must call the node spec runner directly')
|
||||
}
|
||||
|
||||
async function main () {
|
||||
const DISABLED_TESTS = require('./node-disabled-tests.json')
|
||||
const defaultOptions = [
|
||||
'tools/test.py',
|
||||
'-p',
|
||||
'tap',
|
||||
'--logfile',
|
||||
TAP_FILE_NAME,
|
||||
'--mode=debug',
|
||||
'default',
|
||||
`--skip-tests=${DISABLED_TESTS.join(',')}`,
|
||||
'--shell',
|
||||
utils.getAbsoluteElectronExec(),
|
||||
'-J'
|
||||
]
|
||||
|
||||
const testChild = cp.spawn('python', ['tools/test.py', '--verbose', '-p', 'tap', '--logfile', TAP_FILE_NAME, '--mode=debug', 'default', `--skip-tests=${DISABLED_TESTS.join(',')}`, '--shell', utils.getAbsoluteElectronExec(), '-J'], {
|
||||
const getCustomOptions = () => {
|
||||
let customOptions = ['tools/test.py']
|
||||
|
||||
// Add all custom arguments.
|
||||
const extra = process.argv.slice(2)
|
||||
if (extra) {
|
||||
customOptions = customOptions.concat(extra)
|
||||
}
|
||||
|
||||
// We need this unilaterally or Node.js will try
|
||||
// to run from out/Release/node.
|
||||
customOptions = customOptions.concat([
|
||||
'--shell',
|
||||
utils.getAbsoluteElectronExec()
|
||||
])
|
||||
|
||||
return customOptions
|
||||
}
|
||||
|
||||
async function main () {
|
||||
const options = args.default ? defaultOptions : getCustomOptions()
|
||||
|
||||
const testChild = cp.spawn('python', options, {
|
||||
env: {
|
||||
...process.env,
|
||||
ELECTRON_RUN_AS_NODE: 'true',
|
||||
|
||||
@@ -23,6 +23,11 @@ const circleCIJobs = [
|
||||
'osx-publish'
|
||||
]
|
||||
|
||||
const circleCIPublishWorkflows = [
|
||||
'linux-publish',
|
||||
'macos-publish'
|
||||
]
|
||||
|
||||
const vstsArmJobs = [
|
||||
'electron-arm-testing',
|
||||
'electron-arm64-testing',
|
||||
@@ -87,13 +92,18 @@ async function circleCIcall (targetBranch, job, options) {
|
||||
if (workflowId === -1) {
|
||||
return
|
||||
}
|
||||
console.log(`CircleCI release build workflow running at https://circleci.com/workflow-run/${workflowId} for ${job}.`)
|
||||
const jobNumber = await getCircleCIJobNumber(workflowId)
|
||||
if (jobNumber === -1) {
|
||||
return
|
||||
const workFlowUrl = `https://circleci.com/workflow-run/${workflowId}`
|
||||
if (options.runningPublishWorkflows) {
|
||||
console.log(`CircleCI release workflow request for ${job} successful. Check ${workFlowUrl} for status.`)
|
||||
} else {
|
||||
console.log(`CircleCI release build workflow running at https://circleci.com/workflow-run/${workflowId} for ${job}.`)
|
||||
const jobNumber = await getCircleCIJobNumber(workflowId)
|
||||
if (jobNumber === -1) {
|
||||
return
|
||||
}
|
||||
const jobUrl = `https://circleci.com/gh/electron/electron/${jobNumber}`
|
||||
console.log(`CircleCI release build request for ${job} successful. Check ${jobUrl} for status.`)
|
||||
}
|
||||
const jobUrl = `https://circleci.com/gh/electron/electron/${jobNumber}`
|
||||
console.log(`CircleCI release build request for ${job} successful. Check ${jobUrl} for status.`)
|
||||
} catch (err) {
|
||||
console.log('Error calling CircleCI: ', err)
|
||||
}
|
||||
@@ -232,7 +242,8 @@ function buildCircleCI (targetBranch, options) {
|
||||
assert(circleCIJobs.includes(options.job), `Unknown CircleCI job name: ${options.job}. Valid values are: ${circleCIJobs}.`)
|
||||
circleCIcall(targetBranch, options.job, options)
|
||||
} else {
|
||||
circleCIJobs.forEach((job) => circleCIcall(targetBranch, job, options))
|
||||
options.runningPublishWorkflows = true
|
||||
circleCIPublishWorkflows.forEach((job) => circleCIcall(targetBranch, job, options))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ const CHECK_INTERVAL = 5000
|
||||
|
||||
const CACHE_DIR = path.resolve(__dirname, '.cache')
|
||||
const NO_NOTES = 'No notes'
|
||||
const FOLLOW_REPOS = [ 'electron/electron', 'electron/libchromiumcontent', 'electron/node' ]
|
||||
const FOLLOW_REPOS = [ 'electron/electron', 'electron/node' ]
|
||||
|
||||
const breakTypes = new Set(['breaking-change'])
|
||||
const docTypes = new Set(['doc', 'docs'])
|
||||
@@ -341,44 +341,6 @@ const addRepoToPool = async (pool, repo, from, to) => {
|
||||
**** Other Repos
|
||||
***/
|
||||
|
||||
// other repos - gyp
|
||||
|
||||
const getGypSubmoduleRef = async (dir, point) => {
|
||||
// example: '160000 commit 028b0af83076cec898f4ebce208b7fadb715656e libchromiumcontent'
|
||||
const response = await runGit(
|
||||
path.dirname(dir),
|
||||
['ls-tree', '-t', point, path.basename(dir)]
|
||||
)
|
||||
|
||||
const line = response.split('\n').filter(line => line.startsWith('160000')).shift()
|
||||
const tokens = line ? line.split(/\s/).map(token => token.trim()) : null
|
||||
const ref = tokens && tokens.length >= 3 ? tokens[2] : null
|
||||
|
||||
return ref
|
||||
}
|
||||
|
||||
const getDependencyCommitsGyp = async (pool, fromRef, toRef) => {
|
||||
const commits = []
|
||||
|
||||
const repos = [{
|
||||
owner: 'electron',
|
||||
repo: 'libchromiumcontent',
|
||||
dir: path.resolve(ELECTRON_VERSION, 'vendor', 'libchromiumcontent')
|
||||
}, {
|
||||
owner: 'electron',
|
||||
repo: 'node',
|
||||
dir: path.resolve(ELECTRON_VERSION, 'vendor', 'node')
|
||||
}]
|
||||
|
||||
for (const repo of repos) {
|
||||
const from = await getGypSubmoduleRef(repo.dir, fromRef)
|
||||
const to = await getGypSubmoduleRef(repo.dir, toRef)
|
||||
await addRepoToPool(pool, repo, from, to)
|
||||
}
|
||||
|
||||
return commits
|
||||
}
|
||||
|
||||
// other repos - gn
|
||||
|
||||
const getDepsVariable = async (ref, key) => {
|
||||
@@ -416,17 +378,6 @@ const getDependencyCommitsGN = async (pool, fromRef, toRef) => {
|
||||
}
|
||||
}
|
||||
|
||||
// other repos - controller
|
||||
|
||||
const getDependencyCommits = async (pool, from, to) => {
|
||||
const filename = path.resolve(ELECTRON_VERSION, 'vendor', 'libchromiumcontent')
|
||||
const useGyp = fs.existsSync(filename)
|
||||
|
||||
return useGyp
|
||||
? getDependencyCommitsGyp(pool, from, to)
|
||||
: getDependencyCommitsGN(pool, from, to)
|
||||
}
|
||||
|
||||
// Changes are interesting if they make a change relative to a previous
|
||||
// release in the same series. For example if you fix a Y.0.0 bug, that
|
||||
// should be included in the Y.0.1 notes even if it's also tropped back
|
||||
@@ -474,7 +425,7 @@ const getNotes = async (fromRef, toRef, newVersion) => {
|
||||
semver.major(fromRef) === semver.major(toRef)
|
||||
|
||||
if (includeDeps) {
|
||||
await getDependencyCommits(pool, fromRef, toRef)
|
||||
await getDependencyCommitsGN(pool, fromRef, toRef)
|
||||
}
|
||||
|
||||
// remove any old commits
|
||||
|
||||
@@ -35,9 +35,8 @@ const NPX_CMD = process.platform === 'win32' ? 'npx.cmd' : 'npx'
|
||||
|
||||
const runners = new Map([
|
||||
['main', { description: 'Main process specs', run: runMainProcessElectronTests }],
|
||||
['remote', { description: 'Remote based specs', run: runRemoteBasedElectronTests }]
|
||||
// TODO(codebytere): refactor native tests to only depend on what we need
|
||||
/* ['native', { description: 'Native specs', run: runNativeElectronTests }] */
|
||||
['remote', { description: 'Remote based specs', run: runRemoteBasedElectronTests }],
|
||||
['native', { description: 'Native specs', run: runNativeElectronTests }]
|
||||
])
|
||||
|
||||
const specHashPath = path.resolve(__dirname, '../spec/.hash')
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
param([string]$gomaDir=$PWD)
|
||||
$cmdPath = Join-Path -Path $gomaDir -ChildPath "goma_ctl.py"
|
||||
Start-Process -FilePath cmd -ArgumentList "/C", "python", "$cmdPath", "ensure_start"
|
||||
$env:GLOG_logtostderr = "true"
|
||||
$timedOut = $false; $waitTime = 0; $waitIncrement = 5; $timeout=120;
|
||||
Do { sleep $waitIncrement; $timedOut = (($waitTime+=$waitIncrement) -gt $timeout); iex "$gomaDir\gomacc.exe port 2" > $null; } Until(($LASTEXITCODE -eq 0) -or $timedOut)
|
||||
if ($timedOut) {
|
||||
|
||||
@@ -4,7 +4,7 @@ import argparse
|
||||
import os
|
||||
import sys
|
||||
|
||||
from lib.config import LINUX_BINARIES
|
||||
from lib.config import LINUX_BINARIES, enable_verbose_mode
|
||||
from lib.util import execute, get_out_dir
|
||||
|
||||
def strip_binaries(directory, target_cpu):
|
||||
@@ -22,10 +22,12 @@ def strip_binary(binary_path, target_cpu):
|
||||
strip = 'mips64el-redhat-linux-strip'
|
||||
else:
|
||||
strip = 'strip'
|
||||
execute([strip, binary_path])
|
||||
execute([strip, '--preserve-dates', binary_path])
|
||||
|
||||
def main():
|
||||
args = parse_args()
|
||||
if args.verbose:
|
||||
enable_verbose_mode()
|
||||
if args.file:
|
||||
strip_binary(args.file, args.target_cpu)
|
||||
else:
|
||||
|
||||
@@ -33,12 +33,13 @@
|
||||
#endif // defined(WIDEVINE_CDM_AVAILABLE)
|
||||
|
||||
#if BUILDFLAG(ENABLE_PDF_VIEWER)
|
||||
#include "pdf/pdf.h" // nogncheck
|
||||
#include "pdf/pdf_ppapi.h" // nogncheck
|
||||
#include "shell/common/electron_constants.h" // nogncheck
|
||||
#endif // BUILDFLAG(ENABLE_PDF_VIEWER)
|
||||
#include "pdf/pdf.h" // nogncheck
|
||||
#include "pdf/pdf_ppapi.h" // nogncheck
|
||||
#include "shell/common/electron_constants.h"
|
||||
#endif // BUILDFLAG(ENABLE_PDF_VIEWER)
|
||||
|
||||
#if BUILDFLAG(ENABLE_PLUGINS)
|
||||
#include "content/public/browser/plugin_service.h"
|
||||
#include "content/public/common/pepper_plugin_info.h"
|
||||
#include "ppapi/shared_impl/ppapi_permissions.h"
|
||||
#endif // BUILDFLAG(ENABLE_PLUGINS)
|
||||
@@ -155,7 +156,8 @@ void ComputeBuiltInPlugins(std::vector<content::PepperPluginInfo>* plugins) {
|
||||
pdf_info.is_out_of_process = true;
|
||||
pdf_info.name = "Chromium PDF Viewer";
|
||||
pdf_info.description = "Portable Document Format";
|
||||
pdf_info.path = base::FilePath(FILE_PATH_LITERAL("internal-pdf-viewer"));
|
||||
// This isn't a real file path; it's just used as a unique identifier.
|
||||
pdf_info.path = base::FilePath(kPdfPluginPath);
|
||||
content::WebPluginMimeType pdf_mime_type(kPdfPluginMimeType, "pdf",
|
||||
"Portable Document Format");
|
||||
pdf_info.mime_types.push_back(pdf_mime_type);
|
||||
@@ -166,6 +168,21 @@ void ComputeBuiltInPlugins(std::vector<content::PepperPluginInfo>* plugins) {
|
||||
chrome_pdf::PPP_ShutdownModule;
|
||||
pdf_info.permissions = ppapi::PERMISSION_PDF | ppapi::PERMISSION_DEV;
|
||||
plugins->push_back(pdf_info);
|
||||
|
||||
// NB. in Chrome, this plugin isn't registered until the PDF extension is
|
||||
// loaded. However, in Electron, we load the PDF extension unconditionally
|
||||
// when it is enabled in the build, so we're OK to load the plugin eagerly
|
||||
// here.
|
||||
content::WebPluginInfo info;
|
||||
info.type = content::WebPluginInfo::PLUGIN_TYPE_BROWSER_PLUGIN;
|
||||
info.name = base::UTF8ToUTF16("Chromium PDF Viewer");
|
||||
// This isn't a real file path; it's just used as a unique identifier.
|
||||
info.path = base::FilePath::FromUTF8Unsafe(extension_misc::kPdfExtensionId);
|
||||
info.background_color = content::WebPluginInfo::kDefaultBackgroundColor;
|
||||
info.mime_types.emplace_back("application/pdf", "pdf",
|
||||
"Portable Document Format");
|
||||
content::PluginService::GetInstance()->RefreshPlugins();
|
||||
content::PluginService::GetInstance()->RegisterInternalPlugin(info, true);
|
||||
#endif // BUILDFLAG(ENABLE_PDF_VIEWER)
|
||||
}
|
||||
#endif // BUILDFLAG(ENABLE_PLUGINS)
|
||||
|
||||
@@ -118,15 +118,6 @@ void LoadResourceBundle(const std::string& locale) {
|
||||
bundle.ReloadLocaleResources(locale);
|
||||
bundle.AddDataPackFromPath(pak_dir.Append(FILE_PATH_LITERAL("resources.pak")),
|
||||
ui::SCALE_FACTOR_NONE);
|
||||
#if BUILDFLAG(ENABLE_PDF_VIEWER)
|
||||
NOTIMPLEMENTED()
|
||||
<< "Hi, whoever's fixing PDF support! Thanks! The pdf "
|
||||
"viewer resources haven't been ported over to the GN build yet, so "
|
||||
"you'll probably need to change this bit of code.";
|
||||
bundle.AddDataPackFromPath(
|
||||
pak_dir.Append(FILE_PATH_LITERAL("pdf_viewer_resources.pak")),
|
||||
ui::GetSupportedScaleFactors()[0]);
|
||||
#endif // BUILDFLAG(ENABLE_PDF_VIEWER)
|
||||
}
|
||||
|
||||
ElectronMainDelegate::ElectronMainDelegate() = default;
|
||||
@@ -224,6 +215,21 @@ bool ElectronMainDelegate::BasicStartupComplete(int* exit_code) {
|
||||
<< " is not supported. See https://crbug.com/638180.";
|
||||
#endif
|
||||
|
||||
#if defined(MAS_BUILD)
|
||||
// In MAS build we are using --disable-remote-core-animation.
|
||||
//
|
||||
// According to ccameron:
|
||||
// If you're running with --disable-remote-core-animation, you may want to
|
||||
// also run with --disable-gpu-memory-buffer-compositor-resources as well.
|
||||
// That flag makes it so we use regular GL textures instead of IOSurfaces
|
||||
// for compositor resources. IOSurfaces are very heavyweight to
|
||||
// create/destroy, but they can be displayed directly by CoreAnimation (and
|
||||
// --disable-remote-core-animation makes it so we don't use this property,
|
||||
// so they're just heavyweight with no upside).
|
||||
command_line->AppendSwitch(
|
||||
::switches::kDisableGpuMemoryBufferCompositorResources);
|
||||
#endif
|
||||
|
||||
content_client_ = std::make_unique<ElectronContentClient>();
|
||||
SetContentClient(content_client_.get());
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@ void ElectronMainDelegate::SetUpBundleOverrides() {
|
||||
|
||||
void RegisterAtomCrApp() {
|
||||
// Force the NSApplication subclass to be used.
|
||||
[ElectronApplication sharedApplication];
|
||||
[AtomApplication sharedApplication];
|
||||
}
|
||||
|
||||
} // namespace electron
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
@@ -226,6 +227,42 @@ void DestroyGlobalHandle(v8::Isolate* isolate,
|
||||
}
|
||||
}
|
||||
|
||||
class DictionaryObserver final : public SpellcheckCustomDictionary::Observer {
|
||||
private:
|
||||
std::unique_ptr<gin_helper::Promise<std::set<std::string>>> promise_;
|
||||
base::WeakPtr<SpellcheckService> spellcheck_;
|
||||
|
||||
public:
|
||||
DictionaryObserver(gin_helper::Promise<std::set<std::string>> promise,
|
||||
base::WeakPtr<SpellcheckService> spellcheck)
|
||||
: spellcheck_(spellcheck) {
|
||||
promise_ = std::make_unique<gin_helper::Promise<std::set<std::string>>>(
|
||||
std::move(promise));
|
||||
if (spellcheck_)
|
||||
spellcheck_->GetCustomDictionary()->AddObserver(this);
|
||||
}
|
||||
|
||||
~DictionaryObserver() {
|
||||
if (spellcheck_)
|
||||
spellcheck_->GetCustomDictionary()->RemoveObserver(this);
|
||||
}
|
||||
|
||||
void OnCustomDictionaryLoaded() override {
|
||||
if (spellcheck_) {
|
||||
promise_->Resolve(spellcheck_->GetCustomDictionary()->GetWords());
|
||||
} else {
|
||||
promise_->RejectWithErrorMessage(
|
||||
"Spellcheck in unexpected state: failed to load custom dictionary.");
|
||||
}
|
||||
delete this;
|
||||
}
|
||||
|
||||
void OnCustomDictionaryChanged(
|
||||
const SpellcheckCustomDictionary::Change& dictionary_change) override {
|
||||
// noop
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
Session::Session(v8::Isolate* isolate, ElectronBrowserContext* browser_context)
|
||||
@@ -660,7 +697,8 @@ v8::Local<v8::Value> Session::GetAllExtensions() {
|
||||
auto installed_extensions = registry->GenerateInstalledExtensionsSet();
|
||||
std::vector<const extensions::Extension*> extensions_vector;
|
||||
for (const auto& extension : *installed_extensions) {
|
||||
extensions_vector.emplace_back(extension.get());
|
||||
if (extension->location() != extensions::Manifest::COMPONENT)
|
||||
extensions_vector.emplace_back(extension.get());
|
||||
}
|
||||
return gin::ConvertToV8(isolate(), extensions_vector);
|
||||
}
|
||||
@@ -766,6 +804,29 @@ void SetSpellCheckerDictionaryDownloadURL(gin_helper::ErrorThrower thrower,
|
||||
SpellcheckHunspellDictionary::SetDownloadURLForTesting(url);
|
||||
}
|
||||
|
||||
v8::Local<v8::Promise> Session::ListWordsInSpellCheckerDictionary() {
|
||||
gin_helper::Promise<std::set<std::string>> promise(isolate());
|
||||
v8::Local<v8::Promise> handle = promise.GetHandle();
|
||||
|
||||
SpellcheckService* spellcheck =
|
||||
SpellcheckServiceFactory::GetForContext(browser_context_.get());
|
||||
|
||||
if (!spellcheck)
|
||||
promise.RejectWithErrorMessage(
|
||||
"Spellcheck in unexpected state: failed to load custom dictionary.");
|
||||
|
||||
if (spellcheck->GetCustomDictionary()->IsLoaded()) {
|
||||
promise.Resolve(spellcheck->GetCustomDictionary()->GetWords());
|
||||
} else {
|
||||
new DictionaryObserver(std::move(promise), spellcheck->GetWeakPtr());
|
||||
// Dictionary loads by default asynchronously,
|
||||
// call the load function anyways just to be sure.
|
||||
spellcheck->GetCustomDictionary()->Load();
|
||||
}
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
bool Session::AddWordToSpellCheckerDictionary(const std::string& word) {
|
||||
#if BUILDFLAG(USE_BROWSER_SPELLCHECKER)
|
||||
if (spellcheck::UseBrowserSpellChecker()) {
|
||||
@@ -865,6 +926,8 @@ void Session::BuildPrototype(v8::Isolate* isolate,
|
||||
&spellcheck::SpellCheckLanguages)
|
||||
.SetMethod("setSpellCheckerDictionaryDownloadURL",
|
||||
&SetSpellCheckerDictionaryDownloadURL)
|
||||
.SetMethod("listWordsInSpellCheckerDictionary",
|
||||
&Session::ListWordsInSpellCheckerDictionary)
|
||||
.SetMethod("addWordToSpellCheckerDictionary",
|
||||
&Session::AddWordToSpellCheckerDictionary)
|
||||
#endif
|
||||
|
||||
@@ -95,6 +95,7 @@ class Session : public gin_helper::TrackableObject<Session>,
|
||||
base::Value GetSpellCheckerLanguages();
|
||||
void SetSpellCheckerLanguages(gin_helper::ErrorThrower thrower,
|
||||
const std::vector<std::string>& languages);
|
||||
v8::Local<v8::Promise> ListWordsInSpellCheckerDictionary();
|
||||
bool AddWordToSpellCheckerDictionary(const std::string& word);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1803,18 +1803,21 @@ void WebContents::Print(gin_helper::Arguments* args) {
|
||||
settings.SetIntKey(printing::kSettingMarginsType, margin_type);
|
||||
|
||||
if (margin_type == printing::CUSTOM_MARGINS) {
|
||||
base::Value custom_margins(base::Value::Type::DICTIONARY);
|
||||
int top = 0;
|
||||
margins.Get("top", &top);
|
||||
settings.SetIntKey(printing::kSettingMarginTop, top);
|
||||
custom_margins.SetIntKey(printing::kSettingMarginTop, top);
|
||||
int bottom = 0;
|
||||
margins.Get("bottom", &bottom);
|
||||
settings.SetIntKey(printing::kSettingMarginBottom, bottom);
|
||||
custom_margins.SetIntKey(printing::kSettingMarginBottom, bottom);
|
||||
int left = 0;
|
||||
margins.Get("left", &left);
|
||||
settings.SetIntKey(printing::kSettingMarginLeft, left);
|
||||
custom_margins.SetIntKey(printing::kSettingMarginLeft, left);
|
||||
int right = 0;
|
||||
margins.Get("right", &right);
|
||||
settings.SetIntKey(printing::kSettingMarginRight, right);
|
||||
custom_margins.SetIntKey(printing::kSettingMarginRight, right);
|
||||
settings.SetPath(printing::kSettingMarginsCustom,
|
||||
std::move(custom_margins));
|
||||
}
|
||||
} else {
|
||||
settings.SetIntKey(printing::kSettingMarginsType,
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#include "gin/arguments.h"
|
||||
#include "gin/handle.h"
|
||||
#include "gin/wrappable.h"
|
||||
#include "shell/browser/net/proxying_url_loader_factory.h"
|
||||
#include "shell/browser/net/web_request_api_interface.h"
|
||||
|
||||
namespace content {
|
||||
class BrowserContext;
|
||||
@@ -49,10 +49,6 @@ class WebRequest : public gin::Wrappable<WebRequest>, public WebRequestAPI {
|
||||
v8::Isolate* isolate) override;
|
||||
const char* GetTypeName() override;
|
||||
|
||||
private:
|
||||
WebRequest(v8::Isolate* isolate, content::BrowserContext* browser_context);
|
||||
~WebRequest() override;
|
||||
|
||||
// WebRequestAPI:
|
||||
bool HasListener() const override;
|
||||
int OnBeforeRequest(extensions::WebRequestInfo* info,
|
||||
@@ -86,6 +82,10 @@ class WebRequest : public gin::Wrappable<WebRequest>, public WebRequestAPI {
|
||||
int net_error) override;
|
||||
void OnRequestWillBeDestroyed(extensions::WebRequestInfo* info) override;
|
||||
|
||||
private:
|
||||
WebRequest(v8::Isolate* isolate, content::BrowserContext* browser_context);
|
||||
~WebRequest() override;
|
||||
|
||||
enum SimpleEvent {
|
||||
kOnSendHeaders,
|
||||
kOnBeforeRedirect,
|
||||
|
||||
@@ -29,20 +29,19 @@
|
||||
namespace electron {
|
||||
|
||||
void Browser::SetShutdownHandler(base::Callback<bool()> handler) {
|
||||
[[ElectronApplication sharedApplication]
|
||||
setShutdownHandler:std::move(handler)];
|
||||
[[AtomApplication sharedApplication] setShutdownHandler:std::move(handler)];
|
||||
}
|
||||
|
||||
void Browser::Focus() {
|
||||
[[ElectronApplication sharedApplication] activateIgnoringOtherApps:NO];
|
||||
[[AtomApplication sharedApplication] activateIgnoringOtherApps:NO];
|
||||
}
|
||||
|
||||
void Browser::Hide() {
|
||||
[[ElectronApplication sharedApplication] hide:nil];
|
||||
[[AtomApplication sharedApplication] hide:nil];
|
||||
}
|
||||
|
||||
void Browser::Show() {
|
||||
[[ElectronApplication sharedApplication] unhide:nil];
|
||||
[[AtomApplication sharedApplication] unhide:nil];
|
||||
}
|
||||
|
||||
void Browser::AddRecentDocument(const base::FilePath& path) {
|
||||
@@ -163,7 +162,7 @@ void Browser::SetUserActivity(const std::string& type,
|
||||
std::string url_string;
|
||||
args->GetNext(&url_string);
|
||||
|
||||
[[ElectronApplication sharedApplication]
|
||||
[[AtomApplication sharedApplication]
|
||||
setCurrentActivity:base::SysUTF8ToNSString(type)
|
||||
withUserInfo:DictionaryValueToNSDictionary(user_info)
|
||||
withWebpageURL:net::NSURLWithGURL(GURL(url_string))];
|
||||
@@ -171,21 +170,21 @@ void Browser::SetUserActivity(const std::string& type,
|
||||
|
||||
std::string Browser::GetCurrentActivityType() {
|
||||
NSUserActivity* userActivity =
|
||||
[[ElectronApplication sharedApplication] getCurrentActivity];
|
||||
[[AtomApplication sharedApplication] getCurrentActivity];
|
||||
return base::SysNSStringToUTF8(userActivity.activityType);
|
||||
}
|
||||
|
||||
void Browser::InvalidateCurrentActivity() {
|
||||
[[ElectronApplication sharedApplication] invalidateCurrentActivity];
|
||||
[[AtomApplication sharedApplication] invalidateCurrentActivity];
|
||||
}
|
||||
|
||||
void Browser::ResignCurrentActivity() {
|
||||
[[ElectronApplication sharedApplication] resignCurrentActivity];
|
||||
[[AtomApplication sharedApplication] resignCurrentActivity];
|
||||
}
|
||||
|
||||
void Browser::UpdateCurrentActivity(const std::string& type,
|
||||
base::DictionaryValue user_info) {
|
||||
[[ElectronApplication sharedApplication]
|
||||
[[AtomApplication sharedApplication]
|
||||
updateCurrentActivity:base::SysUTF8ToNSString(type)
|
||||
withUserInfo:DictionaryValueToNSDictionary(user_info)];
|
||||
}
|
||||
@@ -291,17 +290,16 @@ std::string Browser::GetExecutableFileProductName() const {
|
||||
}
|
||||
|
||||
int Browser::DockBounce(BounceType type) {
|
||||
return [[ElectronApplication sharedApplication]
|
||||
return [[AtomApplication sharedApplication]
|
||||
requestUserAttention:static_cast<NSRequestUserAttentionType>(type)];
|
||||
}
|
||||
|
||||
void Browser::DockCancelBounce(int request_id) {
|
||||
[[ElectronApplication sharedApplication]
|
||||
cancelUserAttentionRequest:request_id];
|
||||
[[AtomApplication sharedApplication] cancelUserAttentionRequest:request_id];
|
||||
}
|
||||
|
||||
void Browser::DockSetBadgeText(const std::string& label) {
|
||||
NSDockTile* tile = [[ElectronApplication sharedApplication] dockTile];
|
||||
NSDockTile* tile = [[AtomApplication sharedApplication] dockTile];
|
||||
[tile setBadgeLabel:base::SysUTF8ToNSString(label)];
|
||||
}
|
||||
|
||||
@@ -312,7 +310,7 @@ void Browser::DockDownloadFinished(const std::string& filePath) {
|
||||
}
|
||||
|
||||
std::string Browser::DockGetBadgeText() {
|
||||
NSDockTile* tile = [[ElectronApplication sharedApplication] dockTile];
|
||||
NSDockTile* tile = [[AtomApplication sharedApplication] dockTile];
|
||||
return base::SysNSStringToUTF8([tile badgeLabel]);
|
||||
}
|
||||
|
||||
@@ -371,7 +369,7 @@ void Browser::DockSetMenu(ElectronMenuModel* model) {
|
||||
}
|
||||
|
||||
void Browser::DockSetIcon(const gfx::Image& image) {
|
||||
[[ElectronApplication sharedApplication]
|
||||
[[AtomApplication sharedApplication]
|
||||
setApplicationIconImage:image.AsNSImage()];
|
||||
}
|
||||
|
||||
@@ -394,7 +392,7 @@ void Browser::ShowAboutPanel() {
|
||||
options = [NSDictionary dictionaryWithDictionary:mutable_options];
|
||||
}
|
||||
|
||||
[[ElectronApplication sharedApplication]
|
||||
[[AtomApplication sharedApplication]
|
||||
orderFrontStandardAboutPanelWithOptions:options];
|
||||
}
|
||||
|
||||
@@ -411,7 +409,7 @@ void Browser::SetAboutPanelOptions(base::DictionaryValue options) {
|
||||
}
|
||||
|
||||
void Browser::ShowEmojiPanel() {
|
||||
[[ElectronApplication sharedApplication] orderFrontCharacterPalette:nil];
|
||||
[[AtomApplication sharedApplication] orderFrontCharacterPalette:nil];
|
||||
}
|
||||
|
||||
bool Browser::IsEmojiPanelSupported() {
|
||||
|
||||
@@ -292,8 +292,21 @@ content::WebContents* CommonWebContentsDelegate::OpenURLFromTab(
|
||||
load_url_params.should_replace_current_entry =
|
||||
params.should_replace_current_entry;
|
||||
load_url_params.is_renderer_initiated = params.is_renderer_initiated;
|
||||
load_url_params.started_from_context_menu = params.started_from_context_menu;
|
||||
load_url_params.initiator_origin = params.initiator_origin;
|
||||
load_url_params.should_clear_history_list = true;
|
||||
load_url_params.source_site_instance = params.source_site_instance;
|
||||
load_url_params.frame_tree_node_id = params.frame_tree_node_id;
|
||||
load_url_params.redirect_chain = params.redirect_chain;
|
||||
load_url_params.has_user_gesture = params.user_gesture;
|
||||
load_url_params.blob_url_loader_factory = params.blob_url_loader_factory;
|
||||
load_url_params.href_translate = params.href_translate;
|
||||
load_url_params.reload_type = params.reload_type;
|
||||
|
||||
if (params.post_data) {
|
||||
load_url_params.load_type =
|
||||
content::NavigationController::LOAD_TYPE_HTTP_POST;
|
||||
load_url_params.post_data = params.post_data;
|
||||
}
|
||||
|
||||
source->GetController().LoadURLWithParams(load_url_params);
|
||||
return source;
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#include "extensions/common/constants.h"
|
||||
#include "net/base/escape.h"
|
||||
#include "net/ssl/ssl_cert_request_info.h"
|
||||
#include "ppapi/buildflags/buildflags.h"
|
||||
#include "ppapi/host/ppapi_host.h"
|
||||
#include "printing/buildflags/buildflags.h"
|
||||
#include "services/device/public/cpp/geolocation/location_provider.h"
|
||||
@@ -75,6 +76,7 @@
|
||||
#include "shell/browser/net/network_context_service.h"
|
||||
#include "shell/browser/net/network_context_service_factory.h"
|
||||
#include "shell/browser/net/proxying_url_loader_factory.h"
|
||||
#include "shell/browser/net/proxying_websocket.h"
|
||||
#include "shell/browser/net/system_network_context_manager.h"
|
||||
#include "shell/browser/network_hints_handler_impl.h"
|
||||
#include "shell/browser/notifications/notification_presenter.h"
|
||||
@@ -128,13 +130,29 @@
|
||||
#endif // BUILDFLAG(ENABLE_PRINTING)
|
||||
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
#include "chrome/common/webui_url_constants.h"
|
||||
#include "content/public/browser/child_process_security_policy.h"
|
||||
#include "content/public/browser/file_url_loader.h"
|
||||
#include "content/public/browser/web_ui_url_loader_factory.h"
|
||||
#include "extensions/browser/api/mime_handler_private/mime_handler_private.h"
|
||||
#include "extensions/browser/extension_host.h"
|
||||
#include "extensions/browser/extension_message_filter.h"
|
||||
#include "extensions/browser/extension_navigation_throttle.h"
|
||||
#include "extensions/browser/extension_registry.h"
|
||||
#include "extensions/browser/guest_view/extensions_guest_view_message_filter.h"
|
||||
#include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h"
|
||||
#include "extensions/browser/info_map.h"
|
||||
#include "extensions/browser/process_manager.h"
|
||||
#include "extensions/browser/process_map.h"
|
||||
#include "extensions/common/api/mime_handler.mojom.h"
|
||||
#include "extensions/common/extension.h"
|
||||
#include "shell/browser/extensions/electron_extension_system.h"
|
||||
#include "shell/browser/extensions/electron_extension_web_contents_observer.h"
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(ENABLE_PLUGINS)
|
||||
#include "chrome/browser/plugins/plugin_response_interceptor_url_loader_throttle.h" // nogncheck
|
||||
#include "shell/browser/plugins/plugin_utils.h"
|
||||
#endif
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
@@ -186,6 +204,63 @@ const base::FilePath::StringPieceType kPathDelimiter = FILE_PATH_LITERAL(";");
|
||||
const base::FilePath::StringPieceType kPathDelimiter = FILE_PATH_LITERAL(":");
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
// Used by the GetPrivilegeRequiredByUrl() and GetProcessPrivilege() functions
|
||||
// below. Extension, and isolated apps require different privileges to be
|
||||
// granted to their RenderProcessHosts. This classification allows us to make
|
||||
// sure URLs are served by hosts with the right set of privileges.
|
||||
enum RenderProcessHostPrivilege {
|
||||
PRIV_NORMAL,
|
||||
PRIV_HOSTED,
|
||||
PRIV_ISOLATED,
|
||||
PRIV_EXTENSION,
|
||||
};
|
||||
|
||||
RenderProcessHostPrivilege GetPrivilegeRequiredByUrl(
|
||||
const GURL& url,
|
||||
extensions::ExtensionRegistry* registry) {
|
||||
// Default to a normal renderer cause it is lower privileged. This should only
|
||||
// occur if the URL on a site instance is either malformed, or uninitialized.
|
||||
// If it is malformed, then there is no need for better privileges anyways.
|
||||
// If it is uninitialized, but eventually settles on being an a scheme other
|
||||
// than normal webrenderer, the navigation logic will correct us out of band
|
||||
// anyways.
|
||||
if (!url.is_valid())
|
||||
return PRIV_NORMAL;
|
||||
|
||||
if (!url.SchemeIs(extensions::kExtensionScheme))
|
||||
return PRIV_NORMAL;
|
||||
|
||||
return PRIV_EXTENSION;
|
||||
}
|
||||
|
||||
RenderProcessHostPrivilege GetProcessPrivilege(
|
||||
content::RenderProcessHost* process_host,
|
||||
extensions::ProcessMap* process_map,
|
||||
extensions::ExtensionRegistry* registry) {
|
||||
std::set<std::string> extension_ids =
|
||||
process_map->GetExtensionsInProcess(process_host->GetID());
|
||||
if (extension_ids.empty())
|
||||
return PRIV_NORMAL;
|
||||
|
||||
return PRIV_EXTENSION;
|
||||
}
|
||||
|
||||
const extensions::Extension* GetEnabledExtensionFromEffectiveURL(
|
||||
content::BrowserContext* context,
|
||||
const GURL& effective_url) {
|
||||
if (!effective_url.SchemeIs(extensions::kExtensionScheme))
|
||||
return nullptr;
|
||||
|
||||
extensions::ExtensionRegistry* registry =
|
||||
extensions::ExtensionRegistry::Get(context);
|
||||
if (!registry)
|
||||
return nullptr;
|
||||
|
||||
return registry->enabled_extensions().GetByID(effective_url.host());
|
||||
}
|
||||
#endif // BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
|
||||
} // namespace
|
||||
|
||||
// static
|
||||
@@ -385,6 +460,8 @@ void ElectronBrowserClient::RenderProcessWillLaunch(
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
host->AddFilter(
|
||||
new extensions::ExtensionMessageFilter(process_id, browser_context));
|
||||
host->AddFilter(new extensions::ExtensionsGuestViewMessageFilter(
|
||||
process_id, browser_context));
|
||||
#endif
|
||||
|
||||
ProcessPreferences prefs;
|
||||
@@ -727,6 +804,7 @@ void ElectronBrowserClient::GetAdditionalAllowedSchemesForFileSystem(
|
||||
additional_schemes->insert(additional_schemes->end(), schemes_list.begin(),
|
||||
schemes_list.end());
|
||||
additional_schemes->push_back(content::kChromeDevToolsScheme);
|
||||
additional_schemes->push_back(content::kChromeUIScheme);
|
||||
}
|
||||
|
||||
void ElectronBrowserClient::GetAdditionalWebUISchemes(
|
||||
@@ -760,6 +838,40 @@ void ElectronBrowserClient::SiteInstanceGotProcess(
|
||||
#endif // BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
}
|
||||
|
||||
bool ElectronBrowserClient::IsSuitableHost(
|
||||
content::RenderProcessHost* process_host,
|
||||
const GURL& site_url) {
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
auto* browser_context = process_host->GetBrowserContext();
|
||||
extensions::ExtensionRegistry* registry =
|
||||
extensions::ExtensionRegistry::Get(browser_context);
|
||||
extensions::ProcessMap* process_map =
|
||||
extensions::ProcessMap::Get(browser_context);
|
||||
|
||||
// Otherwise, just make sure the process privilege matches the privilege
|
||||
// required by the site.
|
||||
RenderProcessHostPrivilege privilege_required =
|
||||
GetPrivilegeRequiredByUrl(site_url, registry);
|
||||
return GetProcessPrivilege(process_host, process_map, registry) ==
|
||||
privilege_required;
|
||||
#else
|
||||
return content::ContentBrowserClient::IsSuitableHost(process_host, site_url);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool ElectronBrowserClient::ShouldUseProcessPerSite(
|
||||
content::BrowserContext* browser_context,
|
||||
const GURL& effective_url) {
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
const extensions::Extension* extension =
|
||||
GetEnabledExtensionFromEffectiveURL(browser_context, effective_url);
|
||||
return extension != nullptr;
|
||||
#else
|
||||
return content::ContentBrowserClient::ShouldUseProcessPerSite(browser_context,
|
||||
effective_url);
|
||||
#endif
|
||||
}
|
||||
|
||||
void ElectronBrowserClient::SiteInstanceDeleting(
|
||||
content::SiteInstance* site_instance) {
|
||||
// We are storing weak_ptr, is it fundamental to maintain the map up-to-date
|
||||
@@ -1052,28 +1164,160 @@ void ElectronBrowserClient::RegisterNonNetworkNavigationURLLoaderFactories(
|
||||
protocol->RegisterURLLoaderFactories(factories);
|
||||
}
|
||||
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
namespace {
|
||||
|
||||
// The FileURLLoaderFactory provided to the extension background pages.
|
||||
// Checks with the ChildProcessSecurityPolicy to validate the file access.
|
||||
class FileURLLoaderFactory : public network::mojom::URLLoaderFactory {
|
||||
public:
|
||||
explicit FileURLLoaderFactory(int child_id) : child_id_(child_id) {}
|
||||
|
||||
private:
|
||||
// network::mojom::URLLoaderFactory:
|
||||
void CreateLoaderAndStart(
|
||||
mojo::PendingReceiver<network::mojom::URLLoader> loader,
|
||||
int32_t routing_id,
|
||||
int32_t request_id,
|
||||
uint32_t options,
|
||||
const network::ResourceRequest& request,
|
||||
mojo::PendingRemote<network::mojom::URLLoaderClient> client,
|
||||
const net::MutableNetworkTrafficAnnotationTag& traffic_annotation)
|
||||
override {
|
||||
if (!content::ChildProcessSecurityPolicy::GetInstance()->CanRequestURL(
|
||||
child_id_, request.url)) {
|
||||
mojo::Remote<network::mojom::URLLoaderClient>(std::move(client))
|
||||
->OnComplete(
|
||||
network::URLLoaderCompletionStatus(net::ERR_ACCESS_DENIED));
|
||||
return;
|
||||
}
|
||||
content::CreateFileURLLoaderBypassingSecurityChecks(
|
||||
request, std::move(loader), std::move(client),
|
||||
/*observer=*/nullptr,
|
||||
/* allow_directory_listing */ true);
|
||||
}
|
||||
|
||||
void Clone(
|
||||
mojo::PendingReceiver<network::mojom::URLLoaderFactory> loader) override {
|
||||
receivers_.Add(this, std::move(loader));
|
||||
}
|
||||
|
||||
int child_id_;
|
||||
mojo::ReceiverSet<network::mojom::URLLoaderFactory> receivers_;
|
||||
DISALLOW_COPY_AND_ASSIGN(FileURLLoaderFactory);
|
||||
};
|
||||
|
||||
} // namespace
|
||||
#endif // BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
|
||||
void ElectronBrowserClient::RegisterNonNetworkSubresourceURLLoaderFactories(
|
||||
int render_process_id,
|
||||
int render_frame_id,
|
||||
NonNetworkURLLoaderFactoryMap* factories) {
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
auto factory = extensions::CreateExtensionURLLoaderFactory(render_process_id,
|
||||
render_frame_id);
|
||||
if (factory)
|
||||
factories->emplace(extensions::kExtensionScheme, std::move(factory));
|
||||
#endif
|
||||
|
||||
// Chromium may call this even when NetworkService is not enabled.
|
||||
content::RenderFrameHost* frame_host =
|
||||
content::RenderFrameHost::FromID(render_process_id, render_frame_id);
|
||||
content::WebContents* web_contents =
|
||||
content::WebContents::FromRenderFrameHost(frame_host);
|
||||
|
||||
if (web_contents) {
|
||||
api::Protocol* protocol = api::Protocol::FromWrappedClass(
|
||||
v8::Isolate::GetCurrent(), web_contents->GetBrowserContext());
|
||||
if (protocol)
|
||||
protocol->RegisterURLLoaderFactories(factories);
|
||||
}
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
auto factory = extensions::CreateExtensionURLLoaderFactory(render_process_id,
|
||||
render_frame_id);
|
||||
if (factory)
|
||||
factories->emplace(extensions::kExtensionScheme, std::move(factory));
|
||||
|
||||
if (!web_contents)
|
||||
return;
|
||||
|
||||
extensions::ElectronExtensionWebContentsObserver* web_observer =
|
||||
extensions::ElectronExtensionWebContentsObserver::FromWebContents(
|
||||
web_contents);
|
||||
|
||||
// There is nothing to do if no ElectronExtensionWebContentsObserver is
|
||||
// attached to the |web_contents|.
|
||||
if (!web_observer)
|
||||
return;
|
||||
|
||||
const extensions::Extension* extension =
|
||||
web_observer->GetExtensionFromFrame(frame_host, false);
|
||||
if (!extension)
|
||||
return;
|
||||
|
||||
// Support for chrome:// scheme if appropriate.
|
||||
if (extension->is_extension() &&
|
||||
extensions::Manifest::IsComponentLocation(extension->location())) {
|
||||
// Components of chrome that are implemented as extensions or platform apps
|
||||
// are allowed to use chrome://resources/ and chrome://theme/ URLs.
|
||||
factories->emplace(
|
||||
content::kChromeUIScheme,
|
||||
content::CreateWebUIURLLoader(frame_host, content::kChromeUIScheme,
|
||||
{content::kChromeUIResourcesHost}));
|
||||
}
|
||||
|
||||
// Extension with a background page get file access that gets approval from
|
||||
// ChildProcessSecurityPolicy.
|
||||
extensions::ExtensionHost* host =
|
||||
extensions::ProcessManager::Get(web_contents->GetBrowserContext())
|
||||
->GetBackgroundHostForExtension(extension->id());
|
||||
if (host) {
|
||||
factories->emplace(url::kFileScheme, std::make_unique<FileURLLoaderFactory>(
|
||||
render_process_id));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool ElectronBrowserClient::ShouldTreatURLSchemeAsFirstPartyWhenTopLevel(
|
||||
base::StringPiece scheme,
|
||||
bool is_embedded_origin_secure) {
|
||||
if (is_embedded_origin_secure && scheme == content::kChromeUIScheme)
|
||||
return true;
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
return scheme == extensions::kExtensionScheme;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool ElectronBrowserClient::WillInterceptWebSocket(
|
||||
content::RenderFrameHost* frame) {
|
||||
if (!frame)
|
||||
return false;
|
||||
|
||||
v8::Isolate* isolate = v8::Isolate::GetCurrent();
|
||||
auto* browser_context = frame->GetProcess()->GetBrowserContext();
|
||||
auto web_request = api::WebRequest::FromOrCreate(isolate, browser_context);
|
||||
|
||||
// NOTE: Some unit test environments do not initialize
|
||||
// BrowserContextKeyedAPI factories for e.g. WebRequest.
|
||||
if (!web_request.get())
|
||||
return false;
|
||||
|
||||
return web_request->HasListener();
|
||||
}
|
||||
|
||||
void ElectronBrowserClient::CreateWebSocket(
|
||||
content::RenderFrameHost* frame,
|
||||
WebSocketFactory factory,
|
||||
const GURL& url,
|
||||
const net::SiteForCookies& site_for_cookies,
|
||||
const base::Optional<std::string>& user_agent,
|
||||
mojo::PendingRemote<network::mojom::WebSocketHandshakeClient>
|
||||
handshake_client) {
|
||||
v8::Isolate* isolate = v8::Isolate::GetCurrent();
|
||||
auto* browser_context = frame->GetProcess()->GetBrowserContext();
|
||||
auto web_request = api::WebRequest::FromOrCreate(isolate, browser_context);
|
||||
DCHECK(web_request.get());
|
||||
ProxyingWebSocket::StartProxying(
|
||||
web_request.get(), std::move(factory), url,
|
||||
site_for_cookies.RepresentativeUrl(), user_agent,
|
||||
std::move(handshake_client), true, frame->GetProcess()->GetID(),
|
||||
frame->GetRoutingID(), frame->GetLastCommittedOrigin(), browser_context,
|
||||
&next_id_);
|
||||
}
|
||||
|
||||
bool ElectronBrowserClient::WillCreateURLLoaderFactory(
|
||||
@@ -1118,7 +1362,7 @@ bool ElectronBrowserClient::WillCreateURLLoaderFactory(
|
||||
|
||||
new ProxyingURLLoaderFactory(
|
||||
web_request.get(), protocol->intercept_handlers(), browser_context,
|
||||
render_process_id, std::move(navigation_ui_data),
|
||||
render_process_id, &next_id_, std::move(navigation_ui_data),
|
||||
std::move(navigation_id), std::move(proxied_receiver),
|
||||
std::move(target_factory_remote), std::move(header_client_receiver),
|
||||
type);
|
||||
@@ -1202,11 +1446,31 @@ void ElectronBrowserClient::BindHostReceiverForRenderer(
|
||||
#endif
|
||||
}
|
||||
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
void BindMimeHandlerService(
|
||||
content::RenderFrameHost* frame_host,
|
||||
mojo::PendingReceiver<extensions::mime_handler::MimeHandlerService>
|
||||
receiver) {
|
||||
content::WebContents* contents =
|
||||
content::WebContents::FromRenderFrameHost(frame_host);
|
||||
auto* guest_view =
|
||||
extensions::MimeHandlerViewGuest::FromWebContents(contents);
|
||||
if (!guest_view)
|
||||
return;
|
||||
extensions::MimeHandlerServiceImpl::Create(guest_view->GetStreamWeakPtr(),
|
||||
std::move(receiver));
|
||||
}
|
||||
#endif
|
||||
|
||||
void ElectronBrowserClient::RegisterBrowserInterfaceBindersForFrame(
|
||||
content::RenderFrameHost* render_frame_host,
|
||||
service_manager::BinderMapWithContext<content::RenderFrameHost*>* map) {
|
||||
map->Add<network_hints::mojom::NetworkHintsHandler>(
|
||||
base::BindRepeating(&BindNetworkHintsHandler));
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
map->Add<extensions::mime_handler::MimeHandlerService>(
|
||||
base::BindRepeating(&BindMimeHandlerService));
|
||||
#endif
|
||||
}
|
||||
|
||||
std::unique_ptr<content::LoginDelegate>
|
||||
@@ -1224,4 +1488,35 @@ ElectronBrowserClient::CreateLoginDelegate(
|
||||
first_auth_attempt, std::move(auth_required_callback));
|
||||
}
|
||||
|
||||
std::vector<std::unique_ptr<blink::URLLoaderThrottle>>
|
||||
ElectronBrowserClient::CreateURLLoaderThrottles(
|
||||
const network::ResourceRequest& request,
|
||||
content::BrowserContext* browser_context,
|
||||
const base::RepeatingCallback<content::WebContents*()>& wc_getter,
|
||||
content::NavigationUIData* navigation_ui_data,
|
||||
int frame_tree_node_id) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||
|
||||
std::vector<std::unique_ptr<blink::URLLoaderThrottle>> result;
|
||||
|
||||
#if BUILDFLAG(ENABLE_PLUGINS) && BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
result.push_back(std::make_unique<PluginResponseInterceptorURLLoaderThrottle>(
|
||||
request.resource_type, frame_tree_node_id));
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
base::flat_set<std::string>
|
||||
ElectronBrowserClient::GetPluginMimeTypesWithExternalHandlers(
|
||||
content::BrowserContext* browser_context) {
|
||||
base::flat_set<std::string> mime_types;
|
||||
#if BUILDFLAG(ENABLE_PLUGINS) && BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
auto map = PluginUtils::GetMimeTypeToExtensionIdMap(browser_context);
|
||||
for (const auto& pair : map)
|
||||
mime_types.insert(pair.first);
|
||||
#endif
|
||||
return mime_types;
|
||||
}
|
||||
|
||||
} // namespace electron
|
||||
|
||||
@@ -173,6 +173,15 @@ class ElectronBrowserClient : public content::ContentBrowserClient,
|
||||
int render_process_id,
|
||||
int render_frame_id,
|
||||
NonNetworkURLLoaderFactoryMap* factories) override;
|
||||
void CreateWebSocket(
|
||||
content::RenderFrameHost* frame,
|
||||
WebSocketFactory factory,
|
||||
const GURL& url,
|
||||
const net::SiteForCookies& site_for_cookies,
|
||||
const base::Optional<std::string>& user_agent,
|
||||
mojo::PendingRemote<network::mojom::WebSocketHandshakeClient>
|
||||
handshake_client) override;
|
||||
bool WillInterceptWebSocket(content::RenderFrameHost*) override;
|
||||
bool WillCreateURLLoaderFactory(
|
||||
content::BrowserContext* browser_context,
|
||||
content::RenderFrameHost* frame,
|
||||
@@ -186,6 +195,9 @@ class ElectronBrowserClient : public content::ContentBrowserClient,
|
||||
bool* bypass_redirect_checks,
|
||||
bool* disable_secure_dns,
|
||||
network::mojom::URLLoaderFactoryOverridePtr* factory_override) override;
|
||||
bool ShouldTreatURLSchemeAsFirstPartyWhenTopLevel(
|
||||
base::StringPiece scheme,
|
||||
bool is_embedded_origin_secure) override;
|
||||
void OverrideURLLoaderFactoryParams(
|
||||
content::BrowserContext* browser_context,
|
||||
const url::Origin& origin,
|
||||
@@ -221,6 +233,19 @@ class ElectronBrowserClient : public content::ContentBrowserClient,
|
||||
bool first_auth_attempt,
|
||||
LoginAuthRequiredCallback auth_required_callback) override;
|
||||
void SiteInstanceGotProcess(content::SiteInstance* site_instance) override;
|
||||
bool IsSuitableHost(content::RenderProcessHost* process_host,
|
||||
const GURL& site_url) override;
|
||||
bool ShouldUseProcessPerSite(content::BrowserContext* browser_context,
|
||||
const GURL& effective_url) override;
|
||||
std::vector<std::unique_ptr<blink::URLLoaderThrottle>>
|
||||
CreateURLLoaderThrottles(
|
||||
const network::ResourceRequest& request,
|
||||
content::BrowserContext* browser_context,
|
||||
const base::RepeatingCallback<content::WebContents*()>& wc_getter,
|
||||
content::NavigationUIData* navigation_ui_data,
|
||||
int frame_tree_node_id) override;
|
||||
base::flat_set<std::string> GetPluginMimeTypesWithExternalHandlers(
|
||||
content::BrowserContext* browser_context) override;
|
||||
|
||||
// content::RenderProcessHostObserver:
|
||||
void RenderProcessHostDestroyed(content::RenderProcessHost* host) override;
|
||||
@@ -286,6 +311,10 @@ class ElectronBrowserClient : public content::ContentBrowserClient,
|
||||
|
||||
bool disable_process_restart_tricks_ = false;
|
||||
|
||||
// Simple shared ID generator, used by ProxyingURLLoaderFactory and
|
||||
// ProxyingWebSocket classes.
|
||||
uint64_t next_id_ = 0;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(ElectronBrowserClient);
|
||||
};
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ void ElectronBrowserMainParts::FreeAppDelegate() {
|
||||
}
|
||||
|
||||
void ElectronBrowserMainParts::RegisterURLHandler() {
|
||||
[[ElectronApplication sharedApplication] registerURLHandler];
|
||||
[[AtomApplication sharedApplication] registerURLHandler];
|
||||
}
|
||||
|
||||
// Replicates NSApplicationMain, but doesn't start a run loop.
|
||||
|
||||
35
shell/browser/extensions/api/BUILD.gn
Normal file
35
shell/browser/extensions/api/BUILD.gn
Normal file
@@ -0,0 +1,35 @@
|
||||
# Copyright 2018 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.
|
||||
|
||||
import("//extensions/buildflags/buildflags.gni")
|
||||
import("//tools/json_schema_compiler/json_schema_api.gni")
|
||||
|
||||
assert(enable_extensions,
|
||||
"Cannot depend on extensions because enable_extensions=false.")
|
||||
|
||||
function_registration("api_registration") {
|
||||
sources = [
|
||||
"//electron/shell/common/extensions/api/extension.json",
|
||||
"//electron/shell/common/extensions/api/resources_private.idl",
|
||||
"//electron/shell/common/extensions/api/tabs.json",
|
||||
]
|
||||
impl_dir = "//electron/shell/browser/extensions/api"
|
||||
configs = [ "//build/config:precompiled_headers" ]
|
||||
bundle_name = "Electron"
|
||||
root_namespace = "extensions::api::%(namespace)s"
|
||||
schema_include_rules = "extensions/common/api:extensions::api::%(namespace)s"
|
||||
|
||||
deps = [
|
||||
# Different APIs include headers from these targets.
|
||||
"//components/zoom",
|
||||
"//content/public/browser",
|
||||
"//extensions/browser",
|
||||
|
||||
# Different APIs include some headers from chrome/common that in turn
|
||||
# include generated headers from these targets.
|
||||
# TODO(brettw) this should be made unnecessary if possible.
|
||||
"//electron/shell/common/extensions/api",
|
||||
]
|
||||
deps += [ "//extensions/common/api" ]
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
// Copyright 2015 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/browser/extensions/api/resources_private/resources_private_api.h"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "base/values.h"
|
||||
#include "chrome/browser/browser_process.h"
|
||||
#include "chrome/common/extensions/api/resources_private.h"
|
||||
#include "chrome/grit/generated_resources.h"
|
||||
#include "components/strings/grit/components_strings.h"
|
||||
#include "components/zoom/page_zoom_constants.h"
|
||||
#include "pdf/buildflags.h"
|
||||
#include "printing/buildflags/buildflags.h"
|
||||
#include "ui/base/l10n/l10n_util.h"
|
||||
#include "ui/base/webui/web_ui_util.h"
|
||||
|
||||
#if BUILDFLAG(ENABLE_PDF)
|
||||
#include "pdf/pdf_features.h"
|
||||
#endif // BUILDFLAG(ENABLE_PDF)
|
||||
|
||||
// To add a new component to this API, simply:
|
||||
// 1. Add your component to the Component enum in
|
||||
// chrome/common/extensions/api/resources_private.idl
|
||||
// 2. Create an AddStringsForMyComponent(base::DictionaryValue * dict) method.
|
||||
// 3. Tie in that method to the switch statement in Run()
|
||||
|
||||
namespace extensions {
|
||||
|
||||
namespace {
|
||||
|
||||
void AddStringsForPdf(base::DictionaryValue* dict) {
|
||||
#if BUILDFLAG(ENABLE_PDF)
|
||||
static constexpr webui::LocalizedString kPdfResources[] = {
|
||||
{"passwordDialogTitle", IDS_PDF_PASSWORD_DIALOG_TITLE},
|
||||
{"passwordPrompt", IDS_PDF_NEED_PASSWORD},
|
||||
{"passwordSubmit", IDS_PDF_PASSWORD_SUBMIT},
|
||||
{"passwordInvalid", IDS_PDF_PASSWORD_INVALID},
|
||||
{"pageLoading", IDS_PDF_PAGE_LOADING},
|
||||
{"pageLoadFailed", IDS_PDF_PAGE_LOAD_FAILED},
|
||||
{"errorDialogTitle", IDS_PDF_ERROR_DIALOG_TITLE},
|
||||
{"pageReload", IDS_PDF_PAGE_RELOAD_BUTTON},
|
||||
{"bookmarks", IDS_PDF_BOOKMARKS},
|
||||
{"labelPageNumber", IDS_PDF_LABEL_PAGE_NUMBER},
|
||||
{"tooltipRotateCW", IDS_PDF_TOOLTIP_ROTATE_CW},
|
||||
{"tooltipDownload", IDS_PDF_TOOLTIP_DOWNLOAD},
|
||||
{"tooltipPrint", IDS_PDF_TOOLTIP_PRINT},
|
||||
{"tooltipFitToPage", IDS_PDF_TOOLTIP_FIT_PAGE},
|
||||
{"tooltipFitToWidth", IDS_PDF_TOOLTIP_FIT_WIDTH},
|
||||
{"tooltipZoomIn", IDS_PDF_TOOLTIP_ZOOM_IN},
|
||||
{"tooltipZoomOut", IDS_PDF_TOOLTIP_ZOOM_OUT},
|
||||
};
|
||||
for (const auto& resource : kPdfResources)
|
||||
dict->SetString(resource.name, l10n_util::GetStringUTF16(resource.id));
|
||||
|
||||
dict->SetString("presetZoomFactors", zoom::GetPresetZoomFactorsAsJSON());
|
||||
#endif // BUILDFLAG(ENABLE_PDF)
|
||||
}
|
||||
|
||||
void AddAdditionalDataForPdf(base::DictionaryValue* dict) {
|
||||
#if BUILDFLAG(ENABLE_PDF)
|
||||
dict->SetKey("pdfFormSaveEnabled",
|
||||
base::Value(base::FeatureList::IsEnabled(
|
||||
chrome_pdf::features::kSaveEditedPDFForm)));
|
||||
dict->SetKey("pdfAnnotationsEnabled",
|
||||
base::Value(base::FeatureList::IsEnabled(
|
||||
chrome_pdf::features::kPDFAnnotations)));
|
||||
|
||||
// TODO(nornagon): enable printing once it works.
|
||||
bool enable_printing = false;
|
||||
dict->SetKey("printingEnabled", base::Value(enable_printing));
|
||||
#endif // BUILDFLAG(ENABLE_PDF)
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace get_strings = api::resources_private::GetStrings;
|
||||
|
||||
ResourcesPrivateGetStringsFunction::ResourcesPrivateGetStringsFunction() {}
|
||||
|
||||
ResourcesPrivateGetStringsFunction::~ResourcesPrivateGetStringsFunction() {}
|
||||
|
||||
ExtensionFunction::ResponseAction ResourcesPrivateGetStringsFunction::Run() {
|
||||
std::unique_ptr<get_strings::Params> params(
|
||||
get_strings::Params::Create(*args_));
|
||||
auto dict = std::make_unique<base::DictionaryValue>();
|
||||
|
||||
api::resources_private::Component component = params->component;
|
||||
|
||||
switch (component) {
|
||||
case api::resources_private::COMPONENT_PDF:
|
||||
AddStringsForPdf(dict.get());
|
||||
AddAdditionalDataForPdf(dict.get());
|
||||
break;
|
||||
case api::resources_private::COMPONENT_IDENTITY:
|
||||
NOTREACHED();
|
||||
break;
|
||||
case api::resources_private::COMPONENT_NONE:
|
||||
NOTREACHED();
|
||||
break;
|
||||
}
|
||||
|
||||
const std::string& app_locale = g_browser_process->GetApplicationLocale();
|
||||
webui::SetLoadTimeDataDefaults(app_locale, dict.get());
|
||||
|
||||
return RespondNow(OneArgument(std::move(dict)));
|
||||
}
|
||||
|
||||
} // namespace extensions
|
||||
@@ -0,0 +1,31 @@
|
||||
// Copyright 2015 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_BROWSER_EXTENSIONS_API_RESOURCES_PRIVATE_RESOURCES_PRIVATE_API_H_
|
||||
#define SHELL_BROWSER_EXTENSIONS_API_RESOURCES_PRIVATE_RESOURCES_PRIVATE_API_H_
|
||||
|
||||
#include "base/macros.h"
|
||||
#include "extensions/browser/extension_function.h"
|
||||
|
||||
namespace extensions {
|
||||
|
||||
class ResourcesPrivateGetStringsFunction : public ExtensionFunction {
|
||||
public:
|
||||
DECLARE_EXTENSION_FUNCTION("resourcesPrivate.getStrings",
|
||||
RESOURCESPRIVATE_GETSTRINGS)
|
||||
ResourcesPrivateGetStringsFunction();
|
||||
|
||||
protected:
|
||||
~ResourcesPrivateGetStringsFunction() override;
|
||||
|
||||
// Override from ExtensionFunction:
|
||||
ExtensionFunction::ResponseAction Run() override;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ResourcesPrivateGetStringsFunction);
|
||||
};
|
||||
|
||||
} // namespace extensions
|
||||
|
||||
#endif // SHELL_BROWSER_EXTENSIONS_API_RESOURCES_PRIVATE_RESOURCES_PRIVATE_API_H_
|
||||
@@ -0,0 +1,74 @@
|
||||
// Copyright (c) 2012 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 "electron/shell/browser/extensions/api/streams_private/streams_private_api.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/render_frame_host.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
#include "extensions/browser/extension_registry.h"
|
||||
#include "extensions/browser/guest_view/mime_handler_view/mime_handler_stream_manager.h"
|
||||
#include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h"
|
||||
#include "extensions/common/manifest_handlers/mime_types_handler.h"
|
||||
#include "shell/browser/api/electron_api_web_contents.h"
|
||||
|
||||
namespace extensions {
|
||||
|
||||
void StreamsPrivateAPI::SendExecuteMimeTypeHandlerEvent(
|
||||
const std::string& extension_id,
|
||||
const std::string& view_id,
|
||||
bool embedded,
|
||||
int frame_tree_node_id,
|
||||
int render_process_id,
|
||||
int render_frame_id,
|
||||
content::mojom::TransferrableURLLoaderPtr transferrable_loader,
|
||||
const GURL& original_url) {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
|
||||
content::WebContents* web_contents = nullptr;
|
||||
if (frame_tree_node_id != -1) {
|
||||
web_contents =
|
||||
content::WebContents::FromFrameTreeNodeId(frame_tree_node_id);
|
||||
} else {
|
||||
web_contents = content::WebContents::FromRenderFrameHost(
|
||||
content::RenderFrameHost::FromID(render_process_id, render_frame_id));
|
||||
}
|
||||
if (!web_contents)
|
||||
return;
|
||||
|
||||
auto* browser_context = web_contents->GetBrowserContext();
|
||||
|
||||
const extensions::Extension* extension =
|
||||
extensions::ExtensionRegistry::Get(browser_context)
|
||||
->enabled_extensions()
|
||||
.GetByID(extension_id);
|
||||
if (!extension)
|
||||
return;
|
||||
|
||||
MimeTypesHandler* handler = MimeTypesHandler::GetHandler(extension);
|
||||
if (!handler->HasPlugin())
|
||||
return;
|
||||
|
||||
// If the mime handler uses MimeHandlerViewGuest, the MimeHandlerViewGuest
|
||||
// will take ownership of the stream.
|
||||
GURL handler_url(
|
||||
extensions::Extension::GetBaseURLFromExtensionId(extension_id).spec() +
|
||||
handler->handler_url());
|
||||
int tab_id = -1;
|
||||
auto* api_contents = electron::api::WebContents::FromWrappedClass(
|
||||
v8::Isolate::GetCurrent(), web_contents);
|
||||
if (api_contents)
|
||||
tab_id = api_contents->ID();
|
||||
std::unique_ptr<extensions::StreamContainer> stream_container(
|
||||
new extensions::StreamContainer(
|
||||
tab_id, embedded, handler_url, extension_id,
|
||||
std::move(transferrable_loader), original_url));
|
||||
extensions::MimeHandlerStreamManager::Get(browser_context)
|
||||
->AddStream(view_id, std::move(stream_container), frame_tree_node_id,
|
||||
render_process_id, render_frame_id);
|
||||
}
|
||||
|
||||
} // namespace extensions
|
||||
@@ -0,0 +1,44 @@
|
||||
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_BROWSER_EXTENSIONS_API_STREAMS_PRIVATE_STREAMS_PRIVATE_API_H_
|
||||
#define SHELL_BROWSER_EXTENSIONS_API_STREAMS_PRIVATE_STREAMS_PRIVATE_API_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "base/macros.h"
|
||||
#include "content/public/common/transferrable_url_loader.mojom.h"
|
||||
|
||||
namespace extensions {
|
||||
|
||||
// TODO(devlin): This is now only used for the MimeTypesHandler API. We should
|
||||
// rename and move it to make that clear. https://crbug.com/890401.
|
||||
class StreamsPrivateAPI {
|
||||
public:
|
||||
// Send the onExecuteMimeTypeHandler event to |extension_id|. If the viewer is
|
||||
// being opened in a BrowserPlugin, specify a non-empty |view_id| of the
|
||||
// plugin. |embedded| should be set to whether the document is embedded
|
||||
// within another document. The |frame_tree_node_id| parameter is used for the
|
||||
// top level plugins case. (PDF, etc). If this parameter has a valid value
|
||||
// then it overrides the |render_process_id| and |render_frame_id| parameters.
|
||||
// The |render_process_id| is the id of the renderer process. The
|
||||
// |render_frame_id| is the routing id of the RenderFrameHost.
|
||||
//
|
||||
// If the network service is not enabled, |stream| is used; otherwise,
|
||||
// |transferrable_loader| and |original_url| are used instead.
|
||||
static void SendExecuteMimeTypeHandlerEvent(
|
||||
const std::string& extension_id,
|
||||
const std::string& view_id,
|
||||
bool embedded,
|
||||
int frame_tree_node_id,
|
||||
int render_process_id,
|
||||
int render_frame_id,
|
||||
content::mojom::TransferrableURLLoaderPtr transferrable_loader,
|
||||
const GURL& original_url);
|
||||
};
|
||||
|
||||
} // namespace extensions
|
||||
|
||||
#endif // SHELL_BROWSER_EXTENSIONS_API_STREAMS_PRIVATE_STREAMS_PRIVATE_API_H_
|
||||
@@ -12,13 +12,48 @@
|
||||
#include "extensions/common/manifest_constants.h"
|
||||
#include "extensions/common/permissions/permissions_data.h"
|
||||
#include "shell/browser/api/electron_api_web_contents.h"
|
||||
#include "shell/browser/web_contents_zoom_controller.h"
|
||||
#include "shell/common/extensions/api/tabs.h"
|
||||
#include "third_party/blink/public/common/page/page_zoom.h"
|
||||
|
||||
using electron::WebContentsZoomController;
|
||||
|
||||
namespace extensions {
|
||||
|
||||
namespace tabs = api::tabs;
|
||||
|
||||
const char kFrameNotFoundError[] = "No frame with id * in tab *.";
|
||||
const char kPerOriginOnlyInAutomaticError[] =
|
||||
"Can only set scope to "
|
||||
"\"per-origin\" in \"automatic\" mode.";
|
||||
|
||||
using api::extension_types::InjectDetails;
|
||||
|
||||
namespace {
|
||||
void ZoomModeToZoomSettings(WebContentsZoomController::ZoomMode zoom_mode,
|
||||
api::tabs::ZoomSettings* zoom_settings) {
|
||||
DCHECK(zoom_settings);
|
||||
switch (zoom_mode) {
|
||||
case WebContentsZoomController::ZoomMode::DEFAULT:
|
||||
zoom_settings->mode = api::tabs::ZOOM_SETTINGS_MODE_AUTOMATIC;
|
||||
zoom_settings->scope = api::tabs::ZOOM_SETTINGS_SCOPE_PER_ORIGIN;
|
||||
break;
|
||||
case WebContentsZoomController::ZoomMode::ISOLATED:
|
||||
zoom_settings->mode = api::tabs::ZOOM_SETTINGS_MODE_AUTOMATIC;
|
||||
zoom_settings->scope = api::tabs::ZOOM_SETTINGS_SCOPE_PER_TAB;
|
||||
break;
|
||||
case WebContentsZoomController::ZoomMode::MANUAL:
|
||||
zoom_settings->mode = api::tabs::ZOOM_SETTINGS_MODE_MANUAL;
|
||||
zoom_settings->scope = api::tabs::ZOOM_SETTINGS_SCOPE_PER_TAB;
|
||||
break;
|
||||
case WebContentsZoomController::ZoomMode::DISABLED:
|
||||
zoom_settings->mode = api::tabs::ZOOM_SETTINGS_MODE_DISABLED;
|
||||
zoom_settings->scope = api::tabs::ZOOM_SETTINGS_SCOPE_PER_TAB;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
ExecuteCodeInTabFunction::ExecuteCodeInTabFunction() : execute_tab_id_(-1) {}
|
||||
|
||||
ExecuteCodeInTabFunction::~ExecuteCodeInTabFunction() {}
|
||||
@@ -130,4 +165,149 @@ bool TabsExecuteScriptFunction::ShouldInsertCSS() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
ExtensionFunction::ResponseAction TabsGetFunction::Run() {
|
||||
std::unique_ptr<tabs::Get::Params> params(tabs::Get::Params::Create(*args_));
|
||||
EXTENSION_FUNCTION_VALIDATE(params.get());
|
||||
int tab_id = params->tab_id;
|
||||
|
||||
auto* contents = electron::api::WebContents::FromWeakMapID(
|
||||
v8::Isolate::GetCurrent(), tab_id);
|
||||
if (!contents)
|
||||
return RespondNow(Error("No such tab"));
|
||||
|
||||
tabs::Tab tab;
|
||||
|
||||
tab.id.reset(new int(tab_id));
|
||||
// TODO(nornagon): in Chrome, the tab URL is only available to extensions
|
||||
// that have the "tabs" (or "activeTab") permission. We should do the same
|
||||
// permission check here.
|
||||
tab.url = std::make_unique<std::string>(
|
||||
contents->web_contents()->GetLastCommittedURL().spec());
|
||||
|
||||
return RespondNow(ArgumentList(tabs::Get::Results::Create(std::move(tab))));
|
||||
}
|
||||
|
||||
ExtensionFunction::ResponseAction TabsSetZoomFunction::Run() {
|
||||
std::unique_ptr<tabs::SetZoom::Params> params(
|
||||
tabs::SetZoom::Params::Create(*args_));
|
||||
EXTENSION_FUNCTION_VALIDATE(params);
|
||||
|
||||
int tab_id = params->tab_id ? *params->tab_id : -1;
|
||||
auto* contents = electron::api::WebContents::FromWeakMapID(
|
||||
v8::Isolate::GetCurrent(), tab_id);
|
||||
if (!contents)
|
||||
return RespondNow(Error("No such tab"));
|
||||
|
||||
auto* web_contents = contents->web_contents();
|
||||
GURL url(web_contents->GetVisibleURL());
|
||||
std::string error;
|
||||
if (extension()->permissions_data()->IsRestrictedUrl(url, &error))
|
||||
return RespondNow(Error(error));
|
||||
|
||||
auto* zoom_controller = contents->GetZoomController();
|
||||
double zoom_level =
|
||||
params->zoom_factor > 0
|
||||
? blink::PageZoomFactorToZoomLevel(params->zoom_factor)
|
||||
: blink::PageZoomFactorToZoomLevel(
|
||||
zoom_controller->GetDefaultZoomFactor());
|
||||
|
||||
zoom_controller->SetZoomLevel(zoom_level);
|
||||
|
||||
return RespondNow(NoArguments());
|
||||
}
|
||||
|
||||
ExtensionFunction::ResponseAction TabsGetZoomFunction::Run() {
|
||||
std::unique_ptr<tabs::GetZoom::Params> params(
|
||||
tabs::GetZoom::Params::Create(*args_));
|
||||
EXTENSION_FUNCTION_VALIDATE(params);
|
||||
|
||||
int tab_id = params->tab_id ? *params->tab_id : -1;
|
||||
auto* contents = electron::api::WebContents::FromWeakMapID(
|
||||
v8::Isolate::GetCurrent(), tab_id);
|
||||
if (!contents)
|
||||
return RespondNow(Error("No such tab"));
|
||||
|
||||
double zoom_level = contents->GetZoomController()->GetZoomLevel();
|
||||
double zoom_factor = blink::PageZoomLevelToZoomFactor(zoom_level);
|
||||
|
||||
return RespondNow(ArgumentList(tabs::GetZoom::Results::Create(zoom_factor)));
|
||||
}
|
||||
|
||||
ExtensionFunction::ResponseAction TabsGetZoomSettingsFunction::Run() {
|
||||
std::unique_ptr<tabs::GetZoomSettings::Params> params(
|
||||
tabs::GetZoomSettings::Params::Create(*args_));
|
||||
EXTENSION_FUNCTION_VALIDATE(params);
|
||||
|
||||
int tab_id = params->tab_id ? *params->tab_id : -1;
|
||||
auto* contents = electron::api::WebContents::FromWeakMapID(
|
||||
v8::Isolate::GetCurrent(), tab_id);
|
||||
if (!contents)
|
||||
return RespondNow(Error("No such tab"));
|
||||
|
||||
auto* zoom_controller = contents->GetZoomController();
|
||||
WebContentsZoomController::ZoomMode zoom_mode =
|
||||
contents->GetZoomController()->zoom_mode();
|
||||
api::tabs::ZoomSettings zoom_settings;
|
||||
ZoomModeToZoomSettings(zoom_mode, &zoom_settings);
|
||||
zoom_settings.default_zoom_factor.reset(
|
||||
new double(blink::PageZoomLevelToZoomFactor(
|
||||
zoom_controller->GetDefaultZoomLevel())));
|
||||
|
||||
return RespondNow(
|
||||
ArgumentList(api::tabs::GetZoomSettings::Results::Create(zoom_settings)));
|
||||
}
|
||||
|
||||
ExtensionFunction::ResponseAction TabsSetZoomSettingsFunction::Run() {
|
||||
using api::tabs::ZoomSettings;
|
||||
|
||||
std::unique_ptr<tabs::SetZoomSettings::Params> params(
|
||||
tabs::SetZoomSettings::Params::Create(*args_));
|
||||
EXTENSION_FUNCTION_VALIDATE(params);
|
||||
|
||||
int tab_id = params->tab_id ? *params->tab_id : -1;
|
||||
auto* contents = electron::api::WebContents::FromWeakMapID(
|
||||
v8::Isolate::GetCurrent(), tab_id);
|
||||
if (!contents)
|
||||
return RespondNow(Error("No such tab"));
|
||||
|
||||
std::string error;
|
||||
GURL url(contents->web_contents()->GetVisibleURL());
|
||||
if (extension()->permissions_data()->IsRestrictedUrl(url, &error))
|
||||
return RespondNow(Error(error));
|
||||
|
||||
// "per-origin" scope is only available in "automatic" mode.
|
||||
if (params->zoom_settings.scope == tabs::ZOOM_SETTINGS_SCOPE_PER_ORIGIN &&
|
||||
params->zoom_settings.mode != tabs::ZOOM_SETTINGS_MODE_AUTOMATIC &&
|
||||
params->zoom_settings.mode != tabs::ZOOM_SETTINGS_MODE_NONE) {
|
||||
return RespondNow(Error(kPerOriginOnlyInAutomaticError));
|
||||
}
|
||||
|
||||
// Determine the correct internal zoom mode to set |web_contents| to from the
|
||||
// user-specified |zoom_settings|.
|
||||
WebContentsZoomController::ZoomMode zoom_mode =
|
||||
WebContentsZoomController::ZoomMode::DEFAULT;
|
||||
switch (params->zoom_settings.mode) {
|
||||
case tabs::ZOOM_SETTINGS_MODE_NONE:
|
||||
case tabs::ZOOM_SETTINGS_MODE_AUTOMATIC:
|
||||
switch (params->zoom_settings.scope) {
|
||||
case tabs::ZOOM_SETTINGS_SCOPE_NONE:
|
||||
case tabs::ZOOM_SETTINGS_SCOPE_PER_ORIGIN:
|
||||
zoom_mode = WebContentsZoomController::ZoomMode::DEFAULT;
|
||||
break;
|
||||
case tabs::ZOOM_SETTINGS_SCOPE_PER_TAB:
|
||||
zoom_mode = WebContentsZoomController::ZoomMode::ISOLATED;
|
||||
}
|
||||
break;
|
||||
case tabs::ZOOM_SETTINGS_MODE_MANUAL:
|
||||
zoom_mode = WebContentsZoomController::ZoomMode::MANUAL;
|
||||
break;
|
||||
case tabs::ZOOM_SETTINGS_MODE_DISABLED:
|
||||
zoom_mode = WebContentsZoomController::ZoomMode::DISABLED;
|
||||
}
|
||||
|
||||
contents->GetZoomController()->SetZoomMode(zoom_mode);
|
||||
|
||||
return RespondNow(NoArguments());
|
||||
}
|
||||
|
||||
} // namespace extensions
|
||||
|
||||
@@ -44,6 +44,48 @@ class TabsExecuteScriptFunction : public ExecuteCodeInTabFunction {
|
||||
DECLARE_EXTENSION_FUNCTION("tabs.executeScript", TABS_EXECUTESCRIPT)
|
||||
};
|
||||
|
||||
class TabsGetFunction : public ExtensionFunction {
|
||||
~TabsGetFunction() override {}
|
||||
ResponseAction Run() override;
|
||||
DECLARE_EXTENSION_FUNCTION("tabs.get", TABS_GET)
|
||||
};
|
||||
|
||||
class TabsSetZoomFunction : public ExtensionFunction {
|
||||
private:
|
||||
~TabsSetZoomFunction() override {}
|
||||
|
||||
ResponseAction Run() override;
|
||||
|
||||
DECLARE_EXTENSION_FUNCTION("tabs.setZoom", TABS_SETZOOM)
|
||||
};
|
||||
|
||||
class TabsGetZoomFunction : public ExtensionFunction {
|
||||
private:
|
||||
~TabsGetZoomFunction() override {}
|
||||
|
||||
ResponseAction Run() override;
|
||||
|
||||
DECLARE_EXTENSION_FUNCTION("tabs.getZoom", TABS_GETZOOM)
|
||||
};
|
||||
|
||||
class TabsSetZoomSettingsFunction : public ExtensionFunction {
|
||||
private:
|
||||
~TabsSetZoomSettingsFunction() override {}
|
||||
|
||||
ResponseAction Run() override;
|
||||
|
||||
DECLARE_EXTENSION_FUNCTION("tabs.setZoomSettings", TABS_SETZOOMSETTINGS)
|
||||
};
|
||||
|
||||
class TabsGetZoomSettingsFunction : public ExtensionFunction {
|
||||
private:
|
||||
~TabsGetZoomSettingsFunction() override {}
|
||||
|
||||
ResponseAction Run() override;
|
||||
|
||||
DECLARE_EXTENSION_FUNCTION("tabs.getZoomSettings", TABS_GETZOOMSETTINGS)
|
||||
};
|
||||
|
||||
} // namespace extensions
|
||||
|
||||
#endif // SHELL_BROWSER_EXTENSIONS_API_TABS_TABS_API_H_
|
||||
|
||||
@@ -5,15 +5,12 @@
|
||||
#include "shell/browser/extensions/electron_browser_context_keyed_service_factories.h"
|
||||
|
||||
#include "extensions/browser/updater/update_service_factory.h"
|
||||
// #include "extensions/shell/browser/api/identity/identity_api.h"
|
||||
#include "shell/browser/extensions/electron_extension_system_factory.h"
|
||||
|
||||
namespace extensions {
|
||||
namespace electron {
|
||||
|
||||
void EnsureBrowserContextKeyedServiceFactoriesBuilt() {
|
||||
// IdentityAPI::GetFactoryInstance();
|
||||
|
||||
// TODO(rockot): Remove this once UpdateService is supported across all
|
||||
// extensions embedders (and namely chrome.)
|
||||
UpdateServiceFactory::GetInstance();
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
// Copyright 2014 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/browser/extensions/electron_component_extension_resource_manager.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "base/path_service.h"
|
||||
#include "base/stl_util.h"
|
||||
#include "base/values.h"
|
||||
#include "build/build_config.h"
|
||||
#include "chrome/common/chrome_paths.h"
|
||||
#include "chrome/grit/component_extension_resources_map.h"
|
||||
|
||||
namespace extensions {
|
||||
|
||||
ElectronComponentExtensionResourceManager::
|
||||
ElectronComponentExtensionResourceManager() {
|
||||
AddComponentResourceEntries(kComponentExtensionResources,
|
||||
kComponentExtensionResourcesSize);
|
||||
}
|
||||
|
||||
ElectronComponentExtensionResourceManager::
|
||||
~ElectronComponentExtensionResourceManager() {}
|
||||
|
||||
bool ElectronComponentExtensionResourceManager::IsComponentExtensionResource(
|
||||
const base::FilePath& extension_path,
|
||||
const base::FilePath& resource_path,
|
||||
int* resource_id) const {
|
||||
base::FilePath directory_path = extension_path;
|
||||
base::FilePath resources_dir;
|
||||
base::FilePath relative_path;
|
||||
if (!base::PathService::Get(chrome::DIR_RESOURCES, &resources_dir) ||
|
||||
!resources_dir.AppendRelativePath(directory_path, &relative_path)) {
|
||||
return false;
|
||||
}
|
||||
relative_path = relative_path.Append(resource_path);
|
||||
relative_path = relative_path.NormalizePathSeparators();
|
||||
|
||||
auto entry = path_to_resource_id_.find(relative_path);
|
||||
if (entry != path_to_resource_id_.end()) {
|
||||
*resource_id = entry->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
const ui::TemplateReplacements*
|
||||
ElectronComponentExtensionResourceManager::GetTemplateReplacementsForExtension(
|
||||
const std::string& extension_id) const {
|
||||
auto it = extension_template_replacements_.find(extension_id);
|
||||
if (it == extension_template_replacements_.end()) {
|
||||
return nullptr;
|
||||
}
|
||||
return &it->second;
|
||||
}
|
||||
|
||||
void ElectronComponentExtensionResourceManager::AddComponentResourceEntries(
|
||||
const GritResourceMap* entries,
|
||||
size_t size) {
|
||||
base::FilePath gen_folder_path = base::FilePath().AppendASCII(
|
||||
"@out_folder@/gen/chrome/browser/resources/");
|
||||
gen_folder_path = gen_folder_path.NormalizePathSeparators();
|
||||
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
base::FilePath resource_path =
|
||||
base::FilePath().AppendASCII(entries[i].name);
|
||||
resource_path = resource_path.NormalizePathSeparators();
|
||||
|
||||
if (!gen_folder_path.IsParent(resource_path)) {
|
||||
DCHECK(!base::Contains(path_to_resource_id_, resource_path));
|
||||
path_to_resource_id_[resource_path] = entries[i].value;
|
||||
} else {
|
||||
// If the resource is a generated file, strip the generated folder's path,
|
||||
// so that it can be served from a normal URL (as if it were not
|
||||
// generated).
|
||||
base::FilePath effective_path =
|
||||
base::FilePath().AppendASCII(resource_path.AsUTF8Unsafe().substr(
|
||||
gen_folder_path.value().length()));
|
||||
DCHECK(!base::Contains(path_to_resource_id_, effective_path));
|
||||
path_to_resource_id_[effective_path] = entries[i].value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace extensions
|
||||
@@ -0,0 +1,50 @@
|
||||
// Copyright 2014 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_BROWSER_EXTENSIONS_ELECTRON_COMPONENT_EXTENSION_RESOURCE_MANAGER_H_
|
||||
#define SHELL_BROWSER_EXTENSIONS_ELECTRON_COMPONENT_EXTENSION_RESOURCE_MANAGER_H_
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/macros.h"
|
||||
#include "extensions/browser/component_extension_resource_manager.h"
|
||||
|
||||
struct GritResourceMap;
|
||||
|
||||
namespace extensions {
|
||||
|
||||
class ElectronComponentExtensionResourceManager
|
||||
: public ComponentExtensionResourceManager {
|
||||
public:
|
||||
ElectronComponentExtensionResourceManager();
|
||||
~ElectronComponentExtensionResourceManager() override;
|
||||
|
||||
// Overridden from ComponentExtensionResourceManager:
|
||||
bool IsComponentExtensionResource(const base::FilePath& extension_path,
|
||||
const base::FilePath& resource_path,
|
||||
int* resource_id) const override;
|
||||
const ui::TemplateReplacements* GetTemplateReplacementsForExtension(
|
||||
const std::string& extension_id) const override;
|
||||
|
||||
private:
|
||||
void AddComponentResourceEntries(const GritResourceMap* entries, size_t size);
|
||||
|
||||
// A map from a resource path to the resource ID. Used by
|
||||
// IsComponentExtensionResource.
|
||||
std::map<base::FilePath, int> path_to_resource_id_;
|
||||
|
||||
// A map from an extension ID to its i18n template replacements.
|
||||
std::map<std::string, ui::TemplateReplacements>
|
||||
extension_template_replacements_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(ElectronComponentExtensionResourceManager);
|
||||
};
|
||||
|
||||
} // namespace extensions
|
||||
|
||||
#endif // SHELL_BROWSER_EXTENSIONS_ELECTRON_COMPONENT_EXTENSION_RESOURCE_MANAGER_H_
|
||||
@@ -49,6 +49,8 @@ class ElectronExtensionLoader : public ExtensionRegistrar::Delegate {
|
||||
void UnloadExtension(const ExtensionId& extension_id,
|
||||
extensions::UnloadedExtensionReason reason);
|
||||
|
||||
ExtensionRegistrar* registrar() { return &extension_registrar_; }
|
||||
|
||||
private:
|
||||
// If the extension loaded successfully, enables it. If it's an app, launches
|
||||
// it. If the load failed, updates ShellKeepAliveRequester.
|
||||
|
||||
@@ -11,7 +11,11 @@
|
||||
#include "base/bind.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/json/json_string_value_serializer.h"
|
||||
#include "base/path_service.h"
|
||||
#include "base/task/post_task.h"
|
||||
#include "chrome/browser/pdf/pdf_extension_util.h"
|
||||
#include "chrome/common/chrome_paths.h"
|
||||
#include "content/public/browser/browser_context.h"
|
||||
#include "content/public/browser/browser_task_traits.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
@@ -84,6 +88,35 @@ void ElectronExtensionSystem::InitForRegularProfile(bool extensions_enabled) {
|
||||
app_sorting_ = std::make_unique<NullAppSorting>();
|
||||
extension_loader_ =
|
||||
std::make_unique<ElectronExtensionLoader>(browser_context_);
|
||||
|
||||
if (!browser_context_->IsOffTheRecord())
|
||||
LoadComponentExtensions();
|
||||
}
|
||||
|
||||
std::unique_ptr<base::DictionaryValue> ParseManifest(
|
||||
base::StringPiece manifest_contents) {
|
||||
JSONStringValueDeserializer deserializer(manifest_contents);
|
||||
std::unique_ptr<base::Value> manifest = deserializer.Deserialize(NULL, NULL);
|
||||
|
||||
if (!manifest.get() || !manifest->is_dict()) {
|
||||
LOG(ERROR) << "Failed to parse extension manifest.";
|
||||
return std::unique_ptr<base::DictionaryValue>();
|
||||
}
|
||||
return base::DictionaryValue::From(std::move(manifest));
|
||||
}
|
||||
|
||||
void ElectronExtensionSystem::LoadComponentExtensions() {
|
||||
std::string utf8_error;
|
||||
std::string pdf_manifest_string = pdf_extension_util::GetManifest();
|
||||
std::unique_ptr<base::DictionaryValue> pdf_manifest =
|
||||
ParseManifest(pdf_manifest_string);
|
||||
base::FilePath root_directory;
|
||||
CHECK(base::PathService::Get(chrome::DIR_RESOURCES, &root_directory));
|
||||
root_directory = root_directory.Append(FILE_PATH_LITERAL("pdf"));
|
||||
scoped_refptr<const Extension> pdf_extension = extensions::Extension::Create(
|
||||
root_directory, extensions::Manifest::COMPONENT, *pdf_manifest,
|
||||
extensions::Extension::REQUIRE_KEY, &utf8_error);
|
||||
extension_loader_->registrar()->AddExtension(pdf_extension);
|
||||
}
|
||||
|
||||
ExtensionService* ElectronExtensionSystem::extension_service() {
|
||||
|
||||
@@ -88,6 +88,8 @@ class ElectronExtensionSystem : public ExtensionSystem {
|
||||
private:
|
||||
void OnExtensionRegisteredWithRequestContexts(
|
||||
scoped_refptr<Extension> extension);
|
||||
void LoadComponentExtensions();
|
||||
|
||||
content::BrowserContext* browser_context_; // Not owned.
|
||||
|
||||
// Data to be accessed on the IO thread. Must outlive process_manager_.
|
||||
|
||||
@@ -5,12 +5,34 @@
|
||||
#include "shell/browser/extensions/electron_extensions_api_client.h"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest_delegate.h"
|
||||
#include "shell/browser/extensions/electron_extension_web_contents_observer.h"
|
||||
#include "shell/browser/extensions/electron_messaging_delegate.h"
|
||||
|
||||
namespace extensions {
|
||||
|
||||
class ElectronMimeHandlerViewGuestDelegate
|
||||
: public MimeHandlerViewGuestDelegate {
|
||||
public:
|
||||
ElectronMimeHandlerViewGuestDelegate() {}
|
||||
~ElectronMimeHandlerViewGuestDelegate() override {}
|
||||
|
||||
// MimeHandlerViewGuestDelegate.
|
||||
bool HandleContextMenu(content::WebContents* web_contents,
|
||||
const content::ContextMenuParams& params) override {
|
||||
// TODO(nornagon): surface this event to JS
|
||||
LOG(INFO) << "HCM";
|
||||
return true;
|
||||
}
|
||||
void RecordLoadMetric(bool in_main_frame,
|
||||
const std::string& mime_type) override {}
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ElectronMimeHandlerViewGuestDelegate);
|
||||
};
|
||||
|
||||
ElectronExtensionsAPIClient::ElectronExtensionsAPIClient() = default;
|
||||
ElectronExtensionsAPIClient::~ElectronExtensionsAPIClient() = default;
|
||||
|
||||
@@ -26,4 +48,10 @@ void ElectronExtensionsAPIClient::AttachWebContentsHelpers(
|
||||
web_contents);
|
||||
}
|
||||
|
||||
std::unique_ptr<MimeHandlerViewGuestDelegate>
|
||||
ElectronExtensionsAPIClient::CreateMimeHandlerViewGuestDelegate(
|
||||
MimeHandlerViewGuest* guest) const {
|
||||
return std::make_unique<ElectronMimeHandlerViewGuestDelegate>();
|
||||
}
|
||||
|
||||
} // namespace extensions
|
||||
|
||||
@@ -22,6 +22,9 @@ class ElectronExtensionsAPIClient : public ExtensionsAPIClient {
|
||||
MessagingDelegate* GetMessagingDelegate() override;
|
||||
void AttachWebContentsHelpers(
|
||||
content::WebContents* web_contents) const override;
|
||||
std::unique_ptr<MimeHandlerViewGuestDelegate>
|
||||
CreateMimeHandlerViewGuestDelegate(
|
||||
MimeHandlerViewGuest* guest) const override;
|
||||
|
||||
private:
|
||||
std::unique_ptr<ElectronMessagingDelegate> messaging_delegate_;
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "shell/browser/extensions/electron_extensions_browser_api_provider.h"
|
||||
|
||||
#include "extensions/browser/extension_function_registry.h"
|
||||
#include "shell/browser/extensions/api/generated_api_registration.h"
|
||||
#include "shell/browser/extensions/api/tabs/tabs_api.h"
|
||||
|
||||
namespace extensions {
|
||||
@@ -16,11 +17,8 @@ ElectronExtensionsBrowserAPIProvider::~ElectronExtensionsBrowserAPIProvider() =
|
||||
|
||||
void ElectronExtensionsBrowserAPIProvider::RegisterExtensionFunctions(
|
||||
ExtensionFunctionRegistry* registry) {
|
||||
registry->RegisterFunction<TabsExecuteScriptFunction>();
|
||||
/*
|
||||
// Generated APIs from Electron.
|
||||
api::ElectronGeneratedFunctionRegistry::RegisterAll(registry);
|
||||
*/
|
||||
}
|
||||
|
||||
} // namespace extensions
|
||||
|
||||
@@ -8,8 +8,12 @@
|
||||
|
||||
#include "base/bind.h"
|
||||
#include "base/memory/ptr_util.h"
|
||||
#include "base/path_service.h"
|
||||
#include "base/task/post_task.h"
|
||||
#include "build/build_config.h"
|
||||
#include "chrome/browser/extensions/chrome_url_request_util.h"
|
||||
#include "chrome/common/chrome_paths.h"
|
||||
#include "chrome/common/extensions/chrome_manifest_url_handlers.h"
|
||||
#include "components/version_info/version_info.h"
|
||||
#include "content/public/browser/browser_context.h"
|
||||
#include "content/public/browser/browser_task_traits.h"
|
||||
@@ -20,17 +24,21 @@
|
||||
#include "extensions/browser/component_extension_resource_manager.h"
|
||||
#include "extensions/browser/core_extensions_browser_api_provider.h"
|
||||
#include "extensions/browser/event_router.h"
|
||||
#include "extensions/browser/extension_protocols.h"
|
||||
#include "extensions/browser/null_app_sorting.h"
|
||||
#include "extensions/browser/updater/null_extension_cache.h"
|
||||
#include "extensions/browser/url_request_util.h"
|
||||
#include "extensions/common/features/feature_channel.h"
|
||||
#include "extensions/common/file_util.h"
|
||||
#include "extensions/common/manifest_constants.h"
|
||||
#include "extensions/common/manifest_url_handlers.h"
|
||||
#include "net/base/mime_util.h"
|
||||
#include "services/network/public/mojom/url_loader.mojom.h"
|
||||
#include "shell/browser/browser.h"
|
||||
#include "shell/browser/electron_browser_client.h"
|
||||
#include "shell/browser/electron_browser_context.h"
|
||||
#include "shell/browser/extensions/api/runtime/electron_runtime_api_delegate.h"
|
||||
#include "shell/browser/extensions/electron_component_extension_resource_manager.h"
|
||||
#include "shell/browser/extensions/electron_extension_host_delegate.h"
|
||||
#include "shell/browser/extensions/electron_extension_system_factory.h"
|
||||
#include "shell/browser/extensions/electron_extension_web_contents_observer.h"
|
||||
@@ -38,9 +46,11 @@
|
||||
#include "shell/browser/extensions/electron_extensions_browser_api_provider.h"
|
||||
#include "shell/browser/extensions/electron_navigation_ui_data.h"
|
||||
#include "shell/browser/extensions/electron_process_manager_delegate.h"
|
||||
#include "ui/base/resource/resource_bundle.h"
|
||||
|
||||
using content::BrowserContext;
|
||||
using content::BrowserThread;
|
||||
using extensions::ExtensionsBrowserClient;
|
||||
|
||||
namespace electron {
|
||||
|
||||
@@ -51,6 +61,8 @@ ElectronExtensionsBrowserClient::ElectronExtensionsBrowserClient()
|
||||
// Electron does not have a concept of channel, so leave UNKNOWN to
|
||||
// enable all channel-dependent extension APIs.
|
||||
extensions::SetCurrentChannel(version_info::Channel::UNKNOWN);
|
||||
resource_manager_.reset(
|
||||
new extensions::ElectronComponentExtensionResourceManager());
|
||||
|
||||
AddAPIProvider(
|
||||
std::make_unique<extensions::CoreExtensionsBrowserAPIProvider>());
|
||||
@@ -127,7 +139,28 @@ base::FilePath ElectronExtensionsBrowserClient::GetBundleResourcePath(
|
||||
const base::FilePath& extension_resources_path,
|
||||
int* resource_id) const {
|
||||
*resource_id = 0;
|
||||
return base::FilePath();
|
||||
base::FilePath chrome_resources_path;
|
||||
if (!base::PathService::Get(chrome::DIR_RESOURCES, &chrome_resources_path))
|
||||
return base::FilePath();
|
||||
|
||||
// Since component extension resources are included in
|
||||
// component_extension_resources.pak file in |chrome_resources_path|,
|
||||
// calculate the extension |request_relative_path| against
|
||||
// |chrome_resources_path|.
|
||||
if (!chrome_resources_path.IsParent(extension_resources_path))
|
||||
return base::FilePath();
|
||||
|
||||
const base::FilePath request_relative_path =
|
||||
extensions::file_util::ExtensionURLToRelativeFilePath(request.url);
|
||||
if (!ExtensionsBrowserClient::Get()
|
||||
->GetComponentExtensionResourceManager()
|
||||
->IsComponentExtensionResource(extension_resources_path,
|
||||
request_relative_path, resource_id)) {
|
||||
return base::FilePath();
|
||||
}
|
||||
DCHECK_NE(0, *resource_id);
|
||||
|
||||
return request_relative_path;
|
||||
}
|
||||
|
||||
void ElectronExtensionsBrowserClient::LoadResourceFromResourceBundle(
|
||||
@@ -138,7 +171,9 @@ void ElectronExtensionsBrowserClient::LoadResourceFromResourceBundle(
|
||||
const std::string& content_security_policy,
|
||||
mojo::PendingRemote<network::mojom::URLLoaderClient> client,
|
||||
bool send_cors_header) {
|
||||
NOTREACHED() << "Load resources from bundles not supported.";
|
||||
extensions::chrome_url_request_util::LoadResourceFromResourceBundle(
|
||||
request, std::move(loader), resource_relative_path, resource_id,
|
||||
content_security_policy, std::move(client), send_cors_header);
|
||||
}
|
||||
|
||||
namespace {
|
||||
@@ -160,8 +195,7 @@ bool AllowCrossRendererResourceLoad(const GURL& url,
|
||||
// If there aren't any explicitly marked web accessible resources, the
|
||||
// load should be allowed only if it is by DevTools. A close approximation is
|
||||
// checking if the extension contains a DevTools page.
|
||||
if (extension && !extensions::ManifestURL::Get(
|
||||
extension, extensions::manifest_keys::kDevToolsPage)
|
||||
if (extension && !extensions::chrome_manifest_urls::GetDevToolsPage(extension)
|
||||
.is_empty()) {
|
||||
*allowed = true;
|
||||
return true;
|
||||
@@ -255,7 +289,7 @@ ElectronExtensionsBrowserClient::CreateRuntimeAPIDelegate(
|
||||
|
||||
const extensions::ComponentExtensionResourceManager*
|
||||
ElectronExtensionsBrowserClient::GetComponentExtensionResourceManager() {
|
||||
return NULL;
|
||||
return resource_manager_.get();
|
||||
}
|
||||
|
||||
void ElectronExtensionsBrowserClient::BroadcastEventToRenderers(
|
||||
|
||||
@@ -23,6 +23,7 @@ class KioskDelegate;
|
||||
class ProcessManagerDelegate;
|
||||
class ElectronProcessManagerDelegate;
|
||||
class ProcessMap;
|
||||
class ElectronComponentExtensionResourceManager;
|
||||
} // namespace extensions
|
||||
|
||||
namespace electron {
|
||||
@@ -138,6 +139,9 @@ class ElectronExtensionsBrowserClient
|
||||
// The extension cache used for download and installation.
|
||||
std::unique_ptr<extensions::ExtensionCache> extension_cache_;
|
||||
|
||||
std::unique_ptr<extensions::ElectronComponentExtensionResourceManager>
|
||||
resource_manager_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(ElectronExtensionsBrowserClient);
|
||||
};
|
||||
|
||||
|
||||
@@ -9,9 +9,9 @@
|
||||
#import <AVFoundation/AVFoundation.h>
|
||||
#import <LocalAuthentication/LocalAuthentication.h>
|
||||
|
||||
@interface ElectronApplication : NSApplication <CrAppProtocol,
|
||||
CrAppControlProtocol,
|
||||
NSUserActivityDelegate> {
|
||||
@interface AtomApplication : NSApplication <CrAppProtocol,
|
||||
CrAppControlProtocol,
|
||||
NSUserActivityDelegate> {
|
||||
@private
|
||||
BOOL handlingSendEvent_;
|
||||
base::scoped_nsobject<NSUserActivity> currentActivity_;
|
||||
@@ -20,7 +20,7 @@
|
||||
base::Callback<bool()> shouldShutdown_;
|
||||
}
|
||||
|
||||
+ (ElectronApplication*)sharedApplication;
|
||||
+ (AtomApplication*)sharedApplication;
|
||||
|
||||
- (void)setShutdownHandler:(base::Callback<bool()>)handler;
|
||||
- (void)registerURLHandler;
|
||||
|
||||
@@ -29,16 +29,16 @@ inline void dispatch_sync_main(dispatch_block_t block) {
|
||||
|
||||
} // namespace
|
||||
|
||||
@interface ElectronApplication () <NativeEventProcessor> {
|
||||
@interface AtomApplication () <NativeEventProcessor> {
|
||||
base::ObserverList<content::NativeEventProcessorObserver>::Unchecked
|
||||
observers_;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation ElectronApplication
|
||||
@implementation AtomApplication
|
||||
|
||||
+ (ElectronApplication*)sharedApplication {
|
||||
return (ElectronApplication*)[super sharedApplication];
|
||||
+ (AtomApplication*)sharedApplication {
|
||||
return (AtomApplication*)[super sharedApplication];
|
||||
}
|
||||
|
||||
- (void)terminate:(id)sender {
|
||||
|
||||
@@ -542,17 +542,27 @@ void NativeWindowMac::RepositionTrafficLights() {
|
||||
CGFloat buttonHeight = [close frame].size.height;
|
||||
CGFloat titleBarFrameHeight = buttonHeight + traffic_light_position_.y();
|
||||
CGRect titleBarRect = titleBarContainerView.frame;
|
||||
CGFloat titleBarWidth = NSWidth(titleBarRect);
|
||||
titleBarRect.size.height = titleBarFrameHeight;
|
||||
titleBarRect.origin.y = window.frame.size.height - titleBarFrameHeight;
|
||||
[titleBarContainerView setFrame:titleBarRect];
|
||||
|
||||
BOOL isRTL = [titleBarContainerView userInterfaceLayoutDirection] ==
|
||||
NSUserInterfaceLayoutDirectionRightToLeft;
|
||||
NSArray* windowButtons = @[ close, miniaturize, zoom ];
|
||||
const CGFloat space_between =
|
||||
[miniaturize frame].origin.x - [close frame].origin.x;
|
||||
for (NSUInteger i = 0; i < windowButtons.count; i++) {
|
||||
NSView* view = [windowButtons objectAtIndex:i];
|
||||
CGRect rect = [view frame];
|
||||
rect.origin.x = traffic_light_position_.x() + (i * space_between);
|
||||
if (isRTL) {
|
||||
CGFloat buttonWidth = NSWidth(rect);
|
||||
// origin is always top-left, even in RTL
|
||||
rect.origin.x = titleBarWidth - traffic_light_position_.x() +
|
||||
(i * space_between) - buttonWidth;
|
||||
} else {
|
||||
rect.origin.x = traffic_light_position_.x() + (i * space_between);
|
||||
}
|
||||
rect.origin.y = (titleBarFrameHeight - rect.size.height) / 2;
|
||||
[view setFrameOrigin:rect.origin];
|
||||
}
|
||||
@@ -1455,8 +1465,7 @@ void NativeWindowMac::SetVibrancy(const std::string& type) {
|
||||
relativeTo:nil];
|
||||
}
|
||||
|
||||
std::string dep_warn =
|
||||
" has been deprecated and will be removed in a future version of macOS.";
|
||||
std::string dep_warn = " has been deprecated and removed as of macOS 10.15.";
|
||||
node::Environment* env =
|
||||
node::Environment::GetCurrent(v8::Isolate::GetCurrent());
|
||||
|
||||
@@ -1477,61 +1486,44 @@ void NativeWindowMac::SetVibrancy(const std::string& type) {
|
||||
}
|
||||
|
||||
if (@available(macOS 10.11, *)) {
|
||||
// TODO(codebytere): Use NSVisualEffectMaterial* constants directly once
|
||||
// they are available in the minimum SDK version
|
||||
if (type == "selection") {
|
||||
// NSVisualEffectMaterialSelection
|
||||
vibrancyType = static_cast<NSVisualEffectMaterial>(4);
|
||||
vibrancyType = NSVisualEffectMaterialSelection;
|
||||
} else if (type == "menu") {
|
||||
// NSVisualEffectMaterialMenu
|
||||
vibrancyType = static_cast<NSVisualEffectMaterial>(5);
|
||||
vibrancyType = NSVisualEffectMaterialMenu;
|
||||
} else if (type == "popover") {
|
||||
// NSVisualEffectMaterialPopover
|
||||
vibrancyType = static_cast<NSVisualEffectMaterial>(6);
|
||||
vibrancyType = NSVisualEffectMaterialPopover;
|
||||
} else if (type == "sidebar") {
|
||||
// NSVisualEffectMaterialSidebar
|
||||
vibrancyType = static_cast<NSVisualEffectMaterial>(7);
|
||||
vibrancyType = NSVisualEffectMaterialSidebar;
|
||||
} else if (type == "medium-light") {
|
||||
// NSVisualEffectMaterialMediumLight
|
||||
EmitWarning(env, "NSVisualEffectMaterialMediumLight" + dep_warn,
|
||||
"electron");
|
||||
vibrancyType = static_cast<NSVisualEffectMaterial>(8);
|
||||
vibrancyType = NSVisualEffectMaterialMediumLight;
|
||||
} else if (type == "ultra-dark") {
|
||||
// NSVisualEffectMaterialUltraDark
|
||||
EmitWarning(env, "NSVisualEffectMaterialUltraDark" + dep_warn,
|
||||
"electron");
|
||||
vibrancyType = static_cast<NSVisualEffectMaterial>(9);
|
||||
vibrancyType = NSVisualEffectMaterialUltraDark;
|
||||
}
|
||||
}
|
||||
|
||||
if (@available(macOS 10.14, *)) {
|
||||
if (type == "header") {
|
||||
// NSVisualEffectMaterialHeaderView
|
||||
vibrancyType = static_cast<NSVisualEffectMaterial>(10);
|
||||
vibrancyType = NSVisualEffectMaterialHeaderView;
|
||||
} else if (type == "sheet") {
|
||||
// NSVisualEffectMaterialSheet
|
||||
vibrancyType = static_cast<NSVisualEffectMaterial>(11);
|
||||
vibrancyType = NSVisualEffectMaterialSheet;
|
||||
} else if (type == "window") {
|
||||
// NSVisualEffectMaterialWindowBackground
|
||||
vibrancyType = static_cast<NSVisualEffectMaterial>(12);
|
||||
vibrancyType = NSVisualEffectMaterialWindowBackground;
|
||||
} else if (type == "hud") {
|
||||
// NSVisualEffectMaterialHUDWindow
|
||||
vibrancyType = static_cast<NSVisualEffectMaterial>(13);
|
||||
vibrancyType = NSVisualEffectMaterialHUDWindow;
|
||||
} else if (type == "fullscreen-ui") {
|
||||
// NSVisualEffectMaterialFullScreenUI
|
||||
vibrancyType = static_cast<NSVisualEffectMaterial>(16);
|
||||
vibrancyType = NSVisualEffectMaterialFullScreenUI;
|
||||
} else if (type == "tooltip") {
|
||||
// NSVisualEffectMaterialToolTip
|
||||
vibrancyType = static_cast<NSVisualEffectMaterial>(17);
|
||||
vibrancyType = NSVisualEffectMaterialToolTip;
|
||||
} else if (type == "content") {
|
||||
// NSVisualEffectMaterialContentBackground
|
||||
vibrancyType = static_cast<NSVisualEffectMaterial>(18);
|
||||
vibrancyType = NSVisualEffectMaterialContentBackground;
|
||||
} else if (type == "under-window") {
|
||||
// NSVisualEffectMaterialUnderWindowBackground
|
||||
vibrancyType = static_cast<NSVisualEffectMaterial>(21);
|
||||
vibrancyType = NSVisualEffectMaterialUnderWindowBackground;
|
||||
} else if (type == "under-page") {
|
||||
// NSVisualEffectMaterialUnderPageBackground
|
||||
vibrancyType = static_cast<NSVisualEffectMaterial>(22);
|
||||
vibrancyType = NSVisualEffectMaterialUnderPageBackground;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,13 +20,6 @@
|
||||
#include "shell/common/options_switches.h"
|
||||
|
||||
namespace electron {
|
||||
|
||||
namespace {
|
||||
|
||||
int64_t g_request_id = 0;
|
||||
|
||||
} // namespace
|
||||
|
||||
ProxyingURLLoaderFactory::InProgressRequest::FollowRedirectParams::
|
||||
FollowRedirectParams() = default;
|
||||
ProxyingURLLoaderFactory::InProgressRequest::FollowRedirectParams::
|
||||
@@ -677,6 +670,7 @@ ProxyingURLLoaderFactory::ProxyingURLLoaderFactory(
|
||||
const HandlersMap& intercepted_handlers,
|
||||
content::BrowserContext* browser_context,
|
||||
int render_process_id,
|
||||
uint64_t* request_id_generator,
|
||||
std::unique_ptr<extensions::ExtensionNavigationUIData> navigation_ui_data,
|
||||
base::Optional<int64_t> navigation_id,
|
||||
network::mojom::URLLoaderFactoryRequest loader_request,
|
||||
@@ -688,6 +682,7 @@ ProxyingURLLoaderFactory::ProxyingURLLoaderFactory(
|
||||
intercepted_handlers_(intercepted_handlers),
|
||||
browser_context_(browser_context),
|
||||
render_process_id_(render_process_id),
|
||||
request_id_generator_(request_id_generator),
|
||||
navigation_ui_data_(std::move(navigation_ui_data)),
|
||||
navigation_id_(std::move(navigation_id)),
|
||||
loader_factory_type_(loader_factory_type) {
|
||||
@@ -765,7 +760,7 @@ void ProxyingURLLoaderFactory::CreateLoaderAndStart(
|
||||
// per-BrowserContext so extensions can make sense of it. Note that
|
||||
// |network_service_request_id_| by contrast is not necessarily unique, so we
|
||||
// don't use it for identity here.
|
||||
const uint64_t web_request_id = ++g_request_id;
|
||||
const uint64_t web_request_id = ++(*request_id_generator_);
|
||||
|
||||
// Notes: Chromium assumes that requests with zero-ID would never use the
|
||||
// "extraHeaders" code path, however in Electron requests started from
|
||||
|
||||
@@ -23,53 +23,12 @@
|
||||
#include "services/network/public/mojom/network_context.mojom.h"
|
||||
#include "services/network/public/mojom/url_loader.mojom.h"
|
||||
#include "services/network/public/mojom/url_response_head.mojom.h"
|
||||
#include "shell/browser/api/electron_api_web_request.h"
|
||||
#include "shell/browser/net/electron_url_loader_factory.h"
|
||||
#include "shell/browser/net/web_request_api_interface.h"
|
||||
|
||||
namespace electron {
|
||||
|
||||
// Defines the interface for WebRequest API, implemented by api::WebRequest.
|
||||
class WebRequestAPI {
|
||||
public:
|
||||
virtual ~WebRequestAPI() {}
|
||||
|
||||
using BeforeSendHeadersCallback =
|
||||
base::OnceCallback<void(const std::set<std::string>& removed_headers,
|
||||
const std::set<std::string>& set_headers,
|
||||
int error_code)>;
|
||||
|
||||
virtual bool HasListener() const = 0;
|
||||
virtual int OnBeforeRequest(extensions::WebRequestInfo* info,
|
||||
const network::ResourceRequest& request,
|
||||
net::CompletionOnceCallback callback,
|
||||
GURL* new_url) = 0;
|
||||
virtual int OnBeforeSendHeaders(extensions::WebRequestInfo* info,
|
||||
const network::ResourceRequest& request,
|
||||
BeforeSendHeadersCallback callback,
|
||||
net::HttpRequestHeaders* headers) = 0;
|
||||
virtual int OnHeadersReceived(
|
||||
extensions::WebRequestInfo* info,
|
||||
const network::ResourceRequest& request,
|
||||
net::CompletionOnceCallback callback,
|
||||
const net::HttpResponseHeaders* original_response_headers,
|
||||
scoped_refptr<net::HttpResponseHeaders>* override_response_headers,
|
||||
GURL* allowed_unsafe_redirect_url) = 0;
|
||||
virtual void OnSendHeaders(extensions::WebRequestInfo* info,
|
||||
const network::ResourceRequest& request,
|
||||
const net::HttpRequestHeaders& headers) = 0;
|
||||
virtual void OnBeforeRedirect(extensions::WebRequestInfo* info,
|
||||
const network::ResourceRequest& request,
|
||||
const GURL& new_location) = 0;
|
||||
virtual void OnResponseStarted(extensions::WebRequestInfo* info,
|
||||
const network::ResourceRequest& request) = 0;
|
||||
virtual void OnErrorOccurred(extensions::WebRequestInfo* info,
|
||||
const network::ResourceRequest& request,
|
||||
int net_error) = 0;
|
||||
virtual void OnCompleted(extensions::WebRequestInfo* info,
|
||||
const network::ResourceRequest& request,
|
||||
int net_error) = 0;
|
||||
virtual void OnRequestWillBeDestroyed(extensions::WebRequestInfo* info) = 0;
|
||||
};
|
||||
|
||||
// This class is responsible for following tasks when NetworkService is enabled:
|
||||
// 1. handling intercepted protocols;
|
||||
// 2. implementing webRequest module;
|
||||
@@ -210,6 +169,7 @@ class ProxyingURLLoaderFactory
|
||||
const HandlersMap& intercepted_handlers,
|
||||
content::BrowserContext* browser_context,
|
||||
int render_process_id,
|
||||
uint64_t* request_id_generator,
|
||||
std::unique_ptr<extensions::ExtensionNavigationUIData> navigation_ui_data,
|
||||
base::Optional<int64_t> navigation_id,
|
||||
network::mojom::URLLoaderFactoryRequest loader_request,
|
||||
@@ -269,6 +229,7 @@ class ProxyingURLLoaderFactory
|
||||
|
||||
content::BrowserContext* const browser_context_;
|
||||
const int render_process_id_;
|
||||
uint64_t* request_id_generator_; // managed by AtomBrowserClient
|
||||
std::unique_ptr<extensions::ExtensionNavigationUIData> navigation_ui_data_;
|
||||
base::Optional<int64_t> navigation_id_;
|
||||
mojo::ReceiverSet<network::mojom::URLLoaderFactory> proxy_receivers_;
|
||||
|
||||
456
shell/browser/net/proxying_websocket.cc
Normal file
456
shell/browser/net/proxying_websocket.cc
Normal file
@@ -0,0 +1,456 @@
|
||||
// Copyright 2020 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 "electron/shell/browser/net/proxying_websocket.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "base/bind.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/strings/stringprintf.h"
|
||||
#include "components/keyed_service/content/browser_context_keyed_service_shutdown_notifier_factory.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "extensions/browser/extension_navigation_ui_data.h"
|
||||
#include "net/base/ip_endpoint.h"
|
||||
#include "net/http/http_util.h"
|
||||
|
||||
namespace electron {
|
||||
|
||||
ProxyingWebSocket::ProxyingWebSocket(
|
||||
WebRequestAPI* web_request_api,
|
||||
WebSocketFactory factory,
|
||||
const network::ResourceRequest& request,
|
||||
mojo::PendingRemote<network::mojom::WebSocketHandshakeClient>
|
||||
handshake_client,
|
||||
bool has_extra_headers,
|
||||
int process_id,
|
||||
int render_frame_id,
|
||||
content::BrowserContext* browser_context,
|
||||
uint64_t* request_id_generator)
|
||||
: web_request_api_(web_request_api),
|
||||
request_(request),
|
||||
factory_(std::move(factory)),
|
||||
forwarding_handshake_client_(std::move(handshake_client)),
|
||||
request_headers_(request.headers),
|
||||
response_(network::mojom::URLResponseHead::New()),
|
||||
has_extra_headers_(has_extra_headers),
|
||||
info_(extensions::WebRequestInfoInitParams(
|
||||
++(*request_id_generator),
|
||||
process_id,
|
||||
render_frame_id,
|
||||
nullptr,
|
||||
MSG_ROUTING_NONE,
|
||||
request,
|
||||
/*is_download=*/false,
|
||||
/*is_async=*/true,
|
||||
/*is_service_worker_script=*/false,
|
||||
/*navigation_id=*/base::nullopt)) {}
|
||||
|
||||
ProxyingWebSocket::~ProxyingWebSocket() {
|
||||
if (on_before_send_headers_callback_) {
|
||||
std::move(on_before_send_headers_callback_)
|
||||
.Run(net::ERR_ABORTED, base::nullopt);
|
||||
}
|
||||
if (on_headers_received_callback_) {
|
||||
std::move(on_headers_received_callback_)
|
||||
.Run(net::ERR_ABORTED, base::nullopt, GURL());
|
||||
}
|
||||
}
|
||||
|
||||
void ProxyingWebSocket::Start() {
|
||||
// If the header client will be used, we start the request immediately, and
|
||||
// OnBeforeSendHeaders and OnSendHeaders will be handled there. Otherwise,
|
||||
// send these events before the request starts.
|
||||
base::RepeatingCallback<void(int)> continuation;
|
||||
if (has_extra_headers_) {
|
||||
continuation = base::BindRepeating(
|
||||
&ProxyingWebSocket::ContinueToStartRequest, weak_factory_.GetWeakPtr());
|
||||
} else {
|
||||
continuation =
|
||||
base::BindRepeating(&ProxyingWebSocket::OnBeforeRequestComplete,
|
||||
weak_factory_.GetWeakPtr());
|
||||
}
|
||||
|
||||
int result = web_request_api_->OnBeforeRequest(&info_, request_, continuation,
|
||||
&redirect_url_);
|
||||
|
||||
if (result == net::ERR_BLOCKED_BY_CLIENT) {
|
||||
OnError(result);
|
||||
return;
|
||||
}
|
||||
|
||||
if (result == net::ERR_IO_PENDING) {
|
||||
return;
|
||||
}
|
||||
|
||||
DCHECK_EQ(net::OK, result);
|
||||
continuation.Run(net::OK);
|
||||
}
|
||||
|
||||
void ProxyingWebSocket::OnOpeningHandshakeStarted(
|
||||
network::mojom::WebSocketHandshakeRequestPtr request) {
|
||||
DCHECK(forwarding_handshake_client_);
|
||||
forwarding_handshake_client_->OnOpeningHandshakeStarted(std::move(request));
|
||||
}
|
||||
|
||||
void ProxyingWebSocket::ContinueToHeadersReceived() {
|
||||
auto continuation =
|
||||
base::BindRepeating(&ProxyingWebSocket::OnHeadersReceivedComplete,
|
||||
weak_factory_.GetWeakPtr());
|
||||
info_.AddResponseInfoFromResourceResponse(*response_);
|
||||
int result = web_request_api_->OnHeadersReceived(
|
||||
&info_, request_, continuation, response_->headers.get(),
|
||||
&override_headers_, &redirect_url_);
|
||||
|
||||
if (result == net::ERR_BLOCKED_BY_CLIENT) {
|
||||
OnError(result);
|
||||
return;
|
||||
}
|
||||
|
||||
PauseIncomingMethodCallProcessing();
|
||||
if (result == net::ERR_IO_PENDING)
|
||||
return;
|
||||
|
||||
DCHECK_EQ(net::OK, result);
|
||||
OnHeadersReceivedComplete(net::OK);
|
||||
}
|
||||
|
||||
void ProxyingWebSocket::OnConnectionEstablished(
|
||||
mojo::PendingRemote<network::mojom::WebSocket> websocket,
|
||||
mojo::PendingReceiver<network::mojom::WebSocketClient> client_receiver,
|
||||
network::mojom::WebSocketHandshakeResponsePtr response,
|
||||
mojo::ScopedDataPipeConsumerHandle readable) {
|
||||
DCHECK(forwarding_handshake_client_);
|
||||
DCHECK(!is_done_);
|
||||
is_done_ = true;
|
||||
websocket_ = std::move(websocket);
|
||||
client_receiver_ = std::move(client_receiver);
|
||||
handshake_response_ = std::move(response);
|
||||
readable_ = std::move(readable);
|
||||
|
||||
response_->remote_endpoint = handshake_response_->remote_endpoint;
|
||||
|
||||
// response_->headers will be set in OnBeforeSendHeaders if
|
||||
// |receiver_as_header_client_| is set.
|
||||
if (receiver_as_header_client_.is_bound()) {
|
||||
ContinueToCompleted();
|
||||
return;
|
||||
}
|
||||
|
||||
response_->headers =
|
||||
base::MakeRefCounted<net::HttpResponseHeaders>(base::StringPrintf(
|
||||
"HTTP/%d.%d %d %s", handshake_response_->http_version.major_value(),
|
||||
handshake_response_->http_version.minor_value(),
|
||||
handshake_response_->status_code,
|
||||
handshake_response_->status_text.c_str()));
|
||||
for (const auto& header : handshake_response_->headers)
|
||||
response_->headers->AddHeader(header->name + ": " + header->value);
|
||||
|
||||
ContinueToHeadersReceived();
|
||||
}
|
||||
|
||||
void ProxyingWebSocket::ContinueToCompleted() {
|
||||
DCHECK(forwarding_handshake_client_);
|
||||
DCHECK(is_done_);
|
||||
web_request_api_->OnCompleted(&info_, request_, net::ERR_WS_UPGRADE);
|
||||
forwarding_handshake_client_->OnConnectionEstablished(
|
||||
std::move(websocket_), std::move(client_receiver_),
|
||||
std::move(handshake_response_), std::move(readable_));
|
||||
|
||||
// Deletes |this|.
|
||||
delete this;
|
||||
}
|
||||
|
||||
void ProxyingWebSocket::OnAuthRequired(
|
||||
const net::AuthChallengeInfo& auth_info,
|
||||
const scoped_refptr<net::HttpResponseHeaders>& headers,
|
||||
const net::IPEndPoint& remote_endpoint,
|
||||
OnAuthRequiredCallback callback) {
|
||||
if (!callback) {
|
||||
OnError(net::ERR_FAILED);
|
||||
return;
|
||||
}
|
||||
|
||||
response_->headers = headers;
|
||||
response_->remote_endpoint = remote_endpoint;
|
||||
auth_required_callback_ = std::move(callback);
|
||||
|
||||
auto continuation =
|
||||
base::BindRepeating(&ProxyingWebSocket::OnHeadersReceivedCompleteForAuth,
|
||||
weak_factory_.GetWeakPtr(), auth_info);
|
||||
info_.AddResponseInfoFromResourceResponse(*response_);
|
||||
int result = web_request_api_->OnHeadersReceived(
|
||||
&info_, request_, continuation, response_->headers.get(),
|
||||
&override_headers_, &redirect_url_);
|
||||
|
||||
if (result == net::ERR_BLOCKED_BY_CLIENT) {
|
||||
OnError(result);
|
||||
return;
|
||||
}
|
||||
|
||||
PauseIncomingMethodCallProcessing();
|
||||
if (result == net::ERR_IO_PENDING)
|
||||
return;
|
||||
|
||||
DCHECK_EQ(net::OK, result);
|
||||
OnHeadersReceivedCompleteForAuth(auth_info, net::OK);
|
||||
}
|
||||
|
||||
void ProxyingWebSocket::OnBeforeSendHeaders(
|
||||
const net::HttpRequestHeaders& headers,
|
||||
OnBeforeSendHeadersCallback callback) {
|
||||
DCHECK(receiver_as_header_client_.is_bound());
|
||||
|
||||
request_headers_ = headers;
|
||||
on_before_send_headers_callback_ = std::move(callback);
|
||||
OnBeforeRequestComplete(net::OK);
|
||||
}
|
||||
|
||||
void ProxyingWebSocket::OnHeadersReceived(const std::string& headers,
|
||||
const net::IPEndPoint& endpoint,
|
||||
OnHeadersReceivedCallback callback) {
|
||||
DCHECK(receiver_as_header_client_.is_bound());
|
||||
|
||||
on_headers_received_callback_ = std::move(callback);
|
||||
response_->headers = base::MakeRefCounted<net::HttpResponseHeaders>(headers);
|
||||
|
||||
ContinueToHeadersReceived();
|
||||
}
|
||||
|
||||
void ProxyingWebSocket::StartProxying(
|
||||
WebRequestAPI* web_request_api,
|
||||
WebSocketFactory factory,
|
||||
const GURL& url,
|
||||
const GURL& site_for_cookies,
|
||||
const base::Optional<std::string>& user_agent,
|
||||
mojo::PendingRemote<network::mojom::WebSocketHandshakeClient>
|
||||
handshake_client,
|
||||
bool has_extra_headers,
|
||||
int process_id,
|
||||
int render_frame_id,
|
||||
const url::Origin& origin,
|
||||
content::BrowserContext* browser_context,
|
||||
uint64_t* request_id_generator) {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
network::ResourceRequest request;
|
||||
request.url = url;
|
||||
request.site_for_cookies = net::SiteForCookies::FromUrl(site_for_cookies);
|
||||
if (user_agent) {
|
||||
request.headers.SetHeader(net::HttpRequestHeaders::kUserAgent, *user_agent);
|
||||
}
|
||||
request.request_initiator = origin;
|
||||
|
||||
auto* proxy = new ProxyingWebSocket(
|
||||
web_request_api, std::move(factory), request, std::move(handshake_client),
|
||||
has_extra_headers, process_id, render_frame_id, browser_context,
|
||||
request_id_generator);
|
||||
proxy->Start();
|
||||
}
|
||||
|
||||
void ProxyingWebSocket::OnBeforeRequestComplete(int error_code) {
|
||||
DCHECK(receiver_as_header_client_.is_bound() ||
|
||||
!receiver_as_handshake_client_.is_bound());
|
||||
DCHECK(info_.url.SchemeIsWSOrWSS());
|
||||
if (error_code != net::OK) {
|
||||
OnError(error_code);
|
||||
return;
|
||||
}
|
||||
|
||||
auto continuation =
|
||||
base::BindRepeating(&ProxyingWebSocket::OnBeforeSendHeadersComplete,
|
||||
weak_factory_.GetWeakPtr());
|
||||
|
||||
info_.AddResponseInfoFromResourceResponse(*response_);
|
||||
int result = web_request_api_->OnBeforeSendHeaders(
|
||||
&info_, request_, continuation, &request_headers_);
|
||||
|
||||
if (result == net::ERR_BLOCKED_BY_CLIENT) {
|
||||
OnError(result);
|
||||
return;
|
||||
}
|
||||
|
||||
if (result == net::ERR_IO_PENDING)
|
||||
return;
|
||||
|
||||
DCHECK_EQ(net::OK, result);
|
||||
OnBeforeSendHeadersComplete(std::set<std::string>(), std::set<std::string>(),
|
||||
net::OK);
|
||||
}
|
||||
|
||||
void ProxyingWebSocket::OnBeforeSendHeadersComplete(
|
||||
const std::set<std::string>& removed_headers,
|
||||
const std::set<std::string>& set_headers,
|
||||
int error_code) {
|
||||
DCHECK(receiver_as_header_client_.is_bound() ||
|
||||
!receiver_as_handshake_client_.is_bound());
|
||||
if (error_code != net::OK) {
|
||||
OnError(error_code);
|
||||
return;
|
||||
}
|
||||
|
||||
if (receiver_as_header_client_.is_bound()) {
|
||||
CHECK(on_before_send_headers_callback_);
|
||||
std::move(on_before_send_headers_callback_)
|
||||
.Run(error_code, request_headers_);
|
||||
}
|
||||
|
||||
info_.AddResponseInfoFromResourceResponse(*response_);
|
||||
web_request_api_->OnSendHeaders(&info_, request_, request_headers_);
|
||||
|
||||
if (!receiver_as_header_client_.is_bound())
|
||||
ContinueToStartRequest(net::OK);
|
||||
}
|
||||
|
||||
void ProxyingWebSocket::ContinueToStartRequest(int error_code) {
|
||||
if (error_code != net::OK) {
|
||||
OnError(error_code);
|
||||
return;
|
||||
}
|
||||
|
||||
base::flat_set<std::string> used_header_names;
|
||||
std::vector<network::mojom::HttpHeaderPtr> additional_headers;
|
||||
for (net::HttpRequestHeaders::Iterator it(request_headers_); it.GetNext();) {
|
||||
additional_headers.push_back(
|
||||
network::mojom::HttpHeader::New(it.name(), it.value()));
|
||||
used_header_names.insert(base::ToLowerASCII(it.name()));
|
||||
}
|
||||
for (const auto& header : additional_headers_) {
|
||||
if (!used_header_names.contains(base::ToLowerASCII(header->name))) {
|
||||
additional_headers.push_back(
|
||||
network::mojom::HttpHeader::New(header->name, header->value));
|
||||
}
|
||||
}
|
||||
|
||||
mojo::PendingRemote<network::mojom::TrustedHeaderClient>
|
||||
trusted_header_client = mojo::NullRemote();
|
||||
if (has_extra_headers_) {
|
||||
trusted_header_client =
|
||||
receiver_as_header_client_.BindNewPipeAndPassRemote();
|
||||
}
|
||||
|
||||
std::move(factory_).Run(
|
||||
info_.url, std::move(additional_headers),
|
||||
receiver_as_handshake_client_.BindNewPipeAndPassRemote(),
|
||||
receiver_as_auth_handler_.BindNewPipeAndPassRemote(),
|
||||
std::move(trusted_header_client));
|
||||
|
||||
// Here we detect mojo connection errors on |receiver_as_handshake_client_|.
|
||||
// See also CreateWebSocket in
|
||||
// //network/services/public/mojom/network_context.mojom.
|
||||
receiver_as_handshake_client_.set_disconnect_with_reason_handler(
|
||||
base::BindOnce(&ProxyingWebSocket::OnMojoConnectionErrorWithCustomReason,
|
||||
base::Unretained(this)));
|
||||
forwarding_handshake_client_.set_disconnect_handler(base::BindOnce(
|
||||
&ProxyingWebSocket::OnMojoConnectionError, base::Unretained(this)));
|
||||
}
|
||||
|
||||
void ProxyingWebSocket::OnHeadersReceivedComplete(int error_code) {
|
||||
if (error_code != net::OK) {
|
||||
OnError(error_code);
|
||||
return;
|
||||
}
|
||||
|
||||
if (on_headers_received_callback_) {
|
||||
base::Optional<std::string> headers;
|
||||
if (override_headers_)
|
||||
headers = override_headers_->raw_headers();
|
||||
std::move(on_headers_received_callback_)
|
||||
.Run(net::OK, headers, base::nullopt);
|
||||
}
|
||||
|
||||
if (override_headers_) {
|
||||
response_->headers = override_headers_;
|
||||
override_headers_ = nullptr;
|
||||
}
|
||||
|
||||
ResumeIncomingMethodCallProcessing();
|
||||
info_.AddResponseInfoFromResourceResponse(*response_);
|
||||
web_request_api_->OnResponseStarted(&info_, request_);
|
||||
|
||||
if (!receiver_as_header_client_.is_bound())
|
||||
ContinueToCompleted();
|
||||
}
|
||||
|
||||
void ProxyingWebSocket::OnAuthRequiredComplete(
|
||||
extensions::ExtensionWebRequestEventRouter::AuthRequiredResponse rv) {
|
||||
CHECK(auth_required_callback_);
|
||||
ResumeIncomingMethodCallProcessing();
|
||||
switch (rv) {
|
||||
case extensions::ExtensionWebRequestEventRouter::AuthRequiredResponse::
|
||||
AUTH_REQUIRED_RESPONSE_NO_ACTION:
|
||||
case extensions::ExtensionWebRequestEventRouter::AuthRequiredResponse::
|
||||
AUTH_REQUIRED_RESPONSE_CANCEL_AUTH:
|
||||
std::move(auth_required_callback_).Run(base::nullopt);
|
||||
break;
|
||||
|
||||
case extensions::ExtensionWebRequestEventRouter::AuthRequiredResponse::
|
||||
AUTH_REQUIRED_RESPONSE_SET_AUTH:
|
||||
std::move(auth_required_callback_).Run(auth_credentials_);
|
||||
break;
|
||||
case extensions::ExtensionWebRequestEventRouter::AuthRequiredResponse::
|
||||
AUTH_REQUIRED_RESPONSE_IO_PENDING:
|
||||
NOTREACHED();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ProxyingWebSocket::OnHeadersReceivedCompleteForAuth(
|
||||
const net::AuthChallengeInfo& auth_info,
|
||||
int rv) {
|
||||
if (rv != net::OK) {
|
||||
OnError(rv);
|
||||
return;
|
||||
}
|
||||
ResumeIncomingMethodCallProcessing();
|
||||
info_.AddResponseInfoFromResourceResponse(*response_);
|
||||
|
||||
auto continuation = base::BindRepeating(
|
||||
&ProxyingWebSocket::OnAuthRequiredComplete, weak_factory_.GetWeakPtr());
|
||||
auto auth_rv = extensions::ExtensionWebRequestEventRouter::
|
||||
AuthRequiredResponse::AUTH_REQUIRED_RESPONSE_IO_PENDING;
|
||||
PauseIncomingMethodCallProcessing();
|
||||
|
||||
OnAuthRequiredComplete(auth_rv);
|
||||
}
|
||||
|
||||
void ProxyingWebSocket::PauseIncomingMethodCallProcessing() {
|
||||
receiver_as_handshake_client_.Pause();
|
||||
receiver_as_auth_handler_.Pause();
|
||||
if (receiver_as_header_client_.is_bound())
|
||||
receiver_as_header_client_.Pause();
|
||||
}
|
||||
|
||||
void ProxyingWebSocket::ResumeIncomingMethodCallProcessing() {
|
||||
receiver_as_handshake_client_.Resume();
|
||||
receiver_as_auth_handler_.Resume();
|
||||
if (receiver_as_header_client_.is_bound())
|
||||
receiver_as_header_client_.Resume();
|
||||
}
|
||||
|
||||
void ProxyingWebSocket::OnError(int error_code) {
|
||||
if (!is_done_) {
|
||||
is_done_ = true;
|
||||
web_request_api_->OnErrorOccurred(&info_, request_, error_code);
|
||||
}
|
||||
|
||||
// Deletes |this|.
|
||||
delete this;
|
||||
}
|
||||
|
||||
void ProxyingWebSocket::OnMojoConnectionErrorWithCustomReason(
|
||||
uint32_t custom_reason,
|
||||
const std::string& description) {
|
||||
// Here we want to nofiy the custom reason to the client, which is why
|
||||
// we reset |forwarding_handshake_client_| manually.
|
||||
forwarding_handshake_client_.ResetWithReason(custom_reason, description);
|
||||
OnError(net::ERR_FAILED);
|
||||
// Deletes |this|.
|
||||
}
|
||||
|
||||
void ProxyingWebSocket::OnMojoConnectionError() {
|
||||
OnError(net::ERR_FAILED);
|
||||
// Deletes |this|.
|
||||
}
|
||||
|
||||
} // namespace electron
|
||||
165
shell/browser/net/proxying_websocket.h
Normal file
165
shell/browser/net/proxying_websocket.h
Normal file
@@ -0,0 +1,165 @@
|
||||
// Copyright 2020 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_BROWSER_NET_PROXYING_WEBSOCKET_H_
|
||||
#define SHELL_BROWSER_NET_PROXYING_WEBSOCKET_H_
|
||||
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/optional.h"
|
||||
#include "components/keyed_service/core/keyed_service_shutdown_notifier.h"
|
||||
#include "extensions/browser/api/web_request/web_request_api.h"
|
||||
#include "extensions/browser/api/web_request/web_request_info.h"
|
||||
#include "mojo/public/cpp/bindings/pending_receiver.h"
|
||||
#include "mojo/public/cpp/bindings/receiver.h"
|
||||
#include "mojo/public/cpp/bindings/remote.h"
|
||||
#include "services/network/public/cpp/resource_request.h"
|
||||
#include "services/network/public/mojom/network_context.mojom.h"
|
||||
#include "services/network/public/mojom/websocket.mojom.h"
|
||||
#include "shell/browser/net/web_request_api_interface.h"
|
||||
#include "url/gurl.h"
|
||||
#include "url/origin.h"
|
||||
|
||||
namespace electron {
|
||||
|
||||
// A ProxyingWebSocket proxies a WebSocket connection and dispatches
|
||||
// WebRequest API events.
|
||||
//
|
||||
// The code is referenced from the
|
||||
// extensions::WebRequestProxyingWebSocket class.
|
||||
class ProxyingWebSocket : public network::mojom::WebSocketHandshakeClient,
|
||||
public network::mojom::AuthenticationHandler,
|
||||
public network::mojom::TrustedHeaderClient {
|
||||
public:
|
||||
using WebSocketFactory = content::ContentBrowserClient::WebSocketFactory;
|
||||
|
||||
ProxyingWebSocket(
|
||||
WebRequestAPI* web_request_api,
|
||||
WebSocketFactory factory,
|
||||
const network::ResourceRequest& request,
|
||||
mojo::PendingRemote<network::mojom::WebSocketHandshakeClient>
|
||||
handshake_client,
|
||||
bool has_extra_headers,
|
||||
int process_id,
|
||||
int render_frame_id,
|
||||
content::BrowserContext* browser_context,
|
||||
uint64_t* request_id_generator);
|
||||
~ProxyingWebSocket() override;
|
||||
|
||||
void Start();
|
||||
|
||||
// network::mojom::WebSocketHandshakeClient methods:
|
||||
void OnOpeningHandshakeStarted(
|
||||
network::mojom::WebSocketHandshakeRequestPtr request) override;
|
||||
void OnConnectionEstablished(
|
||||
mojo::PendingRemote<network::mojom::WebSocket> websocket,
|
||||
mojo::PendingReceiver<network::mojom::WebSocketClient> client_receiver,
|
||||
network::mojom::WebSocketHandshakeResponsePtr response,
|
||||
mojo::ScopedDataPipeConsumerHandle readable) override;
|
||||
|
||||
// network::mojom::AuthenticationHandler method:
|
||||
void OnAuthRequired(const net::AuthChallengeInfo& auth_info,
|
||||
const scoped_refptr<net::HttpResponseHeaders>& headers,
|
||||
const net::IPEndPoint& remote_endpoint,
|
||||
OnAuthRequiredCallback callback) override;
|
||||
|
||||
// network::mojom::TrustedHeaderClient methods:
|
||||
void OnBeforeSendHeaders(const net::HttpRequestHeaders& headers,
|
||||
OnBeforeSendHeadersCallback callback) override;
|
||||
void OnHeadersReceived(const std::string& headers,
|
||||
const net::IPEndPoint& endpoint,
|
||||
OnHeadersReceivedCallback callback) override;
|
||||
|
||||
static void StartProxying(
|
||||
WebRequestAPI* web_request_api,
|
||||
WebSocketFactory factory,
|
||||
const GURL& url,
|
||||
const GURL& site_for_cookies,
|
||||
const base::Optional<std::string>& user_agent,
|
||||
mojo::PendingRemote<network::mojom::WebSocketHandshakeClient>
|
||||
handshake_client,
|
||||
bool has_extra_headers,
|
||||
int process_id,
|
||||
int render_frame_id,
|
||||
const url::Origin& origin,
|
||||
content::BrowserContext* browser_context,
|
||||
uint64_t* request_id_generator);
|
||||
|
||||
WebRequestAPI* web_request_api() { return web_request_api_; }
|
||||
|
||||
private:
|
||||
void OnBeforeRequestComplete(int error_code);
|
||||
void OnBeforeSendHeadersComplete(const std::set<std::string>& removed_headers,
|
||||
const std::set<std::string>& set_headers,
|
||||
int error_code);
|
||||
void ContinueToStartRequest(int error_code);
|
||||
void OnHeadersReceivedComplete(int error_code);
|
||||
void ContinueToHeadersReceived();
|
||||
void OnAuthRequiredComplete(
|
||||
extensions::ExtensionWebRequestEventRouter::AuthRequiredResponse rv);
|
||||
void OnHeadersReceivedCompleteForAuth(const net::AuthChallengeInfo& auth_info,
|
||||
int rv);
|
||||
void ContinueToCompleted();
|
||||
|
||||
void PauseIncomingMethodCallProcessing();
|
||||
void ResumeIncomingMethodCallProcessing();
|
||||
void OnError(int result);
|
||||
// This is used for detecting errors on mojo connection with the network
|
||||
// service.
|
||||
void OnMojoConnectionErrorWithCustomReason(uint32_t custom_reason,
|
||||
const std::string& description);
|
||||
// This is used for detecting errors on mojo connection with original client
|
||||
// (i.e., renderer).
|
||||
void OnMojoConnectionError();
|
||||
|
||||
// Passed from api::WebRequest.
|
||||
WebRequestAPI* web_request_api_;
|
||||
|
||||
// Saved to feed the api::WebRequest.
|
||||
network::ResourceRequest request_;
|
||||
|
||||
WebSocketFactory factory_;
|
||||
mojo::Remote<network::mojom::WebSocketHandshakeClient>
|
||||
forwarding_handshake_client_;
|
||||
mojo::Receiver<network::mojom::WebSocketHandshakeClient>
|
||||
receiver_as_handshake_client_{this};
|
||||
mojo::Receiver<network::mojom::AuthenticationHandler>
|
||||
receiver_as_auth_handler_{this};
|
||||
mojo::Receiver<network::mojom::TrustedHeaderClient>
|
||||
receiver_as_header_client_{this};
|
||||
|
||||
net::HttpRequestHeaders request_headers_;
|
||||
network::mojom::URLResponseHeadPtr response_;
|
||||
net::AuthCredentials auth_credentials_;
|
||||
OnAuthRequiredCallback auth_required_callback_;
|
||||
scoped_refptr<net::HttpResponseHeaders> override_headers_;
|
||||
std::vector<network::mojom::HttpHeaderPtr> additional_headers_;
|
||||
|
||||
OnBeforeSendHeadersCallback on_before_send_headers_callback_;
|
||||
OnHeadersReceivedCallback on_headers_received_callback_;
|
||||
|
||||
GURL redirect_url_;
|
||||
bool is_done_ = false;
|
||||
bool has_extra_headers_;
|
||||
mojo::PendingRemote<network::mojom::WebSocket> websocket_;
|
||||
mojo::PendingReceiver<network::mojom::WebSocketClient> client_receiver_;
|
||||
network::mojom::WebSocketHandshakeResponsePtr handshake_response_ = nullptr;
|
||||
mojo::ScopedDataPipeConsumerHandle readable_;
|
||||
|
||||
extensions::WebRequestInfo info_;
|
||||
|
||||
// Notifies the proxy that the browser context has been shutdown.
|
||||
std::unique_ptr<KeyedServiceShutdownNotifier::Subscription>
|
||||
shutdown_notifier_;
|
||||
|
||||
base::WeakPtrFactory<ProxyingWebSocket> weak_factory_{this};
|
||||
DISALLOW_COPY_AND_ASSIGN(ProxyingWebSocket);
|
||||
};
|
||||
|
||||
} // namespace electron
|
||||
|
||||
#endif // SHELL_BROWSER_NET_PROXYING_WEBSOCKET_H_
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "chrome/browser/browser_process.h"
|
||||
#include "chrome/browser/net/chrome_mojo_proxy_resolver_factory.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/cors_exempt_headers.h"
|
||||
#include "content/public/browser/network_service_instance.h"
|
||||
#include "content/public/common/content_features.h"
|
||||
#include "content/public/common/service_names.mojom.h"
|
||||
@@ -154,6 +155,10 @@ SystemNetworkContextManager::CreateDefaultNetworkContextParams() {
|
||||
network::mojom::NetworkContextParamsPtr network_context_params =
|
||||
network::mojom::NetworkContextParams::New();
|
||||
|
||||
// This is required to avoid blocking X-Requested-With headers sent by PPAPI
|
||||
// plugins, more info crbug.com/940331
|
||||
content::UpdateCorsExemptHeader(network_context_params.get());
|
||||
|
||||
network_context_params->enable_brotli = true;
|
||||
|
||||
network_context_params->enable_referrers = true;
|
||||
|
||||
61
shell/browser/net/web_request_api_interface.h
Normal file
61
shell/browser/net/web_request_api_interface.h
Normal file
@@ -0,0 +1,61 @@
|
||||
// Copyright (c) 2020 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_BROWSER_NET_WEB_REQUEST_API_INTERFACE_H_
|
||||
#define SHELL_BROWSER_NET_WEB_REQUEST_API_INTERFACE_H_
|
||||
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
#include "extensions/browser/api/web_request/web_request_info.h"
|
||||
#include "services/network/public/cpp/resource_request.h"
|
||||
|
||||
namespace electron {
|
||||
|
||||
// Defines the interface for WebRequest API, implemented by api::WebRequestNS.
|
||||
class WebRequestAPI {
|
||||
public:
|
||||
virtual ~WebRequestAPI() {}
|
||||
|
||||
using BeforeSendHeadersCallback =
|
||||
base::OnceCallback<void(const std::set<std::string>& removed_headers,
|
||||
const std::set<std::string>& set_headers,
|
||||
int error_code)>;
|
||||
|
||||
virtual bool HasListener() const = 0;
|
||||
virtual int OnBeforeRequest(extensions::WebRequestInfo* info,
|
||||
const network::ResourceRequest& request,
|
||||
net::CompletionOnceCallback callback,
|
||||
GURL* new_url) = 0;
|
||||
virtual int OnBeforeSendHeaders(extensions::WebRequestInfo* info,
|
||||
const network::ResourceRequest& request,
|
||||
BeforeSendHeadersCallback callback,
|
||||
net::HttpRequestHeaders* headers) = 0;
|
||||
virtual int OnHeadersReceived(
|
||||
extensions::WebRequestInfo* info,
|
||||
const network::ResourceRequest& request,
|
||||
net::CompletionOnceCallback callback,
|
||||
const net::HttpResponseHeaders* original_response_headers,
|
||||
scoped_refptr<net::HttpResponseHeaders>* override_response_headers,
|
||||
GURL* allowed_unsafe_redirect_url) = 0;
|
||||
virtual void OnSendHeaders(extensions::WebRequestInfo* info,
|
||||
const network::ResourceRequest& request,
|
||||
const net::HttpRequestHeaders& headers) = 0;
|
||||
virtual void OnBeforeRedirect(extensions::WebRequestInfo* info,
|
||||
const network::ResourceRequest& request,
|
||||
const GURL& new_location) = 0;
|
||||
virtual void OnResponseStarted(extensions::WebRequestInfo* info,
|
||||
const network::ResourceRequest& request) = 0;
|
||||
virtual void OnErrorOccurred(extensions::WebRequestInfo* info,
|
||||
const network::ResourceRequest& request,
|
||||
int net_error) = 0;
|
||||
virtual void OnCompleted(extensions::WebRequestInfo* info,
|
||||
const network::ResourceRequest& request,
|
||||
int net_error) = 0;
|
||||
virtual void OnRequestWillBeDestroyed(extensions::WebRequestInfo* info) = 0;
|
||||
};
|
||||
|
||||
} // namespace electron
|
||||
|
||||
#endif // SHELL_BROWSER_NET_WEB_REQUEST_API_INTERFACE_H_
|
||||
63
shell/browser/plugins/plugin_utils.cc
Normal file
63
shell/browser/plugins/plugin_utils.cc
Normal file
@@ -0,0 +1,63 @@
|
||||
// Copyright 2016 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/browser/plugins/plugin_utils.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "base/values.h"
|
||||
#include "content/public/common/webplugininfo.h"
|
||||
#include "extensions/buildflags/buildflags.h"
|
||||
#include "url/gurl.h"
|
||||
#include "url/origin.h"
|
||||
|
||||
#if BUILDFLAG(ENABLE_EXTENSIONS)
|
||||
#include "extensions/browser/extension_registry.h"
|
||||
#include "extensions/browser/extension_util.h"
|
||||
#include "extensions/common/constants.h"
|
||||
#include "extensions/common/extension.h"
|
||||
#include "extensions/common/manifest_handlers/mime_types_handler.h"
|
||||
#endif
|
||||
|
||||
// static
|
||||
std::string PluginUtils::GetExtensionIdForMimeType(
|
||||
content::BrowserContext* browser_context,
|
||||
const std::string& mime_type) {
|
||||
auto map = GetMimeTypeToExtensionIdMap(browser_context);
|
||||
auto it = map.find(mime_type);
|
||||
if (it != map.end())
|
||||
return it->second;
|
||||
return std::string();
|
||||
}
|
||||
|
||||
base::flat_map<std::string, std::string>
|
||||
PluginUtils::GetMimeTypeToExtensionIdMap(
|
||||
content::BrowserContext* browser_context) {
|
||||
base::flat_map<std::string, std::string> mime_type_to_extension_id_map;
|
||||
#if BUILDFLAG(ENABLE_EXTENSIONS)
|
||||
std::vector<std::string> whitelist = MimeTypesHandler::GetMIMETypeWhitelist();
|
||||
// Go through the white-listed extensions and try to use them to intercept
|
||||
// the URL request.
|
||||
for (const std::string& extension_id : whitelist) {
|
||||
const extensions::Extension* extension =
|
||||
extensions::ExtensionRegistry::Get(browser_context)
|
||||
->enabled_extensions()
|
||||
.GetByID(extension_id);
|
||||
// The white-listed extension may not be installed, so we have to nullptr
|
||||
// check |extension|.
|
||||
if (!extension) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (MimeTypesHandler* handler = MimeTypesHandler::GetHandler(extension)) {
|
||||
for (const auto& supported_mime_type : handler->mime_type_set()) {
|
||||
DCHECK(!base::Contains(mime_type_to_extension_id_map,
|
||||
supported_mime_type));
|
||||
mime_type_to_extension_id_map[supported_mime_type] = extension_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return mime_type_to_extension_id_map;
|
||||
}
|
||||
34
shell/browser/plugins/plugin_utils.h
Normal file
34
shell/browser/plugins/plugin_utils.h
Normal file
@@ -0,0 +1,34 @@
|
||||
// Copyright 2016 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_BROWSER_PLUGINS_PLUGIN_UTILS_H_
|
||||
#define SHELL_BROWSER_PLUGINS_PLUGIN_UTILS_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "base/containers/flat_map.h"
|
||||
#include "base/macros.h"
|
||||
|
||||
namespace content {
|
||||
class BrowserContext;
|
||||
}
|
||||
|
||||
class PluginUtils {
|
||||
public:
|
||||
// If there's an extension that is allowed to handle |mime_type|, returns its
|
||||
// ID. Otherwise returns an empty string.
|
||||
static std::string GetExtensionIdForMimeType(
|
||||
content::BrowserContext* browser_context,
|
||||
const std::string& mime_type);
|
||||
|
||||
// Returns a map populated with MIME types that are handled by an extension as
|
||||
// keys and the corresponding extensions Ids as values.
|
||||
static base::flat_map<std::string, std::string> GetMimeTypeToExtensionIdMap(
|
||||
content::BrowserContext* browser_context);
|
||||
|
||||
private:
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(PluginUtils);
|
||||
};
|
||||
|
||||
#endif // SHELL_BROWSER_PLUGINS_PLUGIN_UTILS_H_
|
||||
@@ -27,7 +27,7 @@
|
||||
<key>NSMainNibFile</key>
|
||||
<string>MainMenu</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>ElectronApplication</string>
|
||||
<string>AtomApplication</string>
|
||||
<key>NSSupportsAutomaticGraphicsSwitching</key>
|
||||
<true/>
|
||||
<key>NSHighResolutionCapable</key>
|
||||
|
||||
@@ -50,8 +50,8 @@ END
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 9,0,0,20200205
|
||||
PRODUCTVERSION 9,0,0,20200205
|
||||
FILEVERSION 9,0,0,3
|
||||
PRODUCTVERSION 9,0,0,3
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
|
||||
@@ -50,11 +50,10 @@
|
||||
#include "ui/display/screen.h"
|
||||
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
#include "chrome/common/extensions/chrome_manifest_url_handlers.h"
|
||||
#include "content/public/browser/child_process_security_policy.h"
|
||||
#include "content/public/browser/render_process_host.h"
|
||||
#include "extensions/browser/extension_registry.h"
|
||||
#include "extensions/common/manifest_constants.h"
|
||||
#include "extensions/common/manifest_url_handlers.h"
|
||||
#include "extensions/common/permissions/permissions_data.h"
|
||||
#include "shell/browser/electron_browser_context.h"
|
||||
#endif
|
||||
@@ -601,8 +600,8 @@ void InspectableWebContentsImpl::AddDevToolsExtensionsToClient() {
|
||||
|
||||
base::ListValue results;
|
||||
for (auto& extension : registry->enabled_extensions()) {
|
||||
auto devtools_page_url = extensions::ManifestURL::Get(
|
||||
extension.get(), extensions::manifest_keys::kDevToolsPage);
|
||||
auto devtools_page_url =
|
||||
extensions::chrome_manifest_urls::GetDevToolsPage(extension.get());
|
||||
if (devtools_page_url.is_empty())
|
||||
continue;
|
||||
|
||||
|
||||
@@ -37,11 +37,8 @@ const char kRunAsNode[] = "ELECTRON_RUN_AS_NODE";
|
||||
|
||||
#if BUILDFLAG(ENABLE_PDF_VIEWER)
|
||||
const char kPdfPluginMimeType[] = "application/x-google-chrome-pdf";
|
||||
const char kPdfPluginPath[] = "chrome://pdf-viewer/";
|
||||
const char kPdfPluginSrc[] = "src";
|
||||
|
||||
const char kPdfViewerUIOrigin[] = "chrome://pdf-viewer/";
|
||||
const char kPdfViewerUIHost[] = "pdf-viewer";
|
||||
const base::FilePath::CharType kPdfPluginPath[] =
|
||||
FILE_PATH_LITERAL("internal-pdf-viewer");
|
||||
#endif // BUILDFLAG(ENABLE_PDF_VIEWER)
|
||||
|
||||
} // namespace electron
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#ifndef SHELL_COMMON_ELECTRON_CONSTANTS_H_
|
||||
#define SHELL_COMMON_ELECTRON_CONSTANTS_H_
|
||||
|
||||
#include "base/files/file_path.h"
|
||||
#include "build/build_config.h"
|
||||
#include "electron/buildflags/buildflags.h"
|
||||
|
||||
@@ -39,12 +40,7 @@ extern const char kRunAsNode[];
|
||||
#if BUILDFLAG(ENABLE_PDF_VIEWER)
|
||||
// The MIME type used for the PDF plugin.
|
||||
extern const char kPdfPluginMimeType[];
|
||||
extern const char kPdfPluginPath[];
|
||||
extern const char kPdfPluginSrc[];
|
||||
|
||||
// Constants for PDF viewer webui.
|
||||
extern const char kPdfViewerUIOrigin[];
|
||||
extern const char kPdfViewerUIHost[];
|
||||
extern const base::FilePath::CharType kPdfPluginPath[];
|
||||
#endif // BUILDFLAG(ENABLE_PDF_VIEWER)
|
||||
|
||||
} // namespace electron
|
||||
|
||||
@@ -22,6 +22,7 @@ group("extensions_features") {
|
||||
public_deps = [
|
||||
":api_features",
|
||||
":manifest_features",
|
||||
":permission_features",
|
||||
|
||||
# TODO(devlin): It would be nicer to have this dependency hoisted up to
|
||||
# //extensions/common (since that's where it's consumed), but there's some
|
||||
@@ -36,6 +37,7 @@ group("extensions_features") {
|
||||
generated_json_strings("generated_api_json_strings") {
|
||||
sources = [
|
||||
"extension.json",
|
||||
"resources_private.idl",
|
||||
"tabs.json",
|
||||
]
|
||||
|
||||
@@ -50,7 +52,10 @@ generated_json_strings("generated_api_json_strings") {
|
||||
}
|
||||
|
||||
generated_types("generated_api_types") {
|
||||
sources = [ "tabs.json" ]
|
||||
sources = [
|
||||
"resources_private.idl",
|
||||
"tabs.json",
|
||||
]
|
||||
configs = [ "//build/config:precompiled_headers" ]
|
||||
schema_include_rules = "extensions/common/api:extensions::api::%(namespace)s"
|
||||
|
||||
@@ -73,3 +78,10 @@ json_features("api_features") {
|
||||
sources = [ "_api_features.json" ]
|
||||
visibility = [ ":extensions_features" ]
|
||||
}
|
||||
|
||||
json_features("permission_features") {
|
||||
feature_type = "PermissionFeature"
|
||||
method_name = "AddElectronPermissionFeatures"
|
||||
sources = [ "_permission_features.json" ]
|
||||
visibility = [ ":extensions_features" ]
|
||||
}
|
||||
|
||||
@@ -9,7 +9,27 @@
|
||||
"extension_types": ["extension"],
|
||||
"contexts": ["blessed_extension"]
|
||||
},
|
||||
"extension.getBackgroundPage": {
|
||||
"contexts": ["blessed_extension"],
|
||||
"disallow_for_service_workers": true
|
||||
},
|
||||
"extension.getURL": {
|
||||
"contexts": ["blessed_extension", "unblessed_extension", "content_script"]
|
||||
}
|
||||
},
|
||||
"mimeHandlerViewGuestInternal": {
|
||||
"internal": true,
|
||||
"contexts": "all",
|
||||
"channel": "stable",
|
||||
"matches": ["<all_urls>"]
|
||||
},
|
||||
"resourcesPrivate": [{
|
||||
"dependencies": ["permission:resourcesPrivate"],
|
||||
"contexts": ["blessed_extension"]
|
||||
}, {
|
||||
"channel": "stable",
|
||||
"contexts": ["webui"],
|
||||
"matches": [
|
||||
"chrome://print/*"
|
||||
]
|
||||
}]
|
||||
}
|
||||
|
||||
9
shell/common/extensions/api/_permission_features.json
Normal file
9
shell/common/extensions/api/_permission_features.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"resourcesPrivate": {
|
||||
"channel": "stable",
|
||||
"extension_types": [
|
||||
"extension"
|
||||
],
|
||||
"location": "component"
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,20 @@
|
||||
"properties": {
|
||||
},
|
||||
"functions": [
|
||||
{
|
||||
"name": "getBackgroundPage",
|
||||
"nocompile": true,
|
||||
"type": "function",
|
||||
"description": "Returns the JavaScript 'window' object for the background page running inside the current extension. Returns null if the extension has no background page.",
|
||||
"parameters": [],
|
||||
"returns": {
|
||||
"type": "object",
|
||||
"optional": true,
|
||||
"name": "backgroundPageGlobal",
|
||||
"isInstanceOf": "Window",
|
||||
"additionalProperties": { "type": "any" }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "getURL",
|
||||
"deprecated": "Please use $(ref:runtime.getURL).",
|
||||
|
||||
23
shell/common/extensions/api/resources_private.idl
Normal file
23
shell/common/extensions/api/resources_private.idl
Normal file
@@ -0,0 +1,23 @@
|
||||
// Copyright 2015 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.
|
||||
|
||||
// resourcesPrivate.
|
||||
namespace resourcesPrivate {
|
||||
enum Component { identity, pdf };
|
||||
|
||||
callback GetStringsCallback = void (object result);
|
||||
|
||||
interface Functions {
|
||||
// Gets localized strings for a component extension. Includes default WebUI
|
||||
// loadTimeData values for text and language settings (fontsize, fontfamily,
|
||||
// language, textdirection). See
|
||||
// chrome/browser/extensions/api/resources_private/resources_private_api.cc
|
||||
// for instructions on adding a new component to this API.
|
||||
//
|
||||
// |component| : Internal chrome component to get strings for.
|
||||
// |callback| : Called with a dictionary mapping names to strings.
|
||||
static void getStrings(Component component,
|
||||
GetStringsCallback callback);
|
||||
};
|
||||
};
|
||||
@@ -1,7 +1,143 @@
|
||||
[
|
||||
{
|
||||
"namespace": "tabs",
|
||||
"description": "Use the <code>chrome.tabs</code> API to interact with the browser's tab system. You can use this API to create, modify, and rearrange tabs in the browser.",
|
||||
"types": [
|
||||
{ "id": "MutedInfoReason",
|
||||
"type": "string",
|
||||
"description": "An event that caused a muted state change.",
|
||||
"enum": [
|
||||
{"name": "user", "description": "A user input action set the muted state."},
|
||||
{"name": "capture", "description": "Tab capture was started, forcing a muted state change."},
|
||||
{"name": "extension", "description": "An extension, identified by the extensionId field, set the muted state."}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "MutedInfo",
|
||||
"type": "object",
|
||||
"description": "The tab's muted state and the reason for the last state change.",
|
||||
"properties": {
|
||||
"muted": {
|
||||
"type": "boolean",
|
||||
"description": "Whether the tab is muted (prevented from playing sound). The tab may be muted even if it has not played or is not currently playing sound. Equivalent to whether the 'muted' audio indicator is showing."
|
||||
},
|
||||
"reason": {
|
||||
"$ref": "MutedInfoReason",
|
||||
"optional": true,
|
||||
"description": "The reason the tab was muted or unmuted. Not set if the tab's mute state has never been changed."
|
||||
},
|
||||
"extensionId": {
|
||||
"type": "string",
|
||||
"optional": true,
|
||||
"description": "The ID of the extension that changed the muted state. Not set if an extension was not the reason the muted state last changed."
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "Tab",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {"type": "integer", "minimum": -1, "optional": true, "description": "The ID of the tab. Tab IDs are unique within a browser session. Under some circumstances a tab may not be assigned an ID; for example, when querying foreign tabs using the $(ref:sessions) API, in which case a session ID may be present. Tab ID can also be set to <code>chrome.tabs.TAB_ID_NONE</code> for apps and devtools windows."},
|
||||
// TODO(kalman): Investigate how this is ending up as -1 (based on window type? a bug?) and whether it should be optional instead.
|
||||
"index": {"type": "integer", "minimum": -1, "description": "The zero-based index of the tab within its window."},
|
||||
"windowId": {"type": "integer", "minimum": 0, "description": "The ID of the window that contains the tab."},
|
||||
"openerTabId": {"type": "integer", "minimum": 0, "optional": true, "description": "The ID of the tab that opened this tab, if any. This property is only present if the opener tab still exists."},
|
||||
"selected": {"type": "boolean", "description": "Whether the tab is selected.", "deprecated": "Please use $(ref:tabs.Tab.highlighted)."},
|
||||
"highlighted": {"type": "boolean", "description": "Whether the tab is highlighted."},
|
||||
"active": {"type": "boolean", "description": "Whether the tab is active in its window. Does not necessarily mean the window is focused."},
|
||||
"pinned": {"type": "boolean", "description": "Whether the tab is pinned."},
|
||||
"audible": {"type": "boolean", "optional": true, "description": "Whether the tab has produced sound over the past couple of seconds (but it might not be heard if also muted). Equivalent to whether the 'speaker audio' indicator is showing."},
|
||||
"discarded": {"type": "boolean", "description": "Whether the tab is discarded. A discarded tab is one whose content has been unloaded from memory, but is still visible in the tab strip. Its content is reloaded the next time it is activated."},
|
||||
"autoDiscardable": {"type": "boolean", "description": "Whether the tab can be discarded automatically by the browser when resources are low."},
|
||||
"mutedInfo": {"$ref": "MutedInfo", "optional": true, "description": "The tab's muted state and the reason for the last state change."},
|
||||
"url": {"type": "string", "optional": true, "description": "The last committed URL of the main frame of the tab. This property is only present if the extension's manifest includes the <code>\"tabs\"</code> permission and may be an empty string if the tab has not yet committed. See also $(ref:Tab.pendingUrl)."},
|
||||
"pendingUrl": {"type": "string", "optional": true, "description": "The URL the tab is navigating to, before it has committed. This property is only present if the extension's manifest includes the <code>\"tabs\"</code> permission and there is a pending navigation."},
|
||||
"title": {"type": "string", "optional": true, "description": "The title of the tab. This property is only present if the extension's manifest includes the <code>\"tabs\"</code> permission."},
|
||||
"favIconUrl": {"type": "string", "optional": true, "description": "The URL of the tab's favicon. This property is only present if the extension's manifest includes the <code>\"tabs\"</code> permission. It may also be an empty string if the tab is loading."},
|
||||
"status": {"type": "string", "optional": true, "description": "Either <em>loading</em> or <em>complete</em>."},
|
||||
"incognito": {"type": "boolean", "description": "Whether the tab is in an incognito window."},
|
||||
"width": {"type": "integer", "optional": true, "description": "The width of the tab in pixels."},
|
||||
"height": {"type": "integer", "optional": true, "description": "The height of the tab in pixels."},
|
||||
"sessionId": {"type": "string", "optional": true, "description": "The session ID used to uniquely identify a tab obtained from the $(ref:sessions) API."}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "ZoomSettingsMode",
|
||||
"type": "string",
|
||||
"description": "Defines how zoom changes are handled, i.e., which entity is responsible for the actual scaling of the page; defaults to <code>automatic</code>.",
|
||||
"enum": [
|
||||
{
|
||||
"name": "automatic",
|
||||
"description": "Zoom changes are handled automatically by the browser."
|
||||
},
|
||||
{
|
||||
"name": "manual",
|
||||
"description": "Overrides the automatic handling of zoom changes. The <code>onZoomChange</code> event will still be dispatched, and it is the extension's responsibility to listen for this event and manually scale the page. This mode does not support <code>per-origin</code> zooming, and thus ignores the <code>scope</code> zoom setting and assumes <code>per-tab</code>."
|
||||
},
|
||||
{
|
||||
"name": "disabled",
|
||||
"description": "Disables all zooming in the tab. The tab reverts to the default zoom level, and all attempted zoom changes are ignored."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "ZoomSettingsScope",
|
||||
"type": "string",
|
||||
"description": "Defines whether zoom changes persist for the page's origin, or only take effect in this tab; defaults to <code>per-origin</code> when in <code>automatic</code> mode, and <code>per-tab</code> otherwise.",
|
||||
"enum": [
|
||||
{
|
||||
"name": "per-origin",
|
||||
"description": "Zoom changes persist in the zoomed page's origin, i.e., all other tabs navigated to that same origin are zoomed as well. Moreover, <code>per-origin</code> zoom changes are saved with the origin, meaning that when navigating to other pages in the same origin, they are all zoomed to the same zoom factor. The <code>per-origin</code> scope is only available in the <code>automatic</code> mode."
|
||||
},
|
||||
{
|
||||
"name": "per-tab",
|
||||
"description": "Zoom changes only take effect in this tab, and zoom changes in other tabs do not affect the zooming of this tab. Also, <code>per-tab</code> zoom changes are reset on navigation; navigating a tab always loads pages with their <code>per-origin</code> zoom factors."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "ZoomSettings",
|
||||
"type": "object",
|
||||
"description": "Defines how zoom changes in a tab are handled and at what scope.",
|
||||
"properties": {
|
||||
"mode": {
|
||||
"$ref": "ZoomSettingsMode",
|
||||
"description": "Defines how zoom changes are handled, i.e., which entity is responsible for the actual scaling of the page; defaults to <code>automatic</code>.",
|
||||
"optional": true
|
||||
},
|
||||
"scope": {
|
||||
"$ref": "ZoomSettingsScope",
|
||||
"description": "Defines whether zoom changes persist for the page's origin, or only take effect in this tab; defaults to <code>per-origin</code> when in <code>automatic</code> mode, and <code>per-tab</code> otherwise.",
|
||||
"optional": true
|
||||
},
|
||||
"defaultZoomFactor": {
|
||||
"type": "number",
|
||||
"optional": true,
|
||||
"description": "Used to return the default zoom level for the current tab in calls to tabs.getZoomSettings."
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"functions": [
|
||||
{
|
||||
"name": "get",
|
||||
"type": "function",
|
||||
"description": "Retrieves details about the specified tab.",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "tabId",
|
||||
"minimum": 0
|
||||
},
|
||||
{
|
||||
"type": "function",
|
||||
"name": "callback",
|
||||
"parameters": [
|
||||
{"name": "tab", "$ref": "Tab"}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "executeScript",
|
||||
"type": "function",
|
||||
@@ -80,6 +216,127 @@
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "setZoom",
|
||||
"type": "function",
|
||||
"description": "Zooms a specified tab.",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "tabId",
|
||||
"minimum": 0,
|
||||
"optional": true,
|
||||
"description": "The ID of the tab to zoom; defaults to the active tab of the current window."
|
||||
},
|
||||
{
|
||||
"type": "number",
|
||||
"name": "zoomFactor",
|
||||
"description": "The new zoom factor. A value of <code>0</code> sets the tab to its current default zoom factor. Values greater than <code>0</code> specify a (possibly non-default) zoom factor for the tab."
|
||||
},
|
||||
{
|
||||
"type": "function",
|
||||
"name": "callback",
|
||||
"optional": true,
|
||||
"description": "Called after the zoom factor has been changed.",
|
||||
"parameters": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "getZoom",
|
||||
"type": "function",
|
||||
"description": "Gets the current zoom factor of a specified tab.",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "tabId",
|
||||
"minimum": 0,
|
||||
"optional": true,
|
||||
"description": "The ID of the tab to get the current zoom factor from; defaults to the active tab of the current window."
|
||||
},
|
||||
{
|
||||
"type": "function",
|
||||
"name": "callback",
|
||||
"description": "Called with the tab's current zoom factor after it has been fetched.",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "number",
|
||||
"name": "zoomFactor",
|
||||
"description": "The tab's current zoom factor."
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "setZoomSettings",
|
||||
"type": "function",
|
||||
"description": "Sets the zoom settings for a specified tab, which define how zoom changes are handled. These settings are reset to defaults upon navigating the tab.",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "tabId",
|
||||
"optional": true,
|
||||
"minimum": 0,
|
||||
"description": "The ID of the tab to change the zoom settings for; defaults to the active tab of the current window."
|
||||
},
|
||||
{
|
||||
"$ref": "ZoomSettings",
|
||||
"name": "zoomSettings",
|
||||
"description": "Defines how zoom changes are handled and at what scope."
|
||||
},
|
||||
{
|
||||
"type": "function",
|
||||
"name": "callback",
|
||||
"optional": true,
|
||||
"description": "Called after the zoom settings are changed.",
|
||||
"parameters": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "getZoomSettings",
|
||||
"type": "function",
|
||||
"description": "Gets the current zoom settings of a specified tab.",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "tabId",
|
||||
"optional": true,
|
||||
"minimum": 0,
|
||||
"description": "The ID of the tab to get the current zoom settings from; defaults to the active tab of the current window."
|
||||
},
|
||||
{
|
||||
"type": "function",
|
||||
"name": "callback",
|
||||
"description": "Called with the tab's current zoom settings.",
|
||||
"parameters": [
|
||||
{
|
||||
"$ref": "ZoomSettings",
|
||||
"name": "zoomSettings",
|
||||
"description": "The tab's current zoom settings."
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"events": [
|
||||
{
|
||||
"name": "onZoomChange",
|
||||
"type": "function",
|
||||
"description": "Fired when a tab is zoomed.",
|
||||
"parameters": [{
|
||||
"type": "object",
|
||||
"name": "ZoomChangeInfo",
|
||||
"properties": {
|
||||
"tabId": {"type": "integer", "minimum": 0},
|
||||
"oldZoomFactor": {"type": "number"},
|
||||
"newZoomFactor": {"type": "number"},
|
||||
"zoomSettings": {"$ref": "ZoomSettings"}
|
||||
}
|
||||
}]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#include "base/containers/span.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "chrome/common/extensions/chrome_manifest_url_handlers.h"
|
||||
#include "electron/buildflags/buildflags.h"
|
||||
#include "electron/shell/common/extensions/api/generated_schemas.h"
|
||||
#include "extensions/common/alias.h"
|
||||
@@ -23,45 +24,20 @@
|
||||
#include "extensions/common/permissions/permissions_info.h"
|
||||
#include "shell/common/extensions/api/api_features.h"
|
||||
#include "shell/common/extensions/api/manifest_features.h"
|
||||
#include "shell/common/extensions/api/permission_features.h"
|
||||
|
||||
namespace extensions {
|
||||
|
||||
namespace keys = manifest_keys;
|
||||
namespace errors = manifest_errors;
|
||||
|
||||
// Parses the "devtools_page" manifest key.
|
||||
class DevToolsPageHandler : public ManifestHandler {
|
||||
public:
|
||||
DevToolsPageHandler() = default;
|
||||
~DevToolsPageHandler() override = default;
|
||||
|
||||
bool Parse(Extension* extension, base::string16* error) override {
|
||||
std::unique_ptr<ManifestURL> manifest_url(new ManifestURL);
|
||||
std::string devtools_str;
|
||||
if (!extension->manifest()->GetString(keys::kDevToolsPage, &devtools_str)) {
|
||||
*error = base::ASCIIToUTF16(errors::kInvalidDevToolsPage);
|
||||
return false;
|
||||
}
|
||||
manifest_url->url_ = extension->GetResourceURL(devtools_str);
|
||||
extension->SetManifestData(keys::kDevToolsPage, std::move(manifest_url));
|
||||
PermissionsParser::AddAPIPermission(extension, APIPermission::kDevtools);
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
base::span<const char* const> Keys() const override {
|
||||
static constexpr const char* kKeys[] = {keys::kDevToolsPage};
|
||||
return kKeys;
|
||||
}
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(DevToolsPageHandler);
|
||||
};
|
||||
|
||||
constexpr APIPermissionInfo::InitInfo permissions_to_register[] = {
|
||||
{APIPermission::kDevtools, "devtools",
|
||||
APIPermissionInfo::kFlagImpliesFullURLAccess |
|
||||
APIPermissionInfo::kFlagCannotBeOptional |
|
||||
APIPermissionInfo::kFlagInternal},
|
||||
{APIPermission::kResourcesPrivate, "resourcesPrivate",
|
||||
APIPermissionInfo::kFlagCannotBeOptional},
|
||||
};
|
||||
base::span<const APIPermissionInfo::InitInfo> GetPermissionInfos() {
|
||||
return base::make_span(permissions_to_register);
|
||||
@@ -89,7 +65,7 @@ void ElectronExtensionsAPIProvider::AddManifestFeatures(
|
||||
|
||||
void ElectronExtensionsAPIProvider::AddPermissionFeatures(
|
||||
extensions::FeatureProvider* provider) {
|
||||
// No shell-specific permission features.
|
||||
extensions::AddElectronPermissionFeatures(provider);
|
||||
}
|
||||
|
||||
void ElectronExtensionsAPIProvider::AddBehaviorFeatures(
|
||||
|
||||
@@ -117,7 +117,6 @@ extensions::URLPatternSet
|
||||
ElectronExtensionsClient::GetPermittedChromeSchemeHosts(
|
||||
const extensions::Extension* extension,
|
||||
const extensions::APIPermissionSet& api_permissions) const {
|
||||
NOTIMPLEMENTED();
|
||||
return extensions::URLPatternSet();
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
</object>
|
||||
<array class="NSMutableArray" key="IBDocument.RootObjects" id="1048">
|
||||
<object class="NSCustomObject" id="1021">
|
||||
<string key="NSClassName">ElectronApplication</string>
|
||||
<string key="NSClassName">AtomApplication</string>
|
||||
</object>
|
||||
<object class="NSCustomObject" id="1014">
|
||||
<string key="NSClassName">FirstResponder</string>
|
||||
|
||||
31
shell/common/world_ids.h
Normal file
31
shell/common/world_ids.h
Normal file
@@ -0,0 +1,31 @@
|
||||
// Copyright (c) 2020 Samuel Maddock
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_COMMON_WORLD_IDS_H_
|
||||
#define SHELL_COMMON_WORLD_IDS_H_
|
||||
|
||||
#include "third_party/blink/public/platform/web_isolated_world_ids.h"
|
||||
|
||||
namespace electron {
|
||||
|
||||
enum WorldIDs : int32_t {
|
||||
MAIN_WORLD_ID = 0,
|
||||
|
||||
// Use a high number far away from 0 to not collide with any other world
|
||||
// IDs created internally by Chrome.
|
||||
ISOLATED_WORLD_ID = 999,
|
||||
|
||||
// Numbers for isolated worlds for extensions are set in
|
||||
// lib/renderer/content-script-injector.ts, and are greater than or equal to
|
||||
// this number, up to ISOLATED_WORLD_ID_EXTENSIONS_END.
|
||||
ISOLATED_WORLD_ID_EXTENSIONS = 1 << 20,
|
||||
|
||||
// Last valid isolated world ID.
|
||||
ISOLATED_WORLD_ID_EXTENSIONS_END =
|
||||
blink::IsolatedWorldId::kEmbedderWorldIdLimit - 1
|
||||
};
|
||||
|
||||
} // namespace electron
|
||||
|
||||
#endif // SHELL_COMMON_WORLD_IDS_H_
|
||||
@@ -50,6 +50,10 @@ class RenderFramePersistenceStore final : public content::RenderFrameObserver {
|
||||
v8::Local<v8::Value> proxy_value);
|
||||
v8::MaybeLocal<v8::Value> GetCachedProxiedObject(v8::Local<v8::Value> from);
|
||||
|
||||
base::WeakPtr<RenderFramePersistenceStore> GetWeakPtr() {
|
||||
return weak_factory_.GetWeakPtr();
|
||||
}
|
||||
|
||||
private:
|
||||
// func_id ==> { function, owning_context }
|
||||
std::map<size_t, FunctionContextPair> functions_;
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
#include "shell/common/gin_helper/dictionary.h"
|
||||
#include "shell/common/gin_helper/promise.h"
|
||||
#include "shell/common/node_includes.h"
|
||||
#include "shell/common/world_ids.h"
|
||||
#include "shell/renderer/api/context_bridge/render_frame_context_bridge_store.h"
|
||||
#include "shell/renderer/electron_render_frame_observer.h"
|
||||
#include "third_party/blink/public/web/web_local_frame.h"
|
||||
|
||||
namespace electron {
|
||||
@@ -111,25 +111,31 @@ bool IsPlainArray(const v8::Local<v8::Value>& arr) {
|
||||
|
||||
class FunctionLifeMonitor final : public ObjectLifeMonitor {
|
||||
public:
|
||||
static void BindTo(v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> target,
|
||||
context_bridge::RenderFramePersistenceStore* store,
|
||||
size_t func_id) {
|
||||
static void BindTo(
|
||||
v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> target,
|
||||
base::WeakPtr<context_bridge::RenderFramePersistenceStore> store,
|
||||
size_t func_id) {
|
||||
new FunctionLifeMonitor(isolate, target, store, func_id);
|
||||
}
|
||||
|
||||
protected:
|
||||
FunctionLifeMonitor(v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> target,
|
||||
context_bridge::RenderFramePersistenceStore* store,
|
||||
size_t func_id)
|
||||
FunctionLifeMonitor(
|
||||
v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> target,
|
||||
base::WeakPtr<context_bridge::RenderFramePersistenceStore> store,
|
||||
size_t func_id)
|
||||
: ObjectLifeMonitor(isolate, target), store_(store), func_id_(func_id) {}
|
||||
~FunctionLifeMonitor() override = default;
|
||||
|
||||
void RunDestructor() override { store_->functions().erase(func_id_); }
|
||||
void RunDestructor() override {
|
||||
if (!store_)
|
||||
return;
|
||||
store_->functions().erase(func_id_);
|
||||
}
|
||||
|
||||
private:
|
||||
context_bridge::RenderFramePersistenceStore* store_;
|
||||
base::WeakPtr<context_bridge::RenderFramePersistenceStore> store_;
|
||||
size_t func_id_;
|
||||
};
|
||||
|
||||
@@ -176,7 +182,7 @@ v8::MaybeLocal<v8::Value> PassValueToOtherContext(
|
||||
base::BindRepeating(&ProxyFunctionWrapper, store, func_id));
|
||||
FunctionLifeMonitor::BindTo(destination_context->GetIsolate(),
|
||||
v8::Local<v8::Object>::Cast(proxy_func),
|
||||
store, func_id);
|
||||
store->GetWeakPtr(), func_id);
|
||||
store->CacheProxiedObject(value, proxy_func);
|
||||
return v8::MaybeLocal<v8::Value>(proxy_func);
|
||||
}
|
||||
@@ -471,7 +477,7 @@ void ExposeAPIInMainWorld(const std::string& key,
|
||||
}
|
||||
|
||||
v8::Local<v8::Context> isolated_context =
|
||||
frame->WorldScriptContext(args->isolate(), World::ISOLATED_WORLD);
|
||||
frame->WorldScriptContext(args->isolate(), WorldIDs::ISOLATED_WORLD_ID);
|
||||
|
||||
v8::Context::Scope main_context_scope(main_context);
|
||||
{
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "net/grit/net_resources.h"
|
||||
#include "services/service_manager/public/cpp/interface_provider.h"
|
||||
#include "shell/common/options_switches.h"
|
||||
#include "shell/common/world_ids.h"
|
||||
#include "third_party/blink/public/platform/web_isolated_world_info.h"
|
||||
#include "third_party/blink/public/web/blink.h"
|
||||
#include "third_party/blink/public/web/web_document.h"
|
||||
@@ -57,7 +58,7 @@ void ElectronRenderFrameObserver::DidClearWindowObject() {
|
||||
renderer_client_->DidClearWindowObject(render_frame_);
|
||||
}
|
||||
|
||||
void ElectronRenderFrameObserver::DidCreateScriptContext(
|
||||
void ElectronRenderFrameObserver::DidInstallConditionalFeatures(
|
||||
v8::Handle<v8::Context> context,
|
||||
int world_id) {
|
||||
if (ShouldNotifyClient(world_id))
|
||||
@@ -90,8 +91,8 @@ void ElectronRenderFrameObserver::DidCreateScriptContext(
|
||||
}
|
||||
|
||||
#if !BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
if (world_id >= World::ISOLATED_WORLD_EXTENSIONS &&
|
||||
world_id <= World::ISOLATED_WORLD_EXTENSIONS_END) {
|
||||
if (world_id >= WorldIDs::ISOLATED_WORLD_ID_EXTENSIONS &&
|
||||
world_id <= WorldIDs::ISOLATED_WORLD_ID_EXTENSIONS_END) {
|
||||
renderer_client_->SetupExtensionWorldOverrides(context, render_frame_,
|
||||
world_id);
|
||||
}
|
||||
@@ -136,19 +137,19 @@ void ElectronRenderFrameObserver::CreateIsolatedWorldContext() {
|
||||
blink::WebString::FromUTF8("Electron Isolated Context");
|
||||
// Setup document's origin policy in isolated world
|
||||
info.security_origin = frame->GetDocument().GetSecurityOrigin();
|
||||
frame->SetIsolatedWorldInfo(World::ISOLATED_WORLD, info);
|
||||
frame->SetIsolatedWorldInfo(WorldIDs::ISOLATED_WORLD_ID, info);
|
||||
|
||||
// Create initial script context in isolated world
|
||||
blink::WebScriptSource source("void 0");
|
||||
frame->ExecuteScriptInIsolatedWorld(World::ISOLATED_WORLD, source);
|
||||
frame->ExecuteScriptInIsolatedWorld(WorldIDs::ISOLATED_WORLD_ID, source);
|
||||
}
|
||||
|
||||
bool ElectronRenderFrameObserver::IsMainWorld(int world_id) {
|
||||
return world_id == World::MAIN_WORLD;
|
||||
return world_id == WorldIDs::MAIN_WORLD_ID;
|
||||
}
|
||||
|
||||
bool ElectronRenderFrameObserver::IsIsolatedWorld(int world_id) {
|
||||
return world_id == World::ISOLATED_WORLD;
|
||||
return world_id == WorldIDs::ISOLATED_WORLD_ID;
|
||||
}
|
||||
|
||||
bool ElectronRenderFrameObserver::ShouldNotifyClient(int world_id) {
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
#include "content/public/renderer/render_frame_observer.h"
|
||||
#include "ipc/ipc_platform_file.h"
|
||||
#include "shell/renderer/renderer_client_base.h"
|
||||
#include "third_party/blink/public/platform/web_isolated_world_ids.h"
|
||||
#include "third_party/blink/public/web/web_local_frame.h"
|
||||
|
||||
namespace base {
|
||||
@@ -20,23 +19,6 @@ class ListValue;
|
||||
|
||||
namespace electron {
|
||||
|
||||
enum World {
|
||||
MAIN_WORLD = 0,
|
||||
|
||||
// Use a high number far away from 0 to not collide with any other world
|
||||
// IDs created internally by Chrome.
|
||||
ISOLATED_WORLD = 999,
|
||||
|
||||
// Numbers for isolated worlds for extensions are set in
|
||||
// lib/renderer/content-script-injector.ts, and are greater than or equal to
|
||||
// this number, up to ISOLATED_WORLD_EXTENSIONS_END.
|
||||
ISOLATED_WORLD_EXTENSIONS = 1 << 20,
|
||||
|
||||
// Last valid isolated world ID.
|
||||
ISOLATED_WORLD_EXTENSIONS_END =
|
||||
blink::IsolatedWorldId::kEmbedderWorldIdLimit - 1
|
||||
};
|
||||
|
||||
// Helper class to forward the messages to the client.
|
||||
class ElectronRenderFrameObserver : public content::RenderFrameObserver {
|
||||
public:
|
||||
@@ -45,8 +27,8 @@ class ElectronRenderFrameObserver : public content::RenderFrameObserver {
|
||||
|
||||
// content::RenderFrameObserver:
|
||||
void DidClearWindowObject() override;
|
||||
void DidCreateScriptContext(v8::Handle<v8::Context> context,
|
||||
int world_id) override;
|
||||
void DidInstallConditionalFeatures(v8::Handle<v8::Context> context,
|
||||
int world_id) override;
|
||||
void DraggableRegionsChanged() override;
|
||||
void WillReleaseScriptContext(v8::Local<v8::Context> context,
|
||||
int world_id) override;
|
||||
|
||||
@@ -291,4 +291,12 @@ void ElectronSandboxedRendererClient::WillReleaseScriptContext(
|
||||
InvokeHiddenCallback(context, kLifecycleKey, "onExit");
|
||||
}
|
||||
|
||||
bool ElectronSandboxedRendererClient::ShouldFork(blink::WebLocalFrame* frame,
|
||||
const GURL& url,
|
||||
const std::string& http_method,
|
||||
bool is_initial_navigation,
|
||||
bool is_server_redirect) {
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace electron
|
||||
|
||||
@@ -37,6 +37,11 @@ class ElectronSandboxedRendererClient : public RendererClientBase {
|
||||
void RenderViewCreated(content::RenderView*) override;
|
||||
void RunScriptsAtDocumentStart(content::RenderFrame* render_frame) override;
|
||||
void RunScriptsAtDocumentEnd(content::RenderFrame* render_frame) override;
|
||||
bool ShouldFork(blink::WebLocalFrame* frame,
|
||||
const GURL& url,
|
||||
const std::string& http_method,
|
||||
bool is_initial_navigation,
|
||||
bool is_server_redirect) override;
|
||||
|
||||
private:
|
||||
std::unique_ptr<base::ProcessMetrics> metrics_;
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include "content/public/renderer/render_thread.h"
|
||||
#include "extensions/renderer/dispatcher.h"
|
||||
#include "shell/common/world_ids.h"
|
||||
#include "shell/renderer/extensions/electron_extensions_dispatcher_delegate.h"
|
||||
|
||||
namespace electron {
|
||||
@@ -24,11 +25,7 @@ bool ElectronExtensionsRendererClient::IsIncognitoProcess() const {
|
||||
}
|
||||
|
||||
int ElectronExtensionsRendererClient::GetLowestIsolatedWorldId() const {
|
||||
// app_shell doesn't need to reserve world IDs for anything other than
|
||||
// extensions, so we always return 1. Note that 0 is reserved for the global
|
||||
// world.
|
||||
// TODO(samuelmaddock): skip electron worlds
|
||||
return 10;
|
||||
return WorldIDs::ISOLATED_WORLD_ID_EXTENSIONS;
|
||||
}
|
||||
|
||||
extensions::Dispatcher* ElectronExtensionsRendererClient::GetDispatcher() {
|
||||
|
||||
@@ -24,11 +24,11 @@
|
||||
#include "shell/common/color_util.h"
|
||||
#include "shell/common/gin_helper/dictionary.h"
|
||||
#include "shell/common/options_switches.h"
|
||||
#include "shell/common/world_ids.h"
|
||||
#include "shell/renderer/browser_exposed_renderer_interfaces.h"
|
||||
#include "shell/renderer/content_settings_observer.h"
|
||||
#include "shell/renderer/electron_api_service_impl.h"
|
||||
#include "shell/renderer/electron_autofill_agent.h"
|
||||
#include "shell/renderer/electron_render_frame_observer.h"
|
||||
#include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h"
|
||||
#include "third_party/blink/public/web/blink.h"
|
||||
#include "third_party/blink/public/web/web_custom_element.h" // NOLINT(build/include_alpha)
|
||||
@@ -67,12 +67,16 @@
|
||||
#endif // BUILDFLAG(ENABLE_PRINTING)
|
||||
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "content/public/common/webplugininfo.h"
|
||||
#include "extensions/common/constants.h"
|
||||
#include "extensions/common/extensions_client.h"
|
||||
#include "extensions/renderer/dispatcher.h"
|
||||
#include "extensions/renderer/extension_frame_helper.h"
|
||||
#include "extensions/renderer/guest_view/extensions_guest_view_container.h"
|
||||
#include "extensions/renderer/guest_view/extensions_guest_view_container_dispatcher.h"
|
||||
#include "extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container.h"
|
||||
#include "extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container_manager.h"
|
||||
#include "shell/common/extensions/electron_extensions_client.h"
|
||||
#include "shell/renderer/extensions/electron_extensions_renderer_client.h"
|
||||
#endif // BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
@@ -271,6 +275,11 @@ void RendererClientBase::RenderFrameCreated(
|
||||
new extensions::ExtensionFrameHelper(render_frame, dispatcher);
|
||||
|
||||
dispatcher->OnRenderFrameCreated(render_frame);
|
||||
|
||||
render_frame->GetAssociatedInterfaceRegistry()->AddInterface(
|
||||
base::BindRepeating(
|
||||
&extensions::MimeHandlerViewContainerManager::BindReceiver,
|
||||
render_frame->GetRoutingID()));
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(ENABLE_BUILTIN_SPELLCHECKER)
|
||||
@@ -337,6 +346,52 @@ void RendererClientBase::DidSetUserAgent(const std::string& user_agent) {
|
||||
#endif
|
||||
}
|
||||
|
||||
content::BrowserPluginDelegate* RendererClientBase::CreateBrowserPluginDelegate(
|
||||
content::RenderFrame* render_frame,
|
||||
const content::WebPluginInfo& info,
|
||||
const std::string& mime_type,
|
||||
const GURL& original_url) {
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
// TODO(nornagon): check the mime type isn't content::kBrowserPluginMimeType?
|
||||
return new extensions::MimeHandlerViewContainer(render_frame, info, mime_type,
|
||||
original_url);
|
||||
#else
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool RendererClientBase::IsPluginHandledExternally(
|
||||
content::RenderFrame* render_frame,
|
||||
const blink::WebElement& plugin_element,
|
||||
const GURL& original_url,
|
||||
const std::string& mime_type) {
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS) && BUILDFLAG(ENABLE_PLUGINS)
|
||||
DCHECK(plugin_element.HasHTMLTagName("object") ||
|
||||
plugin_element.HasHTMLTagName("embed"));
|
||||
// TODO(nornagon): this info should be shared with the data in
|
||||
// electron_content_client.cc / ComputeBuiltInPlugins.
|
||||
content::WebPluginInfo info;
|
||||
info.type = content::WebPluginInfo::PLUGIN_TYPE_BROWSER_PLUGIN;
|
||||
info.name = base::UTF8ToUTF16("Chromium PDF Viewer");
|
||||
info.path = base::FilePath::FromUTF8Unsafe(extension_misc::kPdfExtensionId);
|
||||
info.background_color = content::WebPluginInfo::kDefaultBackgroundColor;
|
||||
info.mime_types.emplace_back("application/pdf", "pdf",
|
||||
"Portable Document Format");
|
||||
return extensions::MimeHandlerViewContainerManager::Get(
|
||||
content::RenderFrame::FromWebFrame(
|
||||
plugin_element.GetDocument().GetFrame()),
|
||||
true /* create_if_does_not_exist */)
|
||||
->CreateFrameContainer(plugin_element, original_url, mime_type, info);
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool RendererClientBase::IsOriginIsolatedPepperPlugin(
|
||||
const base::FilePath& plugin_path) {
|
||||
return plugin_path.value() == kPdfPluginPath;
|
||||
}
|
||||
|
||||
std::unique_ptr<blink::WebPrescientNetworking>
|
||||
RendererClientBase::CreatePrescientNetworking(
|
||||
content::RenderFrame* render_frame) {
|
||||
@@ -369,7 +424,7 @@ v8::Local<v8::Context> RendererClientBase::GetContext(
|
||||
blink::WebLocalFrame* frame,
|
||||
v8::Isolate* isolate) const {
|
||||
if (isolated_world())
|
||||
return frame->WorldScriptContext(isolate, World::ISOLATED_WORLD);
|
||||
return frame->WorldScriptContext(isolate, WorldIDs::ISOLATED_WORLD_ID);
|
||||
else
|
||||
return frame->MainWorldScriptContext();
|
||||
}
|
||||
|
||||
@@ -100,6 +100,16 @@ class RendererClientBase : public content::ContentRendererClient
|
||||
override;
|
||||
bool IsKeySystemsUpdateNeeded() override;
|
||||
void DidSetUserAgent(const std::string& user_agent) override;
|
||||
content::BrowserPluginDelegate* CreateBrowserPluginDelegate(
|
||||
content::RenderFrame* render_frame,
|
||||
const content::WebPluginInfo& info,
|
||||
const std::string& mime_type,
|
||||
const GURL& original_url) override;
|
||||
bool IsPluginHandledExternally(content::RenderFrame* render_frame,
|
||||
const blink::WebElement& plugin_element,
|
||||
const GURL& original_url,
|
||||
const std::string& mime_type) override;
|
||||
bool IsOriginIsolatedPepperPlugin(const base::FilePath& plugin_path) override;
|
||||
|
||||
void RunScriptsAtDocumentStart(content::RenderFrame* render_frame) override;
|
||||
void RunScriptsAtDocumentEnd(content::RenderFrame* render_frame) override;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user