mirror of
https://github.com/electron/electron.git
synced 2026-02-26 03:01:17 -05:00
Compare commits
150 Commits
v6.0.0-bet
...
v6.0.0-bet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
adffa99e05 | ||
|
|
51f03033a4 | ||
|
|
733251866c | ||
|
|
41a7d9e42b | ||
|
|
ddbbf34433 | ||
|
|
6f65dec6a2 | ||
|
|
a66657112c | ||
|
|
f5c3394930 | ||
|
|
84bae64def | ||
|
|
4185b93abb | ||
|
|
b1e9f50fad | ||
|
|
6bd901d9ca | ||
|
|
1c2b8f8d9a | ||
|
|
cb9b288d8b | ||
|
|
69fe33a2b1 | ||
|
|
52b42546ed | ||
|
|
8a285f29ed | ||
|
|
92df6cc36c | ||
|
|
ab91656148 | ||
|
|
1fb1e5b2b2 | ||
|
|
54908b56e5 | ||
|
|
48bc247ef7 | ||
|
|
19d9955125 | ||
|
|
24d79d9e5c | ||
|
|
27d0a4d33d | ||
|
|
48226f71ad | ||
|
|
a4acc16e10 | ||
|
|
d8dd94e3a3 | ||
|
|
eb48dcf0a3 | ||
|
|
adfe537e32 | ||
|
|
0d5d54cbae | ||
|
|
988ad92415 | ||
|
|
5dbcdbc3d8 | ||
|
|
212c6b1266 | ||
|
|
74b06ab677 | ||
|
|
9a1c952ab6 | ||
|
|
f36f90b60f | ||
|
|
a603a4dde8 | ||
|
|
3e033b4f27 | ||
|
|
03be4c67d5 | ||
|
|
b20fe76db7 | ||
|
|
503da640f7 | ||
|
|
bd48dfe3cc | ||
|
|
9b47f587a6 | ||
|
|
3a186dad5d | ||
|
|
7959f2e887 | ||
|
|
4868c95425 | ||
|
|
7fa41e3302 | ||
|
|
f3346437be | ||
|
|
6de6d7f6c0 | ||
|
|
eb15be06e3 | ||
|
|
7748decc60 | ||
|
|
d75750ab01 | ||
|
|
152781226e | ||
|
|
7e3bbb6ace | ||
|
|
3c3eb2f65d | ||
|
|
5a83d9e64d | ||
|
|
97bec607fe | ||
|
|
b56ca98b72 | ||
|
|
eeccdc2d5c | ||
|
|
47827ed45c | ||
|
|
d3f7bdd0b3 | ||
|
|
438c50bf14 | ||
|
|
33d860bcea | ||
|
|
2401a2afe9 | ||
|
|
852f0be0b2 | ||
|
|
18ec438eaf | ||
|
|
f7042c8d1b | ||
|
|
bc73f93e6c | ||
|
|
7091508678 | ||
|
|
6d9d66b88a | ||
|
|
fc35b0f1be | ||
|
|
17f86b1223 | ||
|
|
271531f5ff | ||
|
|
9ef83cd8a0 | ||
|
|
f33517dfa7 | ||
|
|
c69f5d9366 | ||
|
|
7902c3ced4 | ||
|
|
21f033474d | ||
|
|
549ac1ed48 | ||
|
|
2dd8d1f150 | ||
|
|
26ee461c32 | ||
|
|
9905a4c328 | ||
|
|
09a22143d6 | ||
|
|
81e8f5c6c2 | ||
|
|
3c322b7349 | ||
|
|
b2ea1bc517 | ||
|
|
16250493b8 | ||
|
|
08887e016c | ||
|
|
aadcce0907 | ||
|
|
9b5353309d | ||
|
|
76303502a6 | ||
|
|
cf07904338 | ||
|
|
8f1e28b59c | ||
|
|
10d0268070 | ||
|
|
7871e18232 | ||
|
|
ceb3792f3c | ||
|
|
65a4bdd87a | ||
|
|
7094870a44 | ||
|
|
cee99b5f2d | ||
|
|
ac86d362ba | ||
|
|
2233a9eb5a | ||
|
|
af24a4f364 | ||
|
|
a78692f5b8 | ||
|
|
335178098d | ||
|
|
ddc0e8f7ba | ||
|
|
80fa2449a1 | ||
|
|
476abafefe | ||
|
|
f7d4d51261 | ||
|
|
7b08510075 | ||
|
|
14b62b28ce | ||
|
|
1c44ed0912 | ||
|
|
de1edf3f4d | ||
|
|
a21ffa027a | ||
|
|
899d42563c | ||
|
|
6eecbb5edd | ||
|
|
6a8e7a10ea | ||
|
|
85bb488732 | ||
|
|
c957215854 | ||
|
|
2ba3a26785 | ||
|
|
f0dc3bc79f | ||
|
|
28d3edcd92 | ||
|
|
8026dee591 | ||
|
|
197cda9e45 | ||
|
|
903fd4e5e9 | ||
|
|
621c86b4cf | ||
|
|
deda7c700f | ||
|
|
d225304370 | ||
|
|
fd22b7ec2a | ||
|
|
a2b1d394b5 | ||
|
|
7d4c78e73e | ||
|
|
b37ff2b822 | ||
|
|
5887f5aa4f | ||
|
|
a9176a2ac8 | ||
|
|
6ceb431942 | ||
|
|
508d131c95 | ||
|
|
ae36659f7a | ||
|
|
f970660766 | ||
|
|
43c5837cda | ||
|
|
a87e88df20 | ||
|
|
5a5d4b06b3 | ||
|
|
28ba88ba70 | ||
|
|
4f8ffe934e | ||
|
|
c5c0a7abc5 | ||
|
|
84b762f0b3 | ||
|
|
043838f9b6 | ||
|
|
a824e92628 | ||
|
|
1843411e79 | ||
|
|
da76c4d7c5 | ||
|
|
4468b86a81 |
@@ -35,6 +35,7 @@ env-debug-build: &env-debug-build
|
||||
|
||||
env-testing-build: &env-testing-build
|
||||
GN_CONFIG: //electron/build/args/testing.gn
|
||||
CHECK_DIST_MANIFEST: '1'
|
||||
|
||||
env-release-build: &env-release-build
|
||||
GN_CONFIG: //electron/build/args/release.gn
|
||||
@@ -279,6 +280,28 @@ step-electron-dist-build: &step-electron-dist-build
|
||||
command: |
|
||||
cd src
|
||||
ninja -C out/Default electron:electron_dist_zip
|
||||
if [ "$CHECK_DIST_MANIFEST" == "1" ]; then
|
||||
if [ "`uname`" == "Darwin" ]; then
|
||||
target_os=mac
|
||||
target_cpu=x64
|
||||
if [ x"$MAS_BUILD" == x"true" ]; then
|
||||
target_os=mac_mas
|
||||
fi
|
||||
elif [ "`uname`" == "Linux" ]; then
|
||||
target_os=linux
|
||||
if [ x"$TARGET_ARCH" == x ]; then
|
||||
target_cpu=x64
|
||||
elif [ "$TARGET_ARCH" == "ia32" ]; then
|
||||
target_cpu=x86
|
||||
else
|
||||
target_cpu="$TARGET_ARCH"
|
||||
fi
|
||||
else
|
||||
echo "Unknown system: `uname`"
|
||||
exit 1
|
||||
fi
|
||||
electron/script/zip_manifests/check-zip-manifest.py out/Default/dist.zip electron/script/zip_manifests/dist_zip.$target_os.$target_cpu.manifest
|
||||
fi
|
||||
|
||||
step-electron-dist-store: &step-electron-dist-store
|
||||
store_artifacts:
|
||||
@@ -427,25 +450,13 @@ step-mksnapshot-store: &step-mksnapshot-store
|
||||
path: src/out/Default/mksnapshot.zip
|
||||
destination: mksnapshot.zip
|
||||
|
||||
step-maybe-build-dump-syms: &step-maybe-build-dump-syms
|
||||
run:
|
||||
name: Build dump_syms binary
|
||||
command: |
|
||||
if [ "$GENERATE_SYMBOLS" == "true" ]; then
|
||||
cd src
|
||||
# Build needed dump_syms executable
|
||||
ninja -C out/Default third_party/breakpad:dump_syms
|
||||
fi
|
||||
|
||||
step-maybe-generate-breakpad-symbols: &step-maybe-generate-breakpad-symbols
|
||||
run:
|
||||
name: Generate breakpad symbols
|
||||
command: |
|
||||
if [ "$GENERATE_SYMBOLS" == "true" ]; then
|
||||
cd src
|
||||
export BUILD_PATH="$PWD/out/Default"
|
||||
export DEST_PATH="$BUILD_PATH/breakpad_symbols"
|
||||
electron/script/dump-symbols.py -b $BUILD_PATH -d $DEST_PATH -v
|
||||
ninja -C out/Default electron:electron_symbols
|
||||
fi
|
||||
|
||||
step-maybe-zip-symbols: &step-maybe-zip-symbols
|
||||
@@ -653,7 +664,6 @@ steps-electron-build-for-tests: &steps-electron-build-for-tests
|
||||
# Save all data needed for a further tests run.
|
||||
- *step-persist-data-for-tests
|
||||
|
||||
- *step-maybe-build-dump-syms
|
||||
- *step-maybe-generate-breakpad-symbols
|
||||
- *step-maybe-zip-symbols
|
||||
|
||||
@@ -679,7 +689,6 @@ steps-electron-build-for-publish: &steps-electron-build-for-publish
|
||||
- *step-maybe-electron-dist-strip
|
||||
- *step-electron-dist-build
|
||||
- *step-electron-dist-store
|
||||
- *step-maybe-build-dump-syms
|
||||
- *step-maybe-generate-breakpad-symbols
|
||||
- *step-maybe-zip-symbols
|
||||
|
||||
@@ -792,7 +801,7 @@ steps-tests: &steps-tests
|
||||
name: Run Electron tests
|
||||
environment:
|
||||
MOCHA_REPORTER: mocha-multi-reporters
|
||||
MOCHA_FILE: junit/test-results.xml
|
||||
ELECTRON_TEST_RESULTS_DIR: junit
|
||||
MOCHA_MULTI_REPORTERS: mocha-junit-reporter, tap
|
||||
ELECTRON_DISABLE_SECURITY_WARNINGS: 1
|
||||
command: |
|
||||
@@ -802,15 +811,13 @@ steps-tests: &steps-tests
|
||||
- run:
|
||||
name: Check test results existence
|
||||
command: |
|
||||
MOCHA_FILE='src/junit/test-results-remote.xml'
|
||||
# Check if it exists and not empty.
|
||||
if [ ! -s "$MOCHA_FILE" ]; then
|
||||
cd src
|
||||
|
||||
# Check if test results exist and are not empty.
|
||||
if [ ! -s "junit/test-results-remote.xml" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
MOCHA_FILE='src/junit/test-results-main.xml'
|
||||
# Check if it exists and not empty.
|
||||
if [ ! -s "$MOCHA_FILE" ]; then
|
||||
if [ ! -s "junit/test-results-main.xml" ]; then
|
||||
exit 1
|
||||
fi
|
||||
- store_test_results:
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# These env vars are only necessary for creating Electron releases.
|
||||
# See docs/development/releasing.md
|
||||
|
||||
APPVEYOR_TOKEN=
|
||||
APPVEYOR_CLOUD_TOKEN=
|
||||
CIRCLE_TOKEN=
|
||||
ELECTRON_GITHUB_TOKEN=
|
||||
VSTS_TOKEN=
|
||||
204
BUILD.gn
204
BUILD.gn
@@ -8,8 +8,9 @@ import("//tools/generate_library_loader/generate_library_loader.gni")
|
||||
import("//tools/grit/grit_rule.gni")
|
||||
import("//tools/grit/repack.gni")
|
||||
import("//tools/v8_context_snapshot/v8_context_snapshot.gni")
|
||||
import("//v8/snapshot_toolchain.gni")
|
||||
import("//v8/gni/snapshot_toolchain.gni")
|
||||
import("build/asar.gni")
|
||||
import("build/extract_symbols.gni")
|
||||
import("build/js_wrap.gni")
|
||||
import("build/npm.gni")
|
||||
import("build/tsc.gni")
|
||||
@@ -21,6 +22,7 @@ import("filenames.gni")
|
||||
if (is_mac) {
|
||||
import("//build/config/mac/rules.gni")
|
||||
import("//third_party/icu/config.gni")
|
||||
import("//ui/gl/features.gni")
|
||||
import("//v8/gni/v8.gni")
|
||||
}
|
||||
|
||||
@@ -545,22 +547,14 @@ static_library("electron_lib") {
|
||||
|
||||
if (is_mac) {
|
||||
deps += [
|
||||
"//third_party/crashpad/crashpad/client",
|
||||
"//components/remote_cocoa/app_shim",
|
||||
"//ui/accelerated_widget_mac",
|
||||
"//ui/views_bridge_mac",
|
||||
]
|
||||
sources += [
|
||||
"atom/browser/ui/views/autofill_popup_view.cc",
|
||||
"atom/browser/ui/views/autofill_popup_view.h",
|
||||
]
|
||||
include_dirs += [
|
||||
# NOTE(nornagon): other chromium files use the full path to include
|
||||
# crashpad; this is just here for compatibility between GN and GYP, so that
|
||||
# the #includes can be agnostic about where crashpad is vendored.
|
||||
"//third_party/crashpad",
|
||||
]
|
||||
if (is_mas_build) {
|
||||
deps -= [ "//third_party/crashpad/crashpad/client" ]
|
||||
sources += [ "atom/browser/api/atom_api_app_mas.mm" ]
|
||||
sources -= [
|
||||
"atom/browser/auto_updater_mac.mm",
|
||||
@@ -590,10 +584,14 @@ static_library("electron_lib") {
|
||||
"//chrome/browser/ui/libgtkui",
|
||||
"//dbus",
|
||||
"//device/bluetooth",
|
||||
"//third_party/breakpad:client",
|
||||
"//ui/events/devices/x11",
|
||||
"//ui/events/platform/x11",
|
||||
"//ui/views/controls/webview",
|
||||
"//ui/wm",
|
||||
]
|
||||
configs += [ ":gio_unix" ]
|
||||
include_dirs += [ "//third_party/breakpad" ]
|
||||
defines += [
|
||||
# Disable warnings for g_settings_list_schemas.
|
||||
"GLIB_DISABLE_DEPRECATION_WARNINGS",
|
||||
@@ -604,20 +602,23 @@ static_library("electron_lib") {
|
||||
if (is_win) {
|
||||
libs += [ "dwmapi.lib" ]
|
||||
deps += [
|
||||
"//third_party/breakpad:breakpad_handler",
|
||||
"//third_party/breakpad:breakpad_sender",
|
||||
"//ui/native_theme:native_theme_browser",
|
||||
"//ui/wm/public",
|
||||
]
|
||||
public_deps += [ "//sandbox/win:sandbox" ]
|
||||
}
|
||||
if (is_linux || is_win) {
|
||||
deps += [
|
||||
"//third_party/breakpad:client",
|
||||
"//ui/views/controls/webview",
|
||||
"//ui/wm",
|
||||
"//ui/wm/public",
|
||||
]
|
||||
include_dirs += [ "//third_party/breakpad" ]
|
||||
public_deps += [
|
||||
"//sandbox/win:sandbox",
|
||||
"//third_party/crashpad/crashpad/handler",
|
||||
]
|
||||
}
|
||||
|
||||
if ((is_mac && !is_mas_build) || is_win) {
|
||||
sources += [
|
||||
"atom/common/crash_reporter/crash_reporter_crashpad.cc",
|
||||
"atom/common/crash_reporter/crash_reporter_crashpad.h",
|
||||
]
|
||||
deps += [ "//third_party/crashpad/crashpad/client" ]
|
||||
}
|
||||
|
||||
if (enable_pdf) {
|
||||
@@ -712,6 +713,7 @@ if (is_mac) {
|
||||
electron_helper_name = "$electron_product_name Helper"
|
||||
electron_login_helper_name = "$electron_product_name Login Helper"
|
||||
electron_framework_version = "A"
|
||||
electron_version = read_file("ELECTRON_VERSION", "trim string")
|
||||
|
||||
mac_xib_bundle_data("electron_xibs") {
|
||||
sources = [
|
||||
@@ -759,6 +761,50 @@ if (is_mac) {
|
||||
group("electron_framework_libraries") {
|
||||
}
|
||||
}
|
||||
if (use_egl) {
|
||||
# Add the ANGLE .dylibs in the Libraries directory of the Framework.
|
||||
bundle_data("electron_angle_binaries") {
|
||||
sources = [
|
||||
"$root_out_dir/egl_intermediates/libEGL.dylib",
|
||||
"$root_out_dir/egl_intermediates/libGLESv2.dylib",
|
||||
]
|
||||
outputs = [
|
||||
"{{bundle_contents_dir}}/Libraries/{{source_file_part}}",
|
||||
]
|
||||
public_deps = [
|
||||
"//ui/gl:angle_library_copy",
|
||||
]
|
||||
}
|
||||
|
||||
# Add the SwiftShader .dylibs in the Libraries directory of the Framework.
|
||||
bundle_data("electron_swiftshader_binaries") {
|
||||
sources = [
|
||||
"$root_out_dir/egl_intermediates/libswiftshader_libEGL.dylib",
|
||||
"$root_out_dir/egl_intermediates/libswiftshader_libGLESv2.dylib",
|
||||
]
|
||||
outputs = [
|
||||
"{{bundle_contents_dir}}/Libraries/{{source_file_part}}",
|
||||
]
|
||||
public_deps = [
|
||||
"//ui/gl:swiftshader_library_copy",
|
||||
]
|
||||
}
|
||||
}
|
||||
group("electron_angle_library") {
|
||||
if (use_egl) {
|
||||
deps = [
|
||||
":electron_angle_binaries",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
group("electron_swiftshader_library") {
|
||||
if (use_egl) {
|
||||
deps = [
|
||||
":electron_swiftshader_binaries",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
bundle_data("electron_crashpad_helper") {
|
||||
sources = [
|
||||
@@ -785,8 +831,10 @@ if (is_mac) {
|
||||
":electron_lib",
|
||||
]
|
||||
deps = [
|
||||
":electron_angle_library",
|
||||
":electron_framework_libraries",
|
||||
":electron_framework_resources",
|
||||
":electron_swiftshader_library",
|
||||
":electron_xibs",
|
||||
]
|
||||
if (!is_mas_build) {
|
||||
@@ -794,7 +842,6 @@ if (is_mac) {
|
||||
}
|
||||
info_plist = "atom/common/resources/mac/Info.plist"
|
||||
|
||||
electron_version = read_file("ELECTRON_VERSION", "trim string")
|
||||
extra_substitutions = [
|
||||
"ATOM_BUNDLE_ID=$electron_mac_bundle_id.framework",
|
||||
"ELECTRON_VERSION=$electron_version",
|
||||
@@ -844,6 +891,7 @@ if (is_mac) {
|
||||
}
|
||||
defines = [ "HELPER_EXECUTABLE" ]
|
||||
sources = filenames.app_sources
|
||||
sources += [ "atom/common/atom_constants.cc" ]
|
||||
include_dirs = [ "." ]
|
||||
info_plist = "atom/renderer/resources/mac/Info.plist"
|
||||
extra_substitutions = [ "ATOM_BUNDLE_ID=$electron_mac_bundle_id.helper" ]
|
||||
@@ -951,6 +999,7 @@ if (is_mac) {
|
||||
mac_app_bundle("electron_app") {
|
||||
output_name = electron_product_name
|
||||
sources = filenames.app_sources
|
||||
sources += [ "atom/common/atom_constants.cc" ]
|
||||
include_dirs = [ "." ]
|
||||
deps = [
|
||||
":electron_app_framework_bundle_data",
|
||||
@@ -966,6 +1015,76 @@ if (is_mac) {
|
||||
"@executable_path/../Frameworks",
|
||||
]
|
||||
}
|
||||
|
||||
if (enable_dsyms) {
|
||||
extract_symbols("electron_framework_syms") {
|
||||
binary = "$root_out_dir/$electron_framework_name.framework/Versions/$electron_framework_version/$electron_framework_name"
|
||||
symbol_dir = "$root_out_dir/breakpad_symbols"
|
||||
dsym_file = "$root_out_dir/$electron_framework_name.dSYM/Contents/Resources/DWARF/$electron_framework_name"
|
||||
deps = [
|
||||
":electron_framework",
|
||||
]
|
||||
}
|
||||
|
||||
extract_symbols("electron_helper_syms") {
|
||||
binary = "$root_out_dir/$electron_helper_name.app/Contents/MacOS/$electron_helper_name"
|
||||
symbol_dir = "$root_out_dir/breakpad_symbols"
|
||||
dsym_file = "$root_out_dir/$electron_helper_name.dSYM/Contents/Resources/DWARF/$electron_helper_name"
|
||||
deps = [
|
||||
":electron_helper_app",
|
||||
]
|
||||
}
|
||||
|
||||
extract_symbols("electron_app_syms") {
|
||||
binary = "$root_out_dir/$electron_product_name.app/Contents/MacOS/$electron_product_name"
|
||||
symbol_dir = "$root_out_dir/breakpad_symbols"
|
||||
dsym_file = "$root_out_dir/$electron_product_name.dSYM/Contents/Resources/DWARF/$electron_product_name"
|
||||
deps = [
|
||||
":electron_app",
|
||||
]
|
||||
}
|
||||
|
||||
extract_symbols("swiftshader_egl_syms") {
|
||||
binary = "$root_out_dir/libswiftshader_libEGL.dylib"
|
||||
symbol_dir = "$root_out_dir/breakpad_symbols"
|
||||
dsym_file = "$root_out_dir/libswiftshader_libEGL.dylib.dSYM/Contents/Resources/DWARF/libswiftshader_libEGL.dylib"
|
||||
deps = [
|
||||
"//third_party/swiftshader/src/OpenGL/libEGL:swiftshader_libEGL",
|
||||
]
|
||||
}
|
||||
|
||||
extract_symbols("swiftshader_gles_syms") {
|
||||
binary = "$root_out_dir/libswiftshader_libGLESv2.dylib"
|
||||
symbol_dir = "$root_out_dir/breakpad_symbols"
|
||||
dsym_file = "$root_out_dir/libswiftshader_libGLESv2.dylib.dSYM/Contents/Resources/DWARF/libswiftshader_libGLESv2.dylib"
|
||||
deps = [
|
||||
"//third_party/swiftshader/src/OpenGL/libGLESv2:swiftshader_libGLESv2",
|
||||
]
|
||||
}
|
||||
|
||||
extract_symbols("crashpad_handler_syms") {
|
||||
binary = "$root_out_dir/crashpad_handler"
|
||||
symbol_dir = "$root_out_dir/breakpad_symbols"
|
||||
dsym_file = "$root_out_dir/crashpad_handler.dSYM/Contents/Resources/DWARF/crashpad_handler"
|
||||
deps = [
|
||||
"//third_party/crashpad/crashpad/handler:crashpad_handler",
|
||||
]
|
||||
}
|
||||
|
||||
group("electron_symbols") {
|
||||
deps = [
|
||||
":crashpad_handler_syms",
|
||||
":electron_app_syms",
|
||||
":electron_framework_syms",
|
||||
":electron_helper_syms",
|
||||
":swiftshader_egl_syms",
|
||||
":swiftshader_gles_syms",
|
||||
]
|
||||
}
|
||||
} else {
|
||||
group("electron_symbols") {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
windows_manifest("electron_app_manifest") {
|
||||
sources = [
|
||||
@@ -1054,6 +1173,49 @@ if (is_mac) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (is_official_build) {
|
||||
if (is_linux) {
|
||||
_target_executable_suffix = ""
|
||||
_target_shared_library_suffix = ".so"
|
||||
} else if (is_win) {
|
||||
_target_executable_suffix = ".exe"
|
||||
_target_shared_library_suffix = ".dll"
|
||||
}
|
||||
|
||||
extract_symbols("electron_app_symbols") {
|
||||
binary = "$root_out_dir/$electron_project_name$_target_executable_suffix"
|
||||
symbol_dir = "$root_out_dir/breakpad_symbols"
|
||||
deps = [
|
||||
":electron_app",
|
||||
]
|
||||
}
|
||||
|
||||
extract_symbols("swiftshader_egl_symbols") {
|
||||
binary = "$root_out_dir/swiftshader/libEGL$_target_shared_library_suffix"
|
||||
symbol_dir = "$root_out_dir/breakpad_symbols"
|
||||
deps = [
|
||||
"//third_party/swiftshader/src/OpenGL/libEGL:swiftshader_libEGL",
|
||||
]
|
||||
}
|
||||
|
||||
extract_symbols("swiftshader_gles_symbols") {
|
||||
binary =
|
||||
"$root_out_dir/swiftshader/libGLESv2$_target_shared_library_suffix"
|
||||
symbol_dir = "$root_out_dir/breakpad_symbols"
|
||||
deps = [
|
||||
"//third_party/swiftshader/src/OpenGL/libGLESv2:swiftshader_libGLESv2",
|
||||
]
|
||||
}
|
||||
|
||||
group("electron_symbols") {
|
||||
deps = [
|
||||
":electron_app_symbols",
|
||||
":swiftshader_egl_symbols",
|
||||
":swiftshader_gles_symbols",
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template("dist_zip") {
|
||||
|
||||
4
DEPS
4
DEPS
@@ -10,9 +10,9 @@ gclient_gn_args = [
|
||||
|
||||
vars = {
|
||||
'chromium_version':
|
||||
'76.0.3783.1',
|
||||
'76.0.3809.60',
|
||||
'node_version':
|
||||
'a86a4a160dc520c61a602c949a32a1bc4c0fc633',
|
||||
'0a300f60bce0c8f0cb3d846fcb0e1f55f26013ee',
|
||||
|
||||
'boto_version': 'f7574aa6cc2c819430c1f05e9a1a1a666ef8169b',
|
||||
'pyyaml_version': '3.12',
|
||||
|
||||
@@ -16,7 +16,7 @@ RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \
|
||||
locales \
|
||||
lsb-release \
|
||||
nano \
|
||||
python-dbusmock \
|
||||
python-dbus \
|
||||
python-pip \
|
||||
python-setuptools \
|
||||
sudo \
|
||||
@@ -33,6 +33,9 @@ RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - \
|
||||
# crcmod is required by gsutil, which is used for filling the gclient git cache
|
||||
RUN pip install -U crcmod
|
||||
|
||||
# dbusmock is needed for Electron tests
|
||||
RUN pip install python-dbusmock
|
||||
|
||||
RUN mkdir /tmp/workspace
|
||||
RUN chown builduser:builduser /tmp/workspace
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
6.0.0-beta.3
|
||||
6.0.0-beta.13
|
||||
@@ -28,7 +28,6 @@ build_cloud: libcc-20
|
||||
image: libcc-20-vs2017-15.9
|
||||
environment:
|
||||
GIT_CACHE_PATH: C:\Users\electron\libcc_cache
|
||||
DISABLE_CRASH_REPORTER_TESTS: true
|
||||
ELECTRON_OUT_DIR: Default
|
||||
ELECTRON_ENABLE_STACK_DUMPING: 1
|
||||
build_script:
|
||||
@@ -73,14 +72,16 @@ build_script:
|
||||
- appveyor PushArtifact out/ffmpeg/ffmpeg.zip
|
||||
- ps: >-
|
||||
if ($env:GN_CONFIG -eq 'release') {
|
||||
ninja -C out/Default third_party/breakpad:dump_syms
|
||||
# Needed for msdia140.dll on 64-bit windows
|
||||
$env:Path += ";$pwd\third_party\llvm-build\Release+Asserts\bin"
|
||||
ninja -C out/Default electron:electron_symbols
|
||||
}
|
||||
- if "%GN_CONFIG%"=="release" ( python electron\script\dump-symbols.py -d %cd%\out\Default\breakpad_symbols -v)
|
||||
- ps: >-
|
||||
if ($env:GN_CONFIG -eq 'release') {
|
||||
python electron\script\zip-symbols.py
|
||||
appveyor PushArtifact out/Default/symbols.zip
|
||||
}
|
||||
- python electron/script/zip_manifests/check-zip-manifest.py out/Default/dist.zip electron/script/zip_manifests/dist_zip.win.%TARGET_ARCH%.manifest
|
||||
test_script:
|
||||
# Workaround for https://github.com/appveyor/ci/issues/2420
|
||||
- set "PATH=%PATH%;C:\Program Files\Git\mingw64\libexec\git-core"
|
||||
|
||||
@@ -268,4 +268,8 @@ void AtomContentClient::AddContentDecryptionModules(
|
||||
}
|
||||
}
|
||||
|
||||
bool AtomContentClient::IsDataResourceGzipped(int resource_id) const {
|
||||
return ui::ResourceBundle::GetSharedInstance().IsGzipped(resource_id);
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -31,6 +31,7 @@ class AtomContentClient : public content::ContentClient {
|
||||
void AddContentDecryptionModules(
|
||||
std::vector<content::CdmInfo>* cdms,
|
||||
std::vector<media::CdmHostFilePath>* cdm_host_file_paths) override;
|
||||
bool IsDataResourceGzipped(int resource_id) const override;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomContentClient);
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include "atom/app/atom_main.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdlib>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
@@ -39,6 +40,7 @@
|
||||
|
||||
#include "atom/app/node_main.h"
|
||||
#include "atom/common/atom_command_line.h"
|
||||
#include "atom/common/atom_constants.h"
|
||||
#include "base/at_exit.h"
|
||||
#include "base/i18n/icu_util.h"
|
||||
#include "electron/buildflags/buildflags.h"
|
||||
@@ -49,10 +51,6 @@
|
||||
|
||||
namespace {
|
||||
|
||||
#if BUILDFLAG(ENABLE_RUN_AS_NODE)
|
||||
const char kRunAsNode[] = "ELECTRON_RUN_AS_NODE";
|
||||
#endif
|
||||
|
||||
ALLOW_UNUSED_TYPE bool IsEnvSet(const char* name) {
|
||||
#if defined(OS_WIN)
|
||||
size_t required_size;
|
||||
@@ -86,6 +84,11 @@ void FixStdioStreams() {
|
||||
} // namespace
|
||||
|
||||
#if defined(OS_WIN)
|
||||
|
||||
namespace crash_reporter {
|
||||
extern const char kCrashpadProcess[];
|
||||
}
|
||||
|
||||
int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
|
||||
struct Arguments {
|
||||
int argc = 0;
|
||||
@@ -122,7 +125,7 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(ENABLE_RUN_AS_NODE)
|
||||
bool run_as_node = IsEnvSet(kRunAsNode);
|
||||
bool run_as_node = IsEnvSet(atom::kRunAsNode);
|
||||
#else
|
||||
bool run_as_node = false;
|
||||
#endif
|
||||
@@ -148,13 +151,11 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
|
||||
atexit([]() { OnThreadExit(nullptr, DLL_THREAD_DETACH, nullptr); });
|
||||
#endif
|
||||
|
||||
std::vector<char*> argv(arguments.argc);
|
||||
std::transform(arguments.argv, arguments.argv + arguments.argc, argv.begin(),
|
||||
[](auto& a) { return _strdup(base::WideToUTF8(a).c_str()); });
|
||||
#if BUILDFLAG(ENABLE_RUN_AS_NODE)
|
||||
if (run_as_node) {
|
||||
std::vector<char*> argv(arguments.argc);
|
||||
std::transform(
|
||||
arguments.argv, arguments.argv + arguments.argc, argv.begin(),
|
||||
[](auto& a) { return _strdup(base::WideToUTF8(a).c_str()); });
|
||||
|
||||
base::AtExitManager atexit_manager;
|
||||
base::i18n::InitializeICU();
|
||||
auto ret = atom::NodeMain(argv.size(), argv.data());
|
||||
@@ -163,8 +164,11 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
|
||||
}
|
||||
#endif
|
||||
|
||||
if (IsEnvSet("ELECTRON_INTERNAL_CRASH_SERVICE")) {
|
||||
return crash_service::Main(cmd);
|
||||
base::CommandLine::Init(argv.size(), argv.data());
|
||||
const base::CommandLine& cmd_line = *base::CommandLine::ForCurrentProcess();
|
||||
if (cmd_line.GetSwitchValueASCII("type") ==
|
||||
crash_reporter::kCrashpadProcess) {
|
||||
return crash_service::Main(&argv);
|
||||
}
|
||||
|
||||
if (!atom::CheckCommandLineArguments(arguments.argc, arguments.argv))
|
||||
@@ -187,7 +191,7 @@ int main(int argc, char* argv[]) {
|
||||
FixStdioStreams();
|
||||
|
||||
#if BUILDFLAG(ENABLE_RUN_AS_NODE)
|
||||
if (IsEnvSet(kRunAsNode)) {
|
||||
if (IsEnvSet(atom::kRunAsNode)) {
|
||||
base::i18n::InitializeICU();
|
||||
base::AtExitManager atexit_manager;
|
||||
return atom::NodeMain(argc, argv);
|
||||
@@ -208,7 +212,7 @@ int main(int argc, char* argv[]) {
|
||||
FixStdioStreams();
|
||||
|
||||
#if BUILDFLAG(ENABLE_RUN_AS_NODE)
|
||||
if (IsEnvSet(kRunAsNode)) {
|
||||
if (IsEnvSet(atom::kRunAsNode)) {
|
||||
return AtomInitializeICUandStartNode(argc, argv);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -47,6 +47,13 @@
|
||||
#include "atom/app/atom_main_delegate_mac.h"
|
||||
#endif
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include "base/win/win_util.h"
|
||||
#if defined(_WIN64)
|
||||
#include "atom/common/crash_reporter/crash_reporter_win.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace {
|
||||
@@ -129,6 +136,10 @@ bool AtomMainDelegate::BasicStartupComplete(int* exit_code) {
|
||||
|
||||
logging::LoggingSettings settings;
|
||||
#if defined(OS_WIN)
|
||||
#if defined(_WIN64)
|
||||
crash_reporter::CrashReporterWin::SetUnhandledExceptionFilter();
|
||||
#endif
|
||||
|
||||
// On Windows the terminal returns immediately, so we add a new line to
|
||||
// prevent output in the same line as the prompt.
|
||||
if (IsBrowserProcess(command_line))
|
||||
@@ -140,10 +151,12 @@ bool AtomMainDelegate::BasicStartupComplete(int* exit_code) {
|
||||
settings.lock_log = logging::LOCK_LOG_FILE;
|
||||
settings.delete_old = logging::DELETE_OLD_LOG_FILE;
|
||||
#else
|
||||
settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
|
||||
settings.logging_dest =
|
||||
logging::LOG_TO_SYSTEM_DEBUG_LOG | logging::LOG_TO_STDERR;
|
||||
#endif // defined(DEBUG)
|
||||
#else // defined(OS_WIN)
|
||||
settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
|
||||
settings.logging_dest =
|
||||
logging::LOG_TO_SYSTEM_DEBUG_LOG | logging::LOG_TO_STDERR;
|
||||
#endif // !defined(OS_WIN)
|
||||
|
||||
// Only enable logging when --enable-logging is specified.
|
||||
@@ -181,6 +194,9 @@ bool AtomMainDelegate::BasicStartupComplete(int* exit_code) {
|
||||
// Disable the ActiveVerifier, which is used by Chrome to track possible
|
||||
// bugs, but no use in Electron.
|
||||
base::win::DisableHandleVerifier();
|
||||
|
||||
if (IsBrowserProcess(command_line))
|
||||
base::win::PinUser32();
|
||||
#endif
|
||||
|
||||
content_client_ = std::make_unique<AtomContentClient>();
|
||||
|
||||
@@ -18,6 +18,22 @@
|
||||
#include "chrome/services/printing/public/cpp/manifest.h"
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
|
||||
// TODO(https://crbug.com/781334): Remove these helpers and just update the
|
||||
// manifest definitions to be marked out-of-process. This is here only to avoid
|
||||
// extra churn when transitioning away from content_packaged_services.
|
||||
service_manager::Manifest MakeOutOfProcess(
|
||||
const service_manager::Manifest& manifest) {
|
||||
// cpplint.py emits a false positive [build/include_what_you_use]
|
||||
service_manager::Manifest copy(manifest); // NOLINT
|
||||
copy.options.execution_mode =
|
||||
service_manager::Manifest::ExecutionMode::kOutOfProcessBuiltin;
|
||||
return copy;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
const service_manager::Manifest& GetElectronContentBrowserOverlayManifest() {
|
||||
static base::NoDestructor<service_manager::Manifest> manifest{
|
||||
service_manager::ManifestBuilder()
|
||||
@@ -35,14 +51,14 @@ const service_manager::Manifest& GetElectronContentBrowserOverlayManifest() {
|
||||
}
|
||||
|
||||
const std::vector<service_manager::Manifest>&
|
||||
GetElectronPackagedServicesOverlayManifest() {
|
||||
GetElectronBuiltinServiceManifests() {
|
||||
static base::NoDestructor<std::vector<service_manager::Manifest>> manifests{{
|
||||
proxy_resolver::GetManifest(),
|
||||
MakeOutOfProcess(proxy_resolver::GetManifest()),
|
||||
#if BUILDFLAG(ENABLE_PRINTING)
|
||||
printing::GetPdfCompositorManifest(),
|
||||
MakeOutOfProcess(printing::GetPdfCompositorManifest()),
|
||||
#endif
|
||||
#if BUILDFLAG(ENABLE_PRINT_PREVIEW)
|
||||
GetChromePrintingManifest(),
|
||||
MakeOutOfProcess(GetChromePrintingManifest()),
|
||||
#endif
|
||||
}};
|
||||
return *manifests;
|
||||
|
||||
@@ -11,6 +11,6 @@
|
||||
|
||||
const service_manager::Manifest& GetElectronContentBrowserOverlayManifest();
|
||||
const std::vector<service_manager::Manifest>&
|
||||
GetElectronPackagedServicesOverlayManifest();
|
||||
GetElectronBuiltinServiceManifests();
|
||||
|
||||
#endif // ATOM_APP_MANIFESTS_H_
|
||||
|
||||
@@ -25,6 +25,10 @@
|
||||
#include "gin/v8_initializer.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
#if defined(_WIN64)
|
||||
#include "atom/common/crash_reporter/crash_reporter_win.h"
|
||||
#endif
|
||||
|
||||
namespace atom {
|
||||
|
||||
int NodeMain(int argc, char* argv[]) {
|
||||
@@ -48,10 +52,13 @@ int NodeMain(int argc, char* argv[]) {
|
||||
gin::V8Initializer::LoadV8Natives();
|
||||
|
||||
// V8 requires a task scheduler apparently
|
||||
base::ThreadPool::CreateAndStartWithDefaultParams("Electron");
|
||||
base::ThreadPoolInstance::CreateAndStartWithDefaultParams("Electron");
|
||||
|
||||
// Initialize gin::IsolateHolder.
|
||||
JavascriptEnvironment gin_env(loop);
|
||||
#if defined(_WIN64)
|
||||
crash_reporter::CrashReporterWin::SetUnhandledExceptionFilter();
|
||||
#endif
|
||||
|
||||
// Explicitly register electron's builtin modules.
|
||||
NodeBindings::RegisterBuiltinModules();
|
||||
@@ -116,7 +123,7 @@ int NodeMain(int argc, char* argv[]) {
|
||||
// gin::IsolateHolder waits for tasks running in ThreadPool in its
|
||||
// destructor and thus must be destroyed before ThreadPool starts skipping
|
||||
// CONTINUE_ON_SHUTDOWN tasks.
|
||||
base::ThreadPool::GetInstance()->Shutdown();
|
||||
base::ThreadPoolInstance::Get()->Shutdown();
|
||||
|
||||
v8::V8::Dispose();
|
||||
|
||||
|
||||
@@ -84,6 +84,7 @@ struct Converter<Browser::UserTask> {
|
||||
return false;
|
||||
dict.Get("arguments", &(out->arguments));
|
||||
dict.Get("description", &(out->description));
|
||||
dict.Get("workingDirectory", &(out->working_dir));
|
||||
return true;
|
||||
}
|
||||
};
|
||||
@@ -157,6 +158,7 @@ struct Converter<JumpListItem> {
|
||||
|
||||
dict.Get("args", &(out->arguments));
|
||||
dict.Get("description", &(out->description));
|
||||
dict.Get("workingDirectory", &(out->working_dir));
|
||||
return true;
|
||||
|
||||
case JumpListItem::Type::SEPARATOR:
|
||||
@@ -183,6 +185,7 @@ struct Converter<JumpListItem> {
|
||||
dict.Set("iconPath", val.icon_path);
|
||||
dict.Set("iconIndex", val.icon_index);
|
||||
dict.Set("description", val.description);
|
||||
dict.Set("workingDirectory", val.working_dir);
|
||||
break;
|
||||
|
||||
case JumpListItem::Type::SEPARATOR:
|
||||
@@ -718,7 +721,7 @@ void App::AllowCertificateError(
|
||||
int cert_error,
|
||||
const net::SSLInfo& ssl_info,
|
||||
const GURL& request_url,
|
||||
content::ResourceType resource_type,
|
||||
bool is_main_frame_request,
|
||||
bool strict_enforcement,
|
||||
bool expired_previous_decision,
|
||||
const base::Callback<void(content::CertificateRequestResultType)>&
|
||||
@@ -1268,6 +1271,21 @@ void App::EnableSandbox(mate::Arguments* args) {
|
||||
command_line->AppendSwitch(switches::kEnableSandbox);
|
||||
}
|
||||
|
||||
void App::SetUserAgentFallback(const std::string& user_agent) {
|
||||
AtomBrowserClient::Get()->SetUserAgent(user_agent);
|
||||
}
|
||||
|
||||
std::string App::GetUserAgentFallback() {
|
||||
return AtomBrowserClient::Get()->GetUserAgent();
|
||||
}
|
||||
|
||||
void App::SetBrowserClientCanUseCustomSiteInstance(bool should_disable) {
|
||||
AtomBrowserClient::Get()->SetCanUseCustomSiteInstance(should_disable);
|
||||
}
|
||||
bool App::CanBrowserClientUseCustomSiteInstance() {
|
||||
return AtomBrowserClient::Get()->CanUseCustomSiteInstance();
|
||||
}
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
bool App::MoveToApplicationsFolder(mate::Arguments* args) {
|
||||
return ui::cocoa::AtomBundleMover::Move(args);
|
||||
@@ -1428,7 +1446,12 @@ void App::BuildPrototype(v8::Isolate* isolate,
|
||||
#if defined(OS_MACOSX)
|
||||
.SetProperty("dock", &App::GetDockAPI)
|
||||
#endif
|
||||
.SetMethod("enableSandbox", &App::EnableSandbox);
|
||||
.SetProperty("userAgentFallback", &App::GetUserAgentFallback,
|
||||
&App::SetUserAgentFallback)
|
||||
.SetMethod("enableSandbox", &App::EnableSandbox)
|
||||
.SetProperty("allowRendererProcessReuse",
|
||||
&App::CanBrowserClientUseCustomSiteInstance,
|
||||
&App::SetBrowserClientCanUseCustomSiteInstance);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
@@ -130,7 +130,7 @@ class App : public AtomBrowserClient::Delegate,
|
||||
int cert_error,
|
||||
const net::SSLInfo& ssl_info,
|
||||
const GURL& request_url,
|
||||
content::ResourceType resource_type,
|
||||
bool is_main_frame_request,
|
||||
bool strict_enforcement,
|
||||
bool expired_previous_decision,
|
||||
const base::Callback<void(content::CertificateRequestResultType)>&
|
||||
@@ -210,6 +210,10 @@ class App : public AtomBrowserClient::Delegate,
|
||||
v8::Local<v8::Promise> GetGPUInfo(v8::Isolate* isolate,
|
||||
const std::string& info_type);
|
||||
void EnableSandbox(mate::Arguments* args);
|
||||
void SetUserAgentFallback(const std::string& user_agent);
|
||||
std::string GetUserAgentFallback();
|
||||
void SetBrowserClientCanUseCustomSiteInstance(bool should_disable);
|
||||
bool CanBrowserClientUseCustomSiteInstance();
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
bool MoveToApplicationsFolder(mate::Arguments* args);
|
||||
|
||||
@@ -67,7 +67,7 @@ BrowserWindow::BrowserWindow(v8::Isolate* isolate,
|
||||
}
|
||||
|
||||
web_contents_.Reset(isolate, web_contents.ToV8());
|
||||
api_web_contents_ = web_contents.get();
|
||||
api_web_contents_ = web_contents->GetWeakPtr();
|
||||
api_web_contents_->AddObserver(this);
|
||||
Observe(api_web_contents_->web_contents());
|
||||
|
||||
@@ -94,7 +94,9 @@ BrowserWindow::BrowserWindow(v8::Isolate* isolate,
|
||||
}
|
||||
|
||||
BrowserWindow::~BrowserWindow() {
|
||||
api_web_contents_->RemoveObserver(this);
|
||||
// FIXME This is a hack rather than a proper fix preventing shutdown crashes.
|
||||
if (api_web_contents_)
|
||||
api_web_contents_->RemoveObserver(this);
|
||||
// Note that the OnWindowClosed will not be called after the destructor runs,
|
||||
// since the window object is managed by the TopLevelWindow class.
|
||||
if (web_contents())
|
||||
|
||||
@@ -116,7 +116,7 @@ class BrowserWindow : public TopLevelWindow,
|
||||
#endif
|
||||
|
||||
v8::Global<v8::Value> web_contents_;
|
||||
api::WebContents* api_web_contents_;
|
||||
base::WeakPtr<api::WebContents> api_web_contents_;
|
||||
|
||||
base::WeakPtrFactory<BrowserWindow> weak_factory_;
|
||||
|
||||
|
||||
@@ -291,7 +291,7 @@ void SetCookieOnIO(scoped_refptr<net::URLRequestContextGetter> getter,
|
||||
EXCLUDE_FAILURE_TO_STORE);
|
||||
return;
|
||||
}
|
||||
if (url.is_empty()) {
|
||||
if (!url.is_valid()) {
|
||||
std::move(completion_callback)
|
||||
.Run(net::CanonicalCookie::CookieInclusionStatus::
|
||||
EXCLUDE_INVALID_DOMAIN);
|
||||
|
||||
@@ -61,7 +61,7 @@ struct Converter<in_app_purchase::Product> {
|
||||
dict.Set("formattedPrice", val.formattedPrice);
|
||||
|
||||
// Downloadable Content Information
|
||||
dict.Set("isDownloadable", val.downloadable);
|
||||
dict.Set("isDownloadable", val.isDownloadable);
|
||||
|
||||
return dict.GetHandle();
|
||||
}
|
||||
|
||||
@@ -51,6 +51,19 @@ std::vector<std::string> MetricsToArray(uint32_t metrics) {
|
||||
return array;
|
||||
}
|
||||
|
||||
void DelayEmit(Screen* screen,
|
||||
const base::StringPiece& name,
|
||||
const display::Display& display) {
|
||||
screen->Emit(name, display);
|
||||
}
|
||||
|
||||
void DelayEmitWithMetrics(Screen* screen,
|
||||
const base::StringPiece& name,
|
||||
const display::Display& display,
|
||||
const std::vector<std::string>& metrics) {
|
||||
screen->Emit(name, display, metrics);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
Screen::Screen(v8::Isolate* isolate, display::Screen* screen)
|
||||
@@ -100,16 +113,23 @@ static gfx::Rect DIPToScreenRect(atom::NativeWindow* window,
|
||||
#endif
|
||||
|
||||
void Screen::OnDisplayAdded(const display::Display& new_display) {
|
||||
Emit("display-added", new_display);
|
||||
base::ThreadTaskRunnerHandle::Get()->PostNonNestableTask(
|
||||
FROM_HERE, base::Bind(&DelayEmit, base::Unretained(this), "display-added",
|
||||
new_display));
|
||||
}
|
||||
|
||||
void Screen::OnDisplayRemoved(const display::Display& old_display) {
|
||||
Emit("display-removed", old_display);
|
||||
base::ThreadTaskRunnerHandle::Get()->PostNonNestableTask(
|
||||
FROM_HERE, base::Bind(&DelayEmit, base::Unretained(this),
|
||||
"display-removed", old_display));
|
||||
}
|
||||
|
||||
void Screen::OnDisplayMetricsChanged(const display::Display& display,
|
||||
uint32_t changed_metrics) {
|
||||
Emit("display-metrics-changed", display, MetricsToArray(changed_metrics));
|
||||
base::ThreadTaskRunnerHandle::Get()->PostNonNestableTask(
|
||||
FROM_HERE, base::Bind(&DelayEmitWithMetrics, base::Unretained(this),
|
||||
"display-metrics-changed", display,
|
||||
MetricsToArray(changed_metrics)));
|
||||
}
|
||||
|
||||
// static
|
||||
|
||||
@@ -50,8 +50,6 @@
|
||||
#include "native_mate/object_template_builder.h"
|
||||
#include "net/base/completion_repeating_callback.h"
|
||||
#include "net/base/load_flags.h"
|
||||
#include "net/disk_cache/disk_cache.h"
|
||||
#include "net/dns/host_cache.h" // nogncheck
|
||||
#include "net/http/http_auth_handler_factory.h"
|
||||
#include "net/http/http_auth_preferences.h"
|
||||
#include "net/http/http_cache.h"
|
||||
@@ -210,73 +208,6 @@ const char kPersistPrefix[] = "persist:";
|
||||
// Referenced session objects.
|
||||
std::map<uint32_t, v8::Global<v8::Object>> g_sessions;
|
||||
|
||||
void ResolveOrRejectPromiseInUI(util::Promise promise, int net_error) {
|
||||
if (net_error != net::OK) {
|
||||
std::string err_msg = net::ErrorToString(net_error);
|
||||
util::Promise::RejectPromise(std::move(promise), std::move(err_msg));
|
||||
} else {
|
||||
util::Promise::ResolveEmptyPromise(std::move(promise));
|
||||
}
|
||||
}
|
||||
|
||||
// Callback of HttpCache::GetBackend.
|
||||
void OnGetBackend(disk_cache::Backend** backend_ptr,
|
||||
Session::CacheAction action,
|
||||
const util::CopyablePromise& promise,
|
||||
int result) {
|
||||
if (result != net::OK) {
|
||||
std::string err_msg =
|
||||
"Failed to retrieve cache backend: " + net::ErrorToString(result);
|
||||
util::Promise::RejectPromise(promise.GetPromise(), std::move(err_msg));
|
||||
} else if (backend_ptr && *backend_ptr) {
|
||||
if (action == Session::CacheAction::CLEAR) {
|
||||
auto success =
|
||||
(*backend_ptr)
|
||||
->DoomAllEntries(base::BindOnce(&ResolveOrRejectPromiseInUI,
|
||||
promise.GetPromise()));
|
||||
if (success != net::ERR_IO_PENDING)
|
||||
ResolveOrRejectPromiseInUI(promise.GetPromise(), success);
|
||||
} else if (action == Session::CacheAction::STATS) {
|
||||
base::StringPairs stats;
|
||||
(*backend_ptr)->GetStats(&stats);
|
||||
for (const auto& stat : stats) {
|
||||
if (stat.first == "Current size") {
|
||||
int current_size;
|
||||
base::StringToInt(stat.second, ¤t_size);
|
||||
util::Promise::ResolvePromise<int>(promise.GetPromise(),
|
||||
current_size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DoCacheActionInIO(
|
||||
const scoped_refptr<net::URLRequestContextGetter>& context_getter,
|
||||
Session::CacheAction action,
|
||||
util::Promise promise) {
|
||||
auto* request_context = context_getter->GetURLRequestContext();
|
||||
|
||||
auto* http_cache = request_context->http_transaction_factory()->GetCache();
|
||||
if (!http_cache) {
|
||||
std::string err_msg =
|
||||
"Failed to retrieve cache: " + net::ErrorToString(net::ERR_FAILED);
|
||||
util::Promise::RejectPromise(std::move(promise), std::move(err_msg));
|
||||
return;
|
||||
}
|
||||
|
||||
// Call GetBackend and make the backend's ptr accessable in OnGetBackend.
|
||||
using BackendPtr = disk_cache::Backend*;
|
||||
auto** backend_ptr = new BackendPtr(nullptr);
|
||||
net::CompletionRepeatingCallback on_get_backend =
|
||||
base::Bind(&OnGetBackend, base::Owned(backend_ptr), action,
|
||||
util::CopyablePromise(promise));
|
||||
int rv = http_cache->GetBackend(backend_ptr, on_get_backend);
|
||||
if (rv != net::ERR_IO_PENDING)
|
||||
on_get_backend.Run(net::OK);
|
||||
}
|
||||
|
||||
void SetCertVerifyProcInIO(
|
||||
const scoped_refptr<net::URLRequestContextGetter>& context_getter,
|
||||
const AtomCertVerifier::VerifyProc& proc) {
|
||||
@@ -352,8 +283,8 @@ void DownloadIdCallback(content::DownloadManager* download_manager,
|
||||
uint32_t id) {
|
||||
download_manager->CreateDownloadItem(
|
||||
base::GenerateGUID(), id, path, path, url_chain, GURL(), GURL(), GURL(),
|
||||
GURL(), mime_type, mime_type, start_time, base::Time(), etag,
|
||||
last_modified, offset, length, std::string(),
|
||||
GURL(), base::nullopt, mime_type, mime_type, start_time, base::Time(),
|
||||
etag, last_modified, offset, length, std::string(),
|
||||
download::DownloadItem::INTERRUPTED,
|
||||
download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
|
||||
download::DOWNLOAD_INTERRUPT_REASON_NETWORK_TIMEOUT, false, base::Time(),
|
||||
@@ -438,17 +369,39 @@ v8::Local<v8::Promise> Session::ResolveProxy(mate::Arguments* args) {
|
||||
return handle;
|
||||
}
|
||||
|
||||
template <Session::CacheAction action>
|
||||
v8::Local<v8::Promise> Session::DoCacheAction() {
|
||||
v8::Isolate* isolate = v8::Isolate::GetCurrent();
|
||||
util::Promise promise(isolate);
|
||||
v8::Local<v8::Promise> handle = promise.GetHandle();
|
||||
v8::Local<v8::Promise> Session::GetCacheSize() {
|
||||
auto* isolate = v8::Isolate::GetCurrent();
|
||||
auto promise = util::Promise(isolate);
|
||||
auto handle = promise.GetHandle();
|
||||
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {BrowserThread::IO},
|
||||
base::BindOnce(&DoCacheActionInIO,
|
||||
WrapRefCounted(browser_context_->GetRequestContext()),
|
||||
action, std::move(promise)));
|
||||
content::BrowserContext::GetDefaultStoragePartition(browser_context_.get())
|
||||
->GetNetworkContext()
|
||||
->ComputeHttpCacheSize(base::Time(), base::Time::Max(),
|
||||
base::BindOnce(
|
||||
[](util::Promise promise, bool is_upper_bound,
|
||||
int64_t size_or_error) {
|
||||
if (size_or_error < 0) {
|
||||
promise.RejectWithErrorMessage(
|
||||
net::ErrorToString(size_or_error));
|
||||
} else {
|
||||
promise.Resolve(size_or_error);
|
||||
}
|
||||
},
|
||||
std::move(promise)));
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
v8::Local<v8::Promise> Session::ClearCache() {
|
||||
auto* isolate = v8::Isolate::GetCurrent();
|
||||
auto promise = util::Promise(isolate);
|
||||
auto handle = promise.GetHandle();
|
||||
|
||||
content::BrowserContext::GetDefaultStoragePartition(browser_context_.get())
|
||||
->GetNetworkContext()
|
||||
->ClearHttpCache(base::Time(), base::Time::Max(), nullptr,
|
||||
base::BindOnce(util::Promise::ResolveEmptyPromise,
|
||||
std::move(promise)));
|
||||
|
||||
return handle;
|
||||
}
|
||||
@@ -581,14 +534,33 @@ void Session::SetCertVerifyProc(v8::Local<v8::Value> val,
|
||||
|
||||
void Session::SetPermissionRequestHandler(v8::Local<v8::Value> val,
|
||||
mate::Arguments* args) {
|
||||
AtomPermissionManager::RequestHandler handler;
|
||||
if (!(val->IsNull() || mate::ConvertFromV8(args->isolate(), val, &handler))) {
|
||||
auto* permission_manager = static_cast<AtomPermissionManager*>(
|
||||
browser_context()->GetPermissionControllerDelegate());
|
||||
if (val->IsNull()) {
|
||||
permission_manager->SetPermissionRequestHandler(
|
||||
AtomPermissionManager::RequestHandler());
|
||||
return;
|
||||
}
|
||||
using StatusCallback =
|
||||
base::RepeatingCallback<void(blink::mojom::PermissionStatus)>;
|
||||
using RequestHandler =
|
||||
base::Callback<void(content::WebContents*, content::PermissionType,
|
||||
StatusCallback, const base::Value&)>;
|
||||
auto handler = std::make_unique<RequestHandler>();
|
||||
if (!mate::ConvertFromV8(args->isolate(), val, handler.get())) {
|
||||
args->ThrowError("Must pass null or function");
|
||||
return;
|
||||
}
|
||||
auto* permission_manager = static_cast<AtomPermissionManager*>(
|
||||
browser_context()->GetPermissionControllerDelegate());
|
||||
permission_manager->SetPermissionRequestHandler(handler);
|
||||
permission_manager->SetPermissionRequestHandler(base::BindRepeating(
|
||||
[](RequestHandler* handler, content::WebContents* web_contents,
|
||||
content::PermissionType permission_type,
|
||||
AtomPermissionManager::StatusCallback callback,
|
||||
const base::Value& details) {
|
||||
handler->Run(web_contents, permission_type,
|
||||
base::AdaptCallbackForRepeating(std::move(callback)),
|
||||
details);
|
||||
},
|
||||
base::Owned(std::move(handler))));
|
||||
}
|
||||
|
||||
void Session::SetPermissionCheckHandler(v8::Local<v8::Value> val,
|
||||
@@ -793,8 +765,8 @@ void Session::BuildPrototype(v8::Isolate* isolate,
|
||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
.MakeDestroyable()
|
||||
.SetMethod("resolveProxy", &Session::ResolveProxy)
|
||||
.SetMethod("getCacheSize", &Session::DoCacheAction<CacheAction::STATS>)
|
||||
.SetMethod("clearCache", &Session::DoCacheAction<CacheAction::CLEAR>)
|
||||
.SetMethod("getCacheSize", &Session::GetCacheSize)
|
||||
.SetMethod("clearCache", &Session::ClearCache)
|
||||
.SetMethod("clearStorageData", &Session::ClearStorageData)
|
||||
.SetMethod("flushStorageData", &Session::FlushStorageData)
|
||||
.SetMethod("setProxy", &Session::SetProxy)
|
||||
|
||||
@@ -63,8 +63,8 @@ class Session : public mate::TrackableObject<Session>,
|
||||
|
||||
// Methods.
|
||||
v8::Local<v8::Promise> ResolveProxy(mate::Arguments* args);
|
||||
template <CacheAction action>
|
||||
v8::Local<v8::Promise> DoCacheAction();
|
||||
v8::Local<v8::Promise> GetCacheSize();
|
||||
v8::Local<v8::Promise> ClearCache();
|
||||
v8::Local<v8::Promise> ClearStorageData(mate::Arguments* args);
|
||||
void FlushStorageData();
|
||||
v8::Local<v8::Promise> SetProxy(mate::Arguments* args);
|
||||
|
||||
@@ -62,11 +62,11 @@ struct Converter<NSAppearance*> {
|
||||
return v8::Null(isolate);
|
||||
}
|
||||
|
||||
if (val.name == NSAppearanceNameAqua) {
|
||||
if ([val.name isEqualToString:NSAppearanceNameAqua]) {
|
||||
return mate::ConvertToV8(isolate, "light");
|
||||
}
|
||||
if (@available(macOS 10.14, *)) {
|
||||
if (val.name == NSAppearanceNameDarkAqua) {
|
||||
if ([val.name isEqualToString:NSAppearanceNameDarkAqua]) {
|
||||
return mate::ConvertToV8(isolate, "dark");
|
||||
}
|
||||
}
|
||||
@@ -625,6 +625,10 @@ void SystemPreferences::RemoveUserDefault(const std::string& name) {
|
||||
}
|
||||
|
||||
bool SystemPreferences::IsDarkMode() {
|
||||
if (@available(macOS 10.15, *)) {
|
||||
return [[NSApplication sharedApplication].effectiveAppearance.name
|
||||
isEqualToString:NSAppearanceNameDarkAqua];
|
||||
}
|
||||
NSString* mode = [[NSUserDefaults standardUserDefaults]
|
||||
stringForKey:@"AppleInterfaceStyle"];
|
||||
return [mode isEqualToString:@"Dark"];
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#include "atom/common/options_switches.h"
|
||||
#include "base/message_loop/message_loop.h"
|
||||
#include "base/no_destructor.h"
|
||||
#include "base/optional.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "base/threading/thread_restrictions.h"
|
||||
#include "base/threading/thread_task_runner_handle.h"
|
||||
@@ -267,7 +268,9 @@ struct WebContents::FrameDispatchHelper {
|
||||
|
||||
WebContents::WebContents(v8::Isolate* isolate,
|
||||
content::WebContents* web_contents)
|
||||
: content::WebContentsObserver(web_contents), type_(REMOTE) {
|
||||
: content::WebContentsObserver(web_contents),
|
||||
type_(REMOTE),
|
||||
weak_factory_(this) {
|
||||
web_contents->SetUserAgentOverride(GetBrowserContext()->GetUserAgent(),
|
||||
false);
|
||||
Init(isolate);
|
||||
@@ -282,7 +285,9 @@ WebContents::WebContents(v8::Isolate* isolate,
|
||||
WebContents::WebContents(v8::Isolate* isolate,
|
||||
std::unique_ptr<content::WebContents> web_contents,
|
||||
Type type)
|
||||
: content::WebContentsObserver(web_contents.get()), type_(type) {
|
||||
: content::WebContentsObserver(web_contents.get()),
|
||||
type_(type),
|
||||
weak_factory_(this) {
|
||||
DCHECK(type != REMOTE) << "Can't take ownership of a remote WebContents";
|
||||
auto session = Session::CreateFrom(isolate, GetBrowserContext());
|
||||
session_.Reset(isolate, session.ToV8());
|
||||
@@ -290,8 +295,8 @@ WebContents::WebContents(v8::Isolate* isolate,
|
||||
mate::Dictionary::CreateEmpty(isolate));
|
||||
}
|
||||
|
||||
WebContents::WebContents(v8::Isolate* isolate,
|
||||
const mate::Dictionary& options) {
|
||||
WebContents::WebContents(v8::Isolate* isolate, const mate::Dictionary& options)
|
||||
: weak_factory_(this) {
|
||||
// Read options.
|
||||
options.Get("backgroundThrottling", &background_throttling_);
|
||||
|
||||
@@ -836,6 +841,10 @@ void WebContents::OnInterfaceRequestFromFrame(
|
||||
registry_.TryBindInterface(interface_name, interface_pipe, render_frame_host);
|
||||
}
|
||||
|
||||
void WebContents::DidAcquireFullscreen(content::RenderFrameHost* rfh) {
|
||||
set_fullscreen_frame(rfh);
|
||||
}
|
||||
|
||||
void WebContents::DocumentLoadedInFrame(
|
||||
content::RenderFrameHost* render_frame_host) {
|
||||
if (!render_frame_host->GetParent())
|
||||
@@ -1214,7 +1223,7 @@ void WebContents::SetBackgroundThrottling(bool allowed) {
|
||||
render_widget_host_impl->disable_hidden_ = !background_throttling_;
|
||||
|
||||
if (render_widget_host_impl->is_hidden()) {
|
||||
render_widget_host_impl->WasShown(false);
|
||||
render_widget_host_impl->WasShown(base::nullopt);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2070,7 +2079,7 @@ v8::Local<v8::Value> WebContents::GetLastWebPreferences(
|
||||
}
|
||||
|
||||
bool WebContents::IsRemoteModuleEnabled() const {
|
||||
if (web_contents()->GetVisibleURL().SchemeIs("chrome-devtools")) {
|
||||
if (web_contents()->GetVisibleURL().SchemeIs("devtools")) {
|
||||
return false;
|
||||
}
|
||||
if (auto* web_preferences = WebContentsPreferences::From(web_contents())) {
|
||||
|
||||
@@ -116,6 +116,8 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype);
|
||||
|
||||
base::WeakPtr<WebContents> GetWeakPtr() { return weak_factory_.GetWeakPtr(); }
|
||||
|
||||
// Destroy the managed content::WebContents instance.
|
||||
//
|
||||
// Note: The |async| should only be |true| when users are expecting to use the
|
||||
@@ -455,6 +457,7 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
content::RenderFrameHost* render_frame_host,
|
||||
const std::string& interface_name,
|
||||
mojo::ScopedMessagePipeHandle* interface_pipe) override;
|
||||
void DidAcquireFullscreen(content::RenderFrameHost* rfh) override;
|
||||
|
||||
// InspectableWebContentsDelegate:
|
||||
void DevToolsReloadPage() override;
|
||||
@@ -558,6 +561,8 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
std::map<content::RenderFrameHost*, std::vector<mojo::BindingId>>
|
||||
frame_to_bindings_map_;
|
||||
|
||||
base::WeakPtrFactory<WebContents> weak_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(WebContents);
|
||||
};
|
||||
|
||||
|
||||
@@ -108,18 +108,6 @@ void GPUInfoEnumerator::EndAuxAttributes() {
|
||||
value_stack.pop();
|
||||
}
|
||||
|
||||
void GPUInfoEnumerator::BeginOverlayCapability() {
|
||||
value_stack.push(std::move(current));
|
||||
current = std::make_unique<base::DictionaryValue>();
|
||||
}
|
||||
|
||||
void GPUInfoEnumerator::EndOverlayCapability() {
|
||||
auto& top_value = value_stack.top();
|
||||
top_value->SetDictionary(kOverlayCapabilityKey, std::move(current));
|
||||
current = std::move(top_value);
|
||||
value_stack.pop();
|
||||
}
|
||||
|
||||
void GPUInfoEnumerator::BeginDx12VulkanVersionInfo() {
|
||||
value_stack.push(std::move(current));
|
||||
current = std::make_unique<base::DictionaryValue>();
|
||||
|
||||
@@ -25,7 +25,6 @@ class GPUInfoEnumerator final : public gpu::GPUInfo::Enumerator {
|
||||
const char* kImageDecodeAcceleratorSupportedProfileKey =
|
||||
"imageDecodeAcceleratorSupportedProfile";
|
||||
const char* kAuxAttributesKey = "auxAttributes";
|
||||
const char* kOverlayCapabilityKey = "overlayCapability";
|
||||
const char* kDx12VulkanVersionInfoKey = "dx12VulkanVersionInfo";
|
||||
|
||||
public:
|
||||
@@ -47,8 +46,6 @@ class GPUInfoEnumerator final : public gpu::GPUInfo::Enumerator {
|
||||
void EndImageDecodeAcceleratorSupportedProfile() override;
|
||||
void BeginAuxAttributes() override;
|
||||
void EndAuxAttributes() override;
|
||||
void BeginOverlayCapability() override;
|
||||
void EndOverlayCapability() override;
|
||||
void BeginDx12VulkanVersionInfo() override;
|
||||
void EndDx12VulkanVersionInfo() override;
|
||||
std::unique_ptr<base::DictionaryValue> GetDictionary();
|
||||
|
||||
@@ -76,11 +76,14 @@
|
||||
#include "services/device/public/cpp/geolocation/location_provider.h"
|
||||
#include "services/network/public/cpp/features.h"
|
||||
#include "services/network/public/cpp/resource_request_body.h"
|
||||
#include "services/proxy_resolver/public/mojom/proxy_resolver.mojom.h"
|
||||
#include "ui/base/l10n/l10n_util.h"
|
||||
#include "ui/base/resource/resource_bundle.h"
|
||||
#include "v8/include/v8.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include "sandbox/win/src/sandbox_policy.h"
|
||||
#endif
|
||||
|
||||
#if defined(USE_NSS_CERTS)
|
||||
#include "net/ssl/client_cert_store_nss.h"
|
||||
#elif defined(OS_WIN)
|
||||
@@ -108,8 +111,6 @@
|
||||
|
||||
#if BUILDFLAG(ENABLE_PRINTING)
|
||||
#include "chrome/browser/printing/printing_message_filter.h"
|
||||
#include "chrome/services/printing/public/mojom/constants.mojom.h"
|
||||
#include "components/services/pdf_compositor/public/interfaces/pdf_compositor.mojom.h"
|
||||
#endif // BUILDFLAG(ENABLE_PRINTING)
|
||||
|
||||
using content::BrowserThread;
|
||||
@@ -400,6 +401,14 @@ void AtomBrowserClient::OverrideWebkitPrefs(content::RenderViewHost* host,
|
||||
web_preferences->OverrideWebkitPrefs(prefs);
|
||||
}
|
||||
|
||||
void AtomBrowserClient::SetCanUseCustomSiteInstance(bool should_disable) {
|
||||
disable_process_restart_tricks_ = should_disable;
|
||||
}
|
||||
|
||||
bool AtomBrowserClient::CanUseCustomSiteInstance() {
|
||||
return disable_process_restart_tricks_;
|
||||
}
|
||||
|
||||
content::ContentBrowserClient::SiteInstanceForNavigationType
|
||||
AtomBrowserClient::ShouldOverrideSiteInstanceForNavigation(
|
||||
content::RenderFrameHost* current_rfh,
|
||||
@@ -498,7 +507,7 @@ void AtomBrowserClient::AppendExtraCommandLineSwitches(
|
||||
|
||||
content::WebContents* web_contents = GetWebContentsFromProcessID(process_id);
|
||||
if (web_contents) {
|
||||
if (web_contents->GetVisibleURL().SchemeIs("chrome-devtools")) {
|
||||
if (web_contents->GetVisibleURL().SchemeIs("devtools")) {
|
||||
command_line->AppendSwitch(switches::kDisableRemoteModule);
|
||||
}
|
||||
auto* web_preferences = WebContentsPreferences::From(web_contents);
|
||||
@@ -506,6 +515,10 @@ void AtomBrowserClient::AppendExtraCommandLineSwitches(
|
||||
web_preferences->AppendCommandLineSwitches(command_line);
|
||||
SessionPreferences::AppendExtraCommandLineSwitches(
|
||||
web_contents->GetBrowserContext(), command_line);
|
||||
if (CanUseCustomSiteInstance()) {
|
||||
command_line->AppendSwitch(
|
||||
switches::kDisableElectronSiteInstanceOverrides);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -555,14 +568,14 @@ void AtomBrowserClient::AllowCertificateError(
|
||||
int cert_error,
|
||||
const net::SSLInfo& ssl_info,
|
||||
const GURL& request_url,
|
||||
content::ResourceType resource_type,
|
||||
bool is_main_frame_request,
|
||||
bool strict_enforcement,
|
||||
bool expired_previous_decision,
|
||||
const base::Callback<void(content::CertificateRequestResultType)>&
|
||||
callback) {
|
||||
if (delegate_) {
|
||||
delegate_->AllowCertificateError(
|
||||
web_contents, cert_error, ssl_info, request_url, resource_type,
|
||||
web_contents, cert_error, ssl_info, request_url, is_main_frame_request,
|
||||
strict_enforcement, expired_previous_decision, callback);
|
||||
}
|
||||
}
|
||||
@@ -606,11 +619,6 @@ bool AtomBrowserClient::CanCreateWindow(
|
||||
|
||||
int opener_render_process_id = opener->GetProcess()->GetID();
|
||||
|
||||
if (IsRendererSandboxed(opener_render_process_id)) {
|
||||
*no_javascript_access = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (RendererUsesNativeWindowOpen(opener_render_process_id)) {
|
||||
if (RendererDisablesPopups(opener_render_process_id)) {
|
||||
// <webview> without allowpopups attribute should return
|
||||
@@ -705,43 +713,26 @@ network::mojom::NetworkContext* AtomBrowserClient::GetSystemNetworkContext() {
|
||||
return g_browser_process->system_network_context_manager()->GetContext();
|
||||
}
|
||||
|
||||
void AtomBrowserClient::RegisterOutOfProcessServices(
|
||||
OutOfProcessServiceMap* services) {
|
||||
(*services)[proxy_resolver::mojom::kProxyResolverServiceName] =
|
||||
base::BindRepeating(&l10n_util::GetStringUTF16,
|
||||
IDS_UTILITY_PROCESS_PROXY_RESOLVER_NAME);
|
||||
|
||||
#if BUILDFLAG(ENABLE_PRINTING)
|
||||
(*services)[printing::mojom::kServiceName] =
|
||||
base::BindRepeating(&l10n_util::GetStringUTF16,
|
||||
IDS_UTILITY_PROCESS_PDF_COMPOSITOR_SERVICE_NAME);
|
||||
|
||||
(*services)[printing::mojom::kChromePrintingServiceName] =
|
||||
base::BindRepeating(&l10n_util::GetStringUTF16,
|
||||
IDS_UTILITY_PROCESS_PRINTING_SERVICE_NAME);
|
||||
#endif
|
||||
}
|
||||
|
||||
base::Optional<service_manager::Manifest>
|
||||
AtomBrowserClient::GetServiceManifestOverlay(base::StringPiece name) {
|
||||
if (name == content::mojom::kBrowserServiceName) {
|
||||
if (name == content::mojom::kBrowserServiceName)
|
||||
return GetElectronContentBrowserOverlayManifest();
|
||||
} else if (name == content::mojom::kPackagedServicesServiceName) {
|
||||
service_manager::Manifest overlay;
|
||||
overlay.packaged_services = GetElectronPackagedServicesOverlayManifest();
|
||||
return overlay;
|
||||
}
|
||||
|
||||
return base::nullopt;
|
||||
}
|
||||
|
||||
std::vector<service_manager::Manifest>
|
||||
AtomBrowserClient::GetExtraServiceManifests() {
|
||||
return GetElectronBuiltinServiceManifests();
|
||||
}
|
||||
|
||||
net::NetLog* AtomBrowserClient::GetNetLog() {
|
||||
return g_browser_process->net_log();
|
||||
}
|
||||
|
||||
content::BrowserMainParts* AtomBrowserClient::CreateBrowserMainParts(
|
||||
std::unique_ptr<content::BrowserMainParts>
|
||||
AtomBrowserClient::CreateBrowserMainParts(
|
||||
const content::MainFunctionParams& params) {
|
||||
return new AtomBrowserMainParts(params);
|
||||
return std::make_unique<AtomBrowserMainParts>(params);
|
||||
}
|
||||
|
||||
void AtomBrowserClient::WebNotificationAllowed(
|
||||
@@ -829,8 +820,6 @@ bool AtomBrowserClient::HandleExternalProtocol(
|
||||
bool is_main_frame,
|
||||
ui::PageTransition page_transition,
|
||||
bool has_user_gesture,
|
||||
const std::string& method,
|
||||
const net::HttpRequestHeaders& headers,
|
||||
network::mojom::URLLoaderFactoryRequest* factory_request,
|
||||
// clang-format off
|
||||
network::mojom::URLLoaderFactory*& out_factory) { // NOLINT
|
||||
@@ -913,9 +902,27 @@ std::string AtomBrowserClient::GetProduct() const {
|
||||
}
|
||||
|
||||
std::string AtomBrowserClient::GetUserAgent() const {
|
||||
return GetApplicationUserAgent();
|
||||
if (user_agent_override_.empty())
|
||||
return GetApplicationUserAgent();
|
||||
return user_agent_override_;
|
||||
}
|
||||
|
||||
void AtomBrowserClient::SetUserAgent(const std::string& user_agent) {
|
||||
user_agent_override_ = user_agent;
|
||||
}
|
||||
|
||||
#if defined(OS_WIN)
|
||||
bool AtomBrowserClient::PreSpawnRenderer(sandbox::TargetPolicy* policy) {
|
||||
// Allow crashpad to communicate via named pipe.
|
||||
sandbox::ResultCode result = policy->AddRule(
|
||||
sandbox::TargetPolicy::SUBSYS_FILES,
|
||||
sandbox::TargetPolicy::FILES_ALLOW_ANY, L"\\??\\pipe\\crashpad_*");
|
||||
if (result != sandbox::SBOX_ALL_OK)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
#endif // defined(OS_WIN)
|
||||
|
||||
std::string AtomBrowserClient::GetApplicationLocale() {
|
||||
if (BrowserThread::CurrentlyOn(BrowserThread::IO))
|
||||
return g_io_thread_application_locale.Get();
|
||||
|
||||
@@ -64,6 +64,12 @@ class AtomBrowserClient : public content::ContentBrowserClient,
|
||||
// content::ContentBrowserClient:
|
||||
bool ShouldEnableStrictSiteIsolation() override;
|
||||
|
||||
std::string GetUserAgent() const override;
|
||||
void SetUserAgent(const std::string& user_agent);
|
||||
|
||||
void SetCanUseCustomSiteInstance(bool should_disable);
|
||||
bool CanUseCustomSiteInstance() override;
|
||||
|
||||
protected:
|
||||
void RenderProcessWillLaunch(
|
||||
content::RenderProcessHost* host,
|
||||
@@ -99,7 +105,7 @@ class AtomBrowserClient : public content::ContentBrowserClient,
|
||||
int cert_error,
|
||||
const net::SSLInfo& ssl_info,
|
||||
const GURL& request_url,
|
||||
content::ResourceType resource_type,
|
||||
bool is_main_frame_request,
|
||||
bool strict_enforcement,
|
||||
bool expired_previous_decision,
|
||||
const base::Callback<void(content::CertificateRequestResultType)>&
|
||||
@@ -139,15 +145,15 @@ class AtomBrowserClient : public content::ContentBrowserClient,
|
||||
bool in_memory,
|
||||
const base::FilePath& relative_partition_path) override;
|
||||
network::mojom::NetworkContext* GetSystemNetworkContext() override;
|
||||
void RegisterOutOfProcessServices(OutOfProcessServiceMap* services) override;
|
||||
base::Optional<service_manager::Manifest> GetServiceManifestOverlay(
|
||||
base::StringPiece name) override;
|
||||
std::vector<service_manager::Manifest> GetExtraServiceManifests() override;
|
||||
net::NetLog* GetNetLog() override;
|
||||
content::MediaObserver* GetMediaObserver() override;
|
||||
content::DevToolsManagerDelegate* GetDevToolsManagerDelegate() override;
|
||||
content::PlatformNotificationService* GetPlatformNotificationService(
|
||||
content::BrowserContext* browser_context) override;
|
||||
content::BrowserMainParts* CreateBrowserMainParts(
|
||||
std::unique_ptr<content::BrowserMainParts> CreateBrowserMainParts(
|
||||
const content::MainFunctionParams&) override;
|
||||
base::FilePath GetDefaultDownloadDirectory() override;
|
||||
scoped_refptr<network::SharedURLLoaderFactory>
|
||||
@@ -156,7 +162,9 @@ class AtomBrowserClient : public content::ContentBrowserClient,
|
||||
network::mojom::NetworkService* network_service) override;
|
||||
bool ShouldBypassCORB(int render_process_id) const override;
|
||||
std::string GetProduct() const override;
|
||||
std::string GetUserAgent() const override;
|
||||
#if defined(OS_WIN)
|
||||
bool PreSpawnRenderer(sandbox::TargetPolicy* policy) override;
|
||||
#endif
|
||||
|
||||
// content::RenderProcessHostObserver:
|
||||
void RenderProcessHostDestroyed(content::RenderProcessHost* host) override;
|
||||
@@ -172,8 +180,6 @@ class AtomBrowserClient : public content::ContentBrowserClient,
|
||||
bool is_main_frame,
|
||||
ui::PageTransition page_transition,
|
||||
bool has_user_gesture,
|
||||
const std::string& method,
|
||||
const net::HttpRequestHeaders& headers,
|
||||
network::mojom::URLLoaderFactoryRequest* factory_request,
|
||||
// clang-format off
|
||||
network::mojom::URLLoaderFactory*& out_factory) // NOLINT
|
||||
@@ -232,6 +238,10 @@ class AtomBrowserClient : public content::ContentBrowserClient,
|
||||
mutable base::Lock process_preferences_lock_;
|
||||
std::map<int, ProcessPreferences> process_preferences_;
|
||||
|
||||
std::string user_agent_override_ = "";
|
||||
|
||||
bool disable_process_restart_tricks_ = false;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomBrowserClient);
|
||||
};
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <utility>
|
||||
|
||||
#include "atom/browser/atom_blob_reader.h"
|
||||
#include "atom/browser/atom_browser_client.h"
|
||||
#include "atom/browser/atom_browser_main_parts.h"
|
||||
#include "atom/browser/atom_download_manager_delegate.h"
|
||||
#include "atom/browser/atom_paths.h"
|
||||
@@ -67,7 +68,7 @@ AtomBrowserContext::AtomBrowserContext(const std::string& partition,
|
||||
storage_policy_(new SpecialStoragePolicy),
|
||||
in_memory_(in_memory),
|
||||
weak_factory_(this) {
|
||||
user_agent_ = GetApplicationUserAgent();
|
||||
user_agent_ = AtomBrowserClient::Get()->GetUserAgent();
|
||||
|
||||
// Read options.
|
||||
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
|
||||
@@ -109,11 +110,12 @@ AtomBrowserContext::~AtomBrowserContext() {
|
||||
NotifyWillBeDestroyed(this);
|
||||
ShutdownStoragePartitions();
|
||||
|
||||
BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE,
|
||||
std::move(resource_context_));
|
||||
|
||||
if (!base::FeatureList::IsEnabled(network::features::kNetworkService))
|
||||
if (!base::FeatureList::IsEnabled(network::features::kNetworkService)) {
|
||||
io_handle_->ShutdownOnUIThread();
|
||||
} else {
|
||||
BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE,
|
||||
std::move(resource_context_));
|
||||
}
|
||||
|
||||
// Notify any keyed services of browser context destruction.
|
||||
BrowserContextDependencyManager::GetInstance()->DestroyBrowserContextServices(
|
||||
|
||||
@@ -127,8 +127,8 @@ void AtomDownloadManagerDelegate::OnDownloadPathGenerated(
|
||||
base::Bind(&AtomDownloadManagerDelegate::OnDownloadSaveDialogDone,
|
||||
base::Unretained(this), download_id, callback);
|
||||
|
||||
file_dialog::ShowSaveDialog(settings, std::move(dialog_promise));
|
||||
ignore_result(dialog_promise.Then(dialog_callback));
|
||||
file_dialog::ShowSaveDialog(settings, std::move(dialog_promise));
|
||||
} else {
|
||||
callback.Run(path, download::DownloadItem::TARGET_DISPOSITION_PROMPT,
|
||||
download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, path,
|
||||
@@ -136,54 +136,48 @@ void AtomDownloadManagerDelegate::OnDownloadPathGenerated(
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(MAS_BUILD)
|
||||
void AtomDownloadManagerDelegate::OnDownloadSaveDialogDone(
|
||||
uint32_t download_id,
|
||||
const content::DownloadTargetCallback& download_callback,
|
||||
bool result,
|
||||
const base::FilePath& path,
|
||||
const std::string& bookmark)
|
||||
#else
|
||||
void AtomDownloadManagerDelegate::OnDownloadSaveDialogDone(
|
||||
uint32_t download_id,
|
||||
const content::DownloadTargetCallback& download_callback,
|
||||
bool result,
|
||||
const base::FilePath& path)
|
||||
#endif
|
||||
{
|
||||
mate::Dictionary result) {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
|
||||
auto* item = download_manager_->GetDownload(download_id);
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
if (result) {
|
||||
// Remember the last selected download directory.
|
||||
AtomBrowserContext* browser_context = static_cast<AtomBrowserContext*>(
|
||||
download_manager_->GetBrowserContext());
|
||||
browser_context->prefs()->SetFilePath(prefs::kDownloadDefaultDirectory,
|
||||
path.DirName());
|
||||
bool canceled = true;
|
||||
result.Get("canceled", &canceled);
|
||||
|
||||
v8::Isolate* isolate = v8::Isolate::GetCurrent();
|
||||
v8::Locker locker(isolate);
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
api::DownloadItem* download_item =
|
||||
api::DownloadItem::FromWrappedClass(isolate, item);
|
||||
if (download_item)
|
||||
download_item->SetSavePath(path);
|
||||
base::FilePath path;
|
||||
|
||||
if (!canceled) {
|
||||
if (result.Get("filePath", &path)) {
|
||||
// Remember the last selected download directory.
|
||||
AtomBrowserContext* browser_context = static_cast<AtomBrowserContext*>(
|
||||
download_manager_->GetBrowserContext());
|
||||
browser_context->prefs()->SetFilePath(prefs::kDownloadDefaultDirectory,
|
||||
path.DirName());
|
||||
|
||||
v8::Isolate* isolate = v8::Isolate::GetCurrent();
|
||||
v8::Locker locker(isolate);
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
api::DownloadItem* download_item =
|
||||
api::DownloadItem::FromWrappedClass(isolate, item);
|
||||
if (download_item)
|
||||
download_item->SetSavePath(path);
|
||||
}
|
||||
}
|
||||
|
||||
// Running the DownloadTargetCallback with an empty FilePath signals that the
|
||||
// download should be cancelled. If user cancels the file save dialog, run
|
||||
// the callback with empty FilePath.
|
||||
const base::FilePath download_path = result ? path : base::FilePath();
|
||||
const auto interrupt_reason =
|
||||
download_path.empty() ? download::DOWNLOAD_INTERRUPT_REASON_USER_CANCELED
|
||||
: download::DOWNLOAD_INTERRUPT_REASON_NONE;
|
||||
download_callback.Run(download_path,
|
||||
download::DownloadItem::TARGET_DISPOSITION_PROMPT,
|
||||
download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
|
||||
download_path, interrupt_reason);
|
||||
path.empty() ? download::DOWNLOAD_INTERRUPT_REASON_USER_CANCELED
|
||||
: download::DOWNLOAD_INTERRUPT_REASON_NONE;
|
||||
download_callback.Run(path, download::DownloadItem::TARGET_DISPOSITION_PROMPT,
|
||||
download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, path,
|
||||
interrupt_reason);
|
||||
}
|
||||
|
||||
void AtomDownloadManagerDelegate::Shutdown() {
|
||||
|
||||
@@ -45,20 +45,10 @@ class AtomDownloadManagerDelegate : public content::DownloadManagerDelegate {
|
||||
const content::DownloadTargetCallback& callback,
|
||||
const base::FilePath& default_path);
|
||||
|
||||
#if defined(MAS_BUILD)
|
||||
void OnDownloadSaveDialogDone(
|
||||
uint32_t download_id,
|
||||
const content::DownloadTargetCallback& download_callback,
|
||||
bool result,
|
||||
const base::FilePath& path,
|
||||
const std::string& bookmark);
|
||||
#else
|
||||
void OnDownloadSaveDialogDone(
|
||||
uint32_t download_id,
|
||||
const content::DownloadTargetCallback& download_callback,
|
||||
bool result,
|
||||
const base::FilePath& path);
|
||||
#endif
|
||||
mate::Dictionary result);
|
||||
|
||||
content::DownloadManager* download_manager_;
|
||||
base::WeakPtrFactory<AtomDownloadManagerDelegate> weak_ptr_factory_;
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "atom/browser/atom_permission_manager.h"
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/browser/atom_browser_client.h"
|
||||
@@ -32,9 +33,9 @@ bool WebContentsDestroyed(int process_id) {
|
||||
}
|
||||
|
||||
void PermissionRequestResponseCallbackWrapper(
|
||||
const AtomPermissionManager::StatusCallback& callback,
|
||||
AtomPermissionManager::StatusCallback callback,
|
||||
const std::vector<blink::mojom::PermissionStatus>& vector) {
|
||||
callback.Run(vector[0]);
|
||||
std::move(callback).Run(vector[0]);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@@ -43,9 +44,9 @@ class AtomPermissionManager::PendingRequest {
|
||||
public:
|
||||
PendingRequest(content::RenderFrameHost* render_frame_host,
|
||||
const std::vector<content::PermissionType>& permissions,
|
||||
const StatusesCallback& callback)
|
||||
StatusesCallback callback)
|
||||
: render_process_id_(render_frame_host->GetProcess()->GetID()),
|
||||
callback_(callback),
|
||||
callback_(std::move(callback)),
|
||||
permissions_(permissions),
|
||||
results_(permissions.size(), blink::mojom::PermissionStatus::DENIED),
|
||||
remaining_results_(permissions.size()) {}
|
||||
@@ -74,11 +75,15 @@ class AtomPermissionManager::PendingRequest {
|
||||
|
||||
bool IsComplete() const { return remaining_results_ == 0; }
|
||||
|
||||
void RunCallback() const { callback_.Run(results_); }
|
||||
void RunCallback() {
|
||||
if (!callback_.is_null()) {
|
||||
std::move(callback_).Run(results_);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
int render_process_id_;
|
||||
const StatusesCallback callback_;
|
||||
StatusesCallback callback_;
|
||||
std::vector<content::PermissionType> permissions_;
|
||||
std::vector<blink::mojom::PermissionStatus> results_;
|
||||
size_t remaining_results_;
|
||||
@@ -91,8 +96,8 @@ AtomPermissionManager::~AtomPermissionManager() {}
|
||||
void AtomPermissionManager::SetPermissionRequestHandler(
|
||||
const RequestHandler& handler) {
|
||||
if (handler.is_null() && !pending_requests_.IsEmpty()) {
|
||||
for (PendingRequestsMap::const_iterator iter(&pending_requests_);
|
||||
!iter.IsAtEnd(); iter.Advance()) {
|
||||
for (PendingRequestsMap::iterator iter(&pending_requests_); !iter.IsAtEnd();
|
||||
iter.Advance()) {
|
||||
auto* request = iter.GetCurrentValue();
|
||||
if (!WebContentsDestroyed(request->render_process_id()))
|
||||
request->RunCallback();
|
||||
@@ -112,11 +117,10 @@ int AtomPermissionManager::RequestPermission(
|
||||
content::RenderFrameHost* render_frame_host,
|
||||
const GURL& requesting_origin,
|
||||
bool user_gesture,
|
||||
const base::Callback<void(blink::mojom::PermissionStatus)>&
|
||||
response_callback) {
|
||||
StatusCallback response_callback) {
|
||||
return RequestPermissionWithDetails(permission, render_frame_host,
|
||||
requesting_origin, user_gesture, nullptr,
|
||||
response_callback);
|
||||
std::move(response_callback));
|
||||
}
|
||||
|
||||
int AtomPermissionManager::RequestPermissionWithDetails(
|
||||
@@ -125,11 +129,12 @@ int AtomPermissionManager::RequestPermissionWithDetails(
|
||||
const GURL& requesting_origin,
|
||||
bool user_gesture,
|
||||
const base::DictionaryValue* details,
|
||||
const StatusCallback& response_callback) {
|
||||
StatusCallback response_callback) {
|
||||
return RequestPermissionsWithDetails(
|
||||
std::vector<content::PermissionType>(1, permission), render_frame_host,
|
||||
requesting_origin, user_gesture, details,
|
||||
base::Bind(&PermissionRequestResponseCallbackWrapper, response_callback));
|
||||
base::BindOnce(PermissionRequestResponseCallbackWrapper,
|
||||
std::move(response_callback)));
|
||||
}
|
||||
|
||||
int AtomPermissionManager::RequestPermissions(
|
||||
@@ -137,10 +142,10 @@ int AtomPermissionManager::RequestPermissions(
|
||||
content::RenderFrameHost* render_frame_host,
|
||||
const GURL& requesting_origin,
|
||||
bool user_gesture,
|
||||
const StatusesCallback& response_callback) {
|
||||
StatusesCallback response_callback) {
|
||||
return RequestPermissionsWithDetails(permissions, render_frame_host,
|
||||
requesting_origin, user_gesture, nullptr,
|
||||
response_callback);
|
||||
std::move(response_callback));
|
||||
}
|
||||
|
||||
int AtomPermissionManager::RequestPermissionsWithDetails(
|
||||
@@ -149,9 +154,9 @@ int AtomPermissionManager::RequestPermissionsWithDetails(
|
||||
const GURL& requesting_origin,
|
||||
bool user_gesture,
|
||||
const base::DictionaryValue* details,
|
||||
const StatusesCallback& response_callback) {
|
||||
StatusesCallback response_callback) {
|
||||
if (permissions.empty()) {
|
||||
response_callback.Run(std::vector<blink::mojom::PermissionStatus>());
|
||||
std::move(response_callback).Run({});
|
||||
return content::PermissionController::kNoPendingOperation;
|
||||
}
|
||||
|
||||
@@ -169,26 +174,27 @@ int AtomPermissionManager::RequestPermissionsWithDetails(
|
||||
}
|
||||
statuses.push_back(blink::mojom::PermissionStatus::GRANTED);
|
||||
}
|
||||
response_callback.Run(statuses);
|
||||
std::move(response_callback).Run(statuses);
|
||||
return content::PermissionController::kNoPendingOperation;
|
||||
}
|
||||
|
||||
auto* web_contents =
|
||||
content::WebContents::FromRenderFrameHost(render_frame_host);
|
||||
int request_id = pending_requests_.Add(std::make_unique<PendingRequest>(
|
||||
render_frame_host, permissions, response_callback));
|
||||
render_frame_host, permissions, std::move(response_callback)));
|
||||
|
||||
for (size_t i = 0; i < permissions.size(); ++i) {
|
||||
auto permission = permissions[i];
|
||||
const auto callback =
|
||||
base::Bind(&AtomPermissionManager::OnPermissionResponse,
|
||||
base::Unretained(this), request_id, i);
|
||||
if (details == nullptr) {
|
||||
request_handler_.Run(web_contents, permission, callback,
|
||||
base::DictionaryValue());
|
||||
} else {
|
||||
request_handler_.Run(web_contents, permission, callback, *details);
|
||||
}
|
||||
base::BindRepeating(&AtomPermissionManager::OnPermissionResponse,
|
||||
base::Unretained(this), request_id, i);
|
||||
auto mutable_details =
|
||||
details == nullptr ? base::DictionaryValue() : details->Clone();
|
||||
mutable_details.SetStringKey(
|
||||
"requestingUrl", render_frame_host->GetLastCommittedURL().spec());
|
||||
mutable_details.SetBoolKey("isMainFrame",
|
||||
render_frame_host->GetParent() == nullptr);
|
||||
request_handler_.Run(web_contents, permission, callback, mutable_details);
|
||||
}
|
||||
|
||||
return request_id;
|
||||
@@ -224,7 +230,7 @@ int AtomPermissionManager::SubscribePermissionStatusChange(
|
||||
content::PermissionType permission,
|
||||
content::RenderFrameHost* render_frame_host,
|
||||
const GURL& requesting_origin,
|
||||
const base::Callback<void(blink::mojom::PermissionStatus)>& callback) {
|
||||
base::RepeatingCallback<void(blink::mojom::PermissionStatus)> callback) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -241,8 +247,14 @@ bool AtomPermissionManager::CheckPermissionWithDetails(
|
||||
}
|
||||
auto* web_contents =
|
||||
content::WebContents::FromRenderFrameHost(render_frame_host);
|
||||
auto mutable_details =
|
||||
details == nullptr ? base::DictionaryValue() : details->Clone();
|
||||
mutable_details.SetStringKey("requestingUrl",
|
||||
render_frame_host->GetLastCommittedURL().spec());
|
||||
mutable_details.SetBoolKey("isMainFrame",
|
||||
render_frame_host->GetParent() == nullptr);
|
||||
return check_handler_.Run(web_contents, permission, requesting_origin,
|
||||
*details);
|
||||
mutable_details);
|
||||
}
|
||||
|
||||
blink::mojom::PermissionStatus
|
||||
|
||||
@@ -25,52 +25,48 @@ class AtomPermissionManager : public content::PermissionControllerDelegate {
|
||||
AtomPermissionManager();
|
||||
~AtomPermissionManager() override;
|
||||
|
||||
using StatusCallback = base::Callback<void(blink::mojom::PermissionStatus)>;
|
||||
using StatusesCallback =
|
||||
base::Callback<void(const std::vector<blink::mojom::PermissionStatus>&)>;
|
||||
using StatusCallback =
|
||||
base::OnceCallback<void(blink::mojom::PermissionStatus)>;
|
||||
using StatusesCallback = base::OnceCallback<void(
|
||||
const std::vector<blink::mojom::PermissionStatus>&)>;
|
||||
using RequestHandler = base::Callback<void(content::WebContents*,
|
||||
content::PermissionType,
|
||||
const StatusCallback&,
|
||||
const base::DictionaryValue&)>;
|
||||
StatusCallback,
|
||||
const base::Value&)>;
|
||||
using CheckHandler = base::Callback<bool(content::WebContents*,
|
||||
content::PermissionType,
|
||||
const GURL& requesting_origin,
|
||||
const base::DictionaryValue&)>;
|
||||
const base::Value&)>;
|
||||
|
||||
// Handler to dispatch permission requests in JS.
|
||||
void SetPermissionRequestHandler(const RequestHandler& handler);
|
||||
void SetPermissionCheckHandler(const CheckHandler& handler);
|
||||
|
||||
// content::PermissionControllerDelegate:
|
||||
int RequestPermission(
|
||||
content::PermissionType permission,
|
||||
content::RenderFrameHost* render_frame_host,
|
||||
const GURL& requesting_origin,
|
||||
bool user_gesture,
|
||||
const base::Callback<void(blink::mojom::PermissionStatus)>& callback)
|
||||
override;
|
||||
int RequestPermission(content::PermissionType permission,
|
||||
content::RenderFrameHost* render_frame_host,
|
||||
const GURL& requesting_origin,
|
||||
bool user_gesture,
|
||||
StatusCallback callback) override;
|
||||
int RequestPermissionWithDetails(content::PermissionType permission,
|
||||
content::RenderFrameHost* render_frame_host,
|
||||
const GURL& requesting_origin,
|
||||
bool user_gesture,
|
||||
const base::DictionaryValue* details,
|
||||
const StatusCallback& callback);
|
||||
StatusCallback callback);
|
||||
int RequestPermissions(
|
||||
const std::vector<content::PermissionType>& permissions,
|
||||
content::RenderFrameHost* render_frame_host,
|
||||
const GURL& requesting_origin,
|
||||
bool user_gesture,
|
||||
const base::Callback<
|
||||
void(const std::vector<blink::mojom::PermissionStatus>&)>& callback)
|
||||
override;
|
||||
StatusesCallback callback) override;
|
||||
int RequestPermissionsWithDetails(
|
||||
const std::vector<content::PermissionType>& permissions,
|
||||
content::RenderFrameHost* render_frame_host,
|
||||
const GURL& requesting_origin,
|
||||
bool user_gesture,
|
||||
const base::DictionaryValue* details,
|
||||
const base::Callback<
|
||||
void(const std::vector<blink::mojom::PermissionStatus>&)>& callback);
|
||||
StatusesCallback callback);
|
||||
blink::mojom::PermissionStatus GetPermissionStatusForFrame(
|
||||
content::PermissionType permission,
|
||||
content::RenderFrameHost* render_frame_host,
|
||||
@@ -98,7 +94,7 @@ class AtomPermissionManager : public content::PermissionControllerDelegate {
|
||||
content::PermissionType permission,
|
||||
content::RenderFrameHost* render_frame_host,
|
||||
const GURL& requesting_origin,
|
||||
const base::Callback<void(blink::mojom::PermissionStatus)>& callback)
|
||||
base::RepeatingCallback<void(blink::mojom::PermissionStatus)> callback)
|
||||
override;
|
||||
void UnsubscribePermissionStatusChange(int subscription_id) override;
|
||||
|
||||
|
||||
@@ -197,6 +197,7 @@ class Browser : public WindowListObserver {
|
||||
base::string16 arguments;
|
||||
base::string16 title;
|
||||
base::string16 description;
|
||||
base::FilePath working_dir;
|
||||
base::FilePath icon_path;
|
||||
int icon_index;
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "chrome/browser/net/chrome_net_log_helper.h"
|
||||
#include "chrome/common/chrome_switches.h"
|
||||
#include "components/net_log/chrome_net_log.h"
|
||||
#include "components/net_log/net_export_file_writer.h"
|
||||
@@ -19,6 +18,7 @@
|
||||
#include "components/proxy_config/proxy_config_dictionary.h"
|
||||
#include "components/proxy_config/proxy_config_pref_names.h"
|
||||
#include "content/public/common/content_switches.h"
|
||||
#include "net/log/net_log_capture_mode.h"
|
||||
#include "net/proxy_resolution/proxy_config.h"
|
||||
#include "net/proxy_resolution/proxy_config_service.h"
|
||||
#include "net/proxy_resolution/proxy_config_with_annotation.h"
|
||||
@@ -105,7 +105,9 @@ void BrowserProcessImpl::PreCreateThreads(
|
||||
command_line.GetSwitchValuePath(network::switches::kLogNetLog);
|
||||
if (!log_file.empty()) {
|
||||
net_log_->StartWritingToFile(
|
||||
log_file, GetNetCaptureModeFromCommandLine(command_line),
|
||||
log_file,
|
||||
net::GetNetCaptureModeFromCommandLine(
|
||||
command_line, network::switches::kNetLogCaptureMode),
|
||||
command_line.GetCommandLineString(), std::string());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,6 +141,7 @@ bool Browser::SetUserTasks(const std::vector<UserTask>& tasks) {
|
||||
item.icon_path = task.icon_path;
|
||||
item.icon_index = task.icon_index;
|
||||
item.description = task.description;
|
||||
item.working_dir = task.working_dir;
|
||||
category.items.push_back(item);
|
||||
}
|
||||
|
||||
|
||||
@@ -84,22 +84,23 @@ std::string RegisterFileSystem(content::WebContents* web_contents,
|
||||
const base::FilePath& path) {
|
||||
auto* isolated_context = storage::IsolatedContext::GetInstance();
|
||||
std::string root_name(kRootName);
|
||||
std::string file_system_id = isolated_context->RegisterFileSystemForPath(
|
||||
storage::kFileSystemTypeNativeLocal, std::string(), path, &root_name);
|
||||
storage::IsolatedContext::ScopedFSHandle file_system =
|
||||
isolated_context->RegisterFileSystemForPath(
|
||||
storage::kFileSystemTypeNativeLocal, std::string(), path, &root_name);
|
||||
|
||||
content::ChildProcessSecurityPolicy* policy =
|
||||
content::ChildProcessSecurityPolicy::GetInstance();
|
||||
content::RenderViewHost* render_view_host = web_contents->GetRenderViewHost();
|
||||
int renderer_id = render_view_host->GetProcess()->GetID();
|
||||
policy->GrantReadFileSystem(renderer_id, file_system_id);
|
||||
policy->GrantWriteFileSystem(renderer_id, file_system_id);
|
||||
policy->GrantCreateFileForFileSystem(renderer_id, file_system_id);
|
||||
policy->GrantDeleteFromFileSystem(renderer_id, file_system_id);
|
||||
policy->GrantReadFileSystem(renderer_id, file_system.id());
|
||||
policy->GrantWriteFileSystem(renderer_id, file_system.id());
|
||||
policy->GrantCreateFileForFileSystem(renderer_id, file_system.id());
|
||||
policy->GrantDeleteFromFileSystem(renderer_id, file_system.id());
|
||||
|
||||
if (!policy->CanReadFile(renderer_id, path))
|
||||
policy->GrantReadFile(renderer_id, path);
|
||||
|
||||
return file_system_id;
|
||||
return file_system.id();
|
||||
}
|
||||
|
||||
FileSystem CreateFileSystemStruct(content::WebContents* web_contents,
|
||||
@@ -327,9 +328,12 @@ void CommonWebContentsDelegate::EnterFullscreenModeForTab(
|
||||
const blink::WebFullscreenOptions& options) {
|
||||
if (!owner_window_)
|
||||
return;
|
||||
if (IsFullscreenForTabOrPending(source)) {
|
||||
DCHECK_EQ(fullscreen_frame_, source->GetFocusedFrame());
|
||||
return;
|
||||
}
|
||||
SetHtmlApiFullscreen(true);
|
||||
owner_window_->NotifyWindowEnterHtmlFullScreen();
|
||||
source->GetRenderViewHost()->GetWidget()->SynchronizeVisualProperties();
|
||||
}
|
||||
|
||||
void CommonWebContentsDelegate::ExitFullscreenModeForTab(
|
||||
@@ -338,7 +342,6 @@ void CommonWebContentsDelegate::ExitFullscreenModeForTab(
|
||||
return;
|
||||
SetHtmlApiFullscreen(false);
|
||||
owner_window_->NotifyWindowLeaveHtmlFullScreen();
|
||||
source->GetRenderViewHost()->GetWidget()->SynchronizeVisualProperties();
|
||||
}
|
||||
|
||||
bool CommonWebContentsDelegate::IsFullscreenForTabOrPending(
|
||||
|
||||
@@ -68,6 +68,10 @@ class CommonWebContentsDelegate : public content::WebContentsDelegate,
|
||||
|
||||
bool is_html_fullscreen() const { return html_fullscreen_; }
|
||||
|
||||
void set_fullscreen_frame(content::RenderFrameHost* rfh) {
|
||||
fullscreen_frame_ = rfh;
|
||||
}
|
||||
|
||||
protected:
|
||||
#if BUILDFLAG(ENABLE_OSR)
|
||||
virtual OffScreenWebContentsView* GetOffScreenWebContentsView() const;
|
||||
@@ -203,6 +207,9 @@ class CommonWebContentsDelegate : public content::WebContentsDelegate,
|
||||
|
||||
scoped_refptr<base::SequencedTaskRunner> file_task_runner_;
|
||||
|
||||
// Stores the frame thats currently in fullscreen, nullptr if there is none.
|
||||
content::RenderFrameHost* fullscreen_frame_ = nullptr;
|
||||
|
||||
base::WeakPtrFactory<CommonWebContentsDelegate> weak_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CommonWebContentsDelegate);
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "atom/browser/net/url_request_context_getter.h"
|
||||
#include "components/net_log/chrome_net_log.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/network_service_instance.h"
|
||||
@@ -35,6 +36,24 @@ IOThread::~IOThread() {
|
||||
BrowserThread::SetIOThreadDelegate(nullptr);
|
||||
}
|
||||
|
||||
void IOThread::RegisterURLRequestContextGetter(
|
||||
atom::URLRequestContextGetter* getter) {
|
||||
base::AutoLock lock(lock_);
|
||||
|
||||
DCHECK(!base::FeatureList::IsEnabled(network::features::kNetworkService));
|
||||
DCHECK_EQ(0u, request_context_getters_.count(getter));
|
||||
request_context_getters_.insert(getter);
|
||||
}
|
||||
|
||||
void IOThread::DeregisterURLRequestContextGetter(
|
||||
atom::URLRequestContextGetter* getter) {
|
||||
base::AutoLock lock(lock_);
|
||||
|
||||
DCHECK(!base::FeatureList::IsEnabled(network::features::kNetworkService));
|
||||
DCHECK_EQ(1u, request_context_getters_.count(getter));
|
||||
request_context_getters_.erase(getter);
|
||||
}
|
||||
|
||||
void IOThread::Init() {
|
||||
if (!base::FeatureList::IsEnabled(network::features::kNetworkService)) {
|
||||
std::unique_ptr<network::URLRequestContextBuilderMojo> builder =
|
||||
@@ -55,20 +74,24 @@ void IOThread::Init() {
|
||||
network_service->ConfigureHttpAuthPrefs(
|
||||
std::move(http_auth_dynamic_params_));
|
||||
|
||||
system_network_context_ =
|
||||
network_service
|
||||
->CreateNetworkContextWithBuilder(
|
||||
std::move(network_context_request_),
|
||||
std::move(network_context_params_), std::move(builder),
|
||||
&system_request_context_)
|
||||
.release();
|
||||
system_network_context_ = network_service->CreateNetworkContextWithBuilder(
|
||||
std::move(network_context_request_), std::move(network_context_params_),
|
||||
std::move(builder), &system_request_context_);
|
||||
}
|
||||
}
|
||||
|
||||
void IOThread::CleanUp() {
|
||||
if (!base::FeatureList::IsEnabled(network::features::kNetworkService))
|
||||
if (!base::FeatureList::IsEnabled(network::features::kNetworkService)) {
|
||||
system_request_context_->proxy_resolution_service()->OnShutdown();
|
||||
|
||||
base::AutoLock lock(lock_);
|
||||
for (auto* getter : request_context_getters_) {
|
||||
getter->NotifyContextShuttingDown();
|
||||
}
|
||||
|
||||
system_network_context_.reset();
|
||||
}
|
||||
|
||||
if (net_log_)
|
||||
net_log_->ShutDownBeforeThreadPool();
|
||||
}
|
||||
|
||||
@@ -6,12 +6,18 @@
|
||||
#define ATOM_BROWSER_IO_THREAD_H_
|
||||
|
||||
#include <memory>
|
||||
#include <set>
|
||||
|
||||
#include "atom/browser/net/system_network_context_manager.h"
|
||||
#include "base/macros.h"
|
||||
#include "base/synchronization/lock.h"
|
||||
#include "content/public/browser/browser_thread_delegate.h"
|
||||
#include "services/network/public/mojom/network_service.mojom.h"
|
||||
|
||||
namespace atom {
|
||||
class URLRequestContextGetter;
|
||||
}
|
||||
|
||||
namespace net {
|
||||
class URLRequestContext;
|
||||
}
|
||||
@@ -27,6 +33,9 @@ class IOThread : public content::BrowserThreadDelegate {
|
||||
SystemNetworkContextManager* system_network_context_manager);
|
||||
~IOThread() override;
|
||||
|
||||
void RegisterURLRequestContextGetter(atom::URLRequestContextGetter* getter);
|
||||
void DeregisterURLRequestContextGetter(atom::URLRequestContextGetter* getter);
|
||||
|
||||
protected:
|
||||
// BrowserThreadDelegate Implementation, runs on the IO thread.
|
||||
void Init() override;
|
||||
@@ -39,13 +48,7 @@ class IOThread : public content::BrowserThreadDelegate {
|
||||
|
||||
// When the network service is disabled, this holds on to a
|
||||
// content::NetworkContext class that owns |system_request_context_|.
|
||||
// TODO(deepak1556): primary network context has to be destroyed after
|
||||
// other active contexts, but since the ownership of latter is not released
|
||||
// before IO thread is destroyed, it results in a DCHECK failure.
|
||||
// We leak the reference to primary context to workaround this issue,
|
||||
// since there is only one instance for the entire lifetime of app, it is
|
||||
// safe.
|
||||
network::mojom::NetworkContext* system_network_context_;
|
||||
std::unique_ptr<network::mojom::NetworkContext> system_network_context_;
|
||||
net::URLRequestContext* system_request_context_;
|
||||
|
||||
// These are set on the UI thread, and then consumed during initialization on
|
||||
@@ -59,6 +62,13 @@ class IOThread : public content::BrowserThreadDelegate {
|
||||
network::mojom::HttpAuthStaticParamsPtr http_auth_static_params_;
|
||||
network::mojom::HttpAuthDynamicParamsPtr http_auth_dynamic_params_;
|
||||
|
||||
// |lock_| protects access to |request_context_getters_|.
|
||||
base::Lock lock_;
|
||||
|
||||
// List of all request contexts that needs to be notified when
|
||||
// IO thread is shutting down.
|
||||
std::set<atom::URLRequestContextGetter*> request_context_getters_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(IOThread);
|
||||
};
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ v8::Isolate* JavascriptEnvironment::Initialize(uv_loop_t* event_loop) {
|
||||
auto* tracing_controller = tracing_agent->GetTracingController();
|
||||
node::tracing::TraceEventHelper::SetAgent(tracing_agent);
|
||||
platform_ = node::CreatePlatform(
|
||||
base::RecommendedMaxNumberOfThreadsInPool(3, 8, 0.1, 0),
|
||||
base::RecommendedMaxNumberOfThreadsInThreadGroup(3, 8, 0.1, 0),
|
||||
tracing_controller);
|
||||
|
||||
v8::V8::InitializePlatform(platform_);
|
||||
|
||||
@@ -29,7 +29,7 @@ struct Product {
|
||||
std::string formattedPrice;
|
||||
|
||||
// Downloadable Content Information
|
||||
bool downloadable = false;
|
||||
bool isDownloadable = false;
|
||||
|
||||
Product(const Product&);
|
||||
Product();
|
||||
|
||||
@@ -146,9 +146,7 @@
|
||||
}
|
||||
|
||||
// Downloadable Content Information
|
||||
if (product.downloadable == true) {
|
||||
productStruct.downloadable = true;
|
||||
}
|
||||
productStruct.isDownloadable = [product downloadable];
|
||||
|
||||
return productStruct;
|
||||
}
|
||||
|
||||
@@ -167,7 +167,7 @@ class NativeWindowMac : public NativeWindow {
|
||||
|
||||
private:
|
||||
// Add custom layers to the content view.
|
||||
void AddContentViewLayers();
|
||||
void AddContentViewLayers(bool minimizable, bool closable);
|
||||
|
||||
void InternalSetParentWindow(NativeWindow* parent, bool attach);
|
||||
void SetForwardMouseMessages(bool forward);
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "base/mac/mac_util.h"
|
||||
#include "base/mac/scoped_cftyperef.h"
|
||||
#include "base/strings/sys_string_conversions.h"
|
||||
#include "components/remote_cocoa/app_shim/bridged_native_widget_impl.h"
|
||||
#include "content/public/browser/browser_accessibility_state.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "skia/ext/skia_utils_mac.h"
|
||||
@@ -30,7 +31,6 @@
|
||||
#include "ui/gl/gpu_switching_manager.h"
|
||||
#include "ui/views/background.h"
|
||||
#include "ui/views/widget/widget.h"
|
||||
#include "ui/views_bridge_mac/bridged_native_widget_impl.h"
|
||||
|
||||
// This view always takes the size of its superview. It is intended to be used
|
||||
// as a NSWindow's contentView. It is needed because NSWindow's implementation
|
||||
@@ -73,9 +73,11 @@
|
||||
NSButton* close_button =
|
||||
[NSWindow standardWindowButton:NSWindowCloseButton
|
||||
forStyleMask:NSWindowStyleMaskTitled];
|
||||
[close_button setTag:1];
|
||||
NSButton* miniaturize_button =
|
||||
[NSWindow standardWindowButton:NSWindowMiniaturizeButton
|
||||
forStyleMask:NSWindowStyleMaskTitled];
|
||||
[miniaturize_button setTag:2];
|
||||
|
||||
CGFloat x = 0;
|
||||
const CGFloat space_between = 20;
|
||||
@@ -459,7 +461,7 @@ NativeWindowMac::NativeWindowMac(const mate::Dictionary& options,
|
||||
|
||||
// Default content view.
|
||||
SetContentView(new views::View());
|
||||
AddContentViewLayers();
|
||||
AddContentViewLayers(minimizable, closable);
|
||||
|
||||
original_frame_ = [window_ frame];
|
||||
original_level_ = [window_ level];
|
||||
@@ -851,9 +853,9 @@ void NativeWindowMac::SetAlwaysOnTop(bool top,
|
||||
if (newLevel >= minWindowLevel && newLevel <= maxWindowLevel) {
|
||||
[window_ setLevel:newLevel];
|
||||
} else {
|
||||
*error = std::string([
|
||||
[NSString stringWithFormat:@"relativeLevel must be between %d and %d",
|
||||
minWindowLevel, maxWindowLevel] UTF8String]);
|
||||
*error = std::string([[NSString
|
||||
stringWithFormat:@"relativeLevel must be between %d and %d",
|
||||
minWindowLevel, maxWindowLevel] UTF8String]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1102,7 +1104,7 @@ void NativeWindowMac::RemoveBrowserView(NativeBrowserView* view) {
|
||||
}
|
||||
|
||||
[view->GetInspectableWebContentsView()->GetNativeView().GetNativeNSView()
|
||||
removeFromSuperview];
|
||||
removeFromSuperview];
|
||||
remove_browser_view(view);
|
||||
|
||||
[CATransaction commit];
|
||||
@@ -1384,7 +1386,7 @@ views::View* NativeWindowMac::GetContentsView() {
|
||||
return root_view_.get();
|
||||
}
|
||||
|
||||
void NativeWindowMac::AddContentViewLayers() {
|
||||
void NativeWindowMac::AddContentViewLayers(bool minimizable, bool closable) {
|
||||
// Make sure the bottom corner is rounded for non-modal windows:
|
||||
// http://crbug.com/396264.
|
||||
if (!is_modal()) {
|
||||
@@ -1424,6 +1426,12 @@ void NativeWindowMac::AddContentViewLayers() {
|
||||
[[CustomWindowButtonView alloc] initWithFrame:NSZeroRect]);
|
||||
// NSWindowStyleMaskFullSizeContentView does not work with zoom button
|
||||
SetFullScreenable(false);
|
||||
|
||||
if (!minimizable)
|
||||
[[buttons_view_ viewWithTag:2] removeFromSuperview];
|
||||
if (!closable)
|
||||
[[buttons_view_ viewWithTag:1] removeFromSuperview];
|
||||
|
||||
[[window_ contentView] addSubview:buttons_view_];
|
||||
} else {
|
||||
if (title_bar_style_ != NORMAL)
|
||||
@@ -1480,7 +1488,7 @@ void NativeWindowMac::OverrideNSWindowContentView() {
|
||||
setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
|
||||
[container_view_ setFrame:[[[window_ contentView] superview] bounds]];
|
||||
[window_ setContentView:container_view_];
|
||||
AddContentViewLayers();
|
||||
AddContentViewLayers(IsMinimizable(), IsClosable());
|
||||
}
|
||||
|
||||
void NativeWindowMac::SetStyleMask(bool on, NSUInteger flag) {
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#include "atom/browser/native_window_views.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include <objbase.h>
|
||||
#include <wrl/client.h>
|
||||
#endif
|
||||
|
||||
@@ -59,10 +58,8 @@
|
||||
#elif defined(OS_WIN)
|
||||
#include "atom/browser/ui/views/win_frame_view.h"
|
||||
#include "atom/browser/ui/win/atom_desktop_native_widget_aura.h"
|
||||
#include "atom/browser/ui/win/atom_desktop_window_tree_host_win.h"
|
||||
#include "skia/ext/skia_utils_win.h"
|
||||
#include "ui/base/win/shell.h"
|
||||
#include "ui/display/display.h"
|
||||
#include "ui/display/screen.h"
|
||||
#include "ui/display/win/screen_win.h"
|
||||
#include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
|
||||
@@ -188,11 +185,7 @@ NativeWindowViews::NativeWindowViews(const mate::Dictionary& options,
|
||||
if (parent)
|
||||
params.parent = parent->GetNativeWindow();
|
||||
|
||||
params.native_widget = new AtomDesktopNativeWidgetAura(widget());
|
||||
atom_desktop_window_tree_host_win_ = new AtomDesktopWindowTreeHostWin(
|
||||
this, widget(),
|
||||
static_cast<views::DesktopNativeWidgetAura*>(params.native_widget));
|
||||
params.desktop_window_tree_host = atom_desktop_window_tree_host_win_;
|
||||
params.native_widget = new AtomDesktopNativeWidgetAura(this);
|
||||
#elif defined(USE_X11)
|
||||
std::string name = Browser::Get()->GetName();
|
||||
// Set WM_WINDOW_ROLE.
|
||||
@@ -473,24 +466,15 @@ void NativeWindowViews::SetEnabledInternal(bool enable) {
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(USE_X11)
|
||||
void NativeWindowViews::Maximize() {
|
||||
#if defined(OS_WIN)
|
||||
// For window without WS_THICKFRAME style, we can not call Maximize().
|
||||
if (!(::GetWindowLong(GetAcceleratedWidget(), GWL_STYLE) & WS_THICKFRAME)) {
|
||||
restore_bounds_ = GetBounds();
|
||||
auto display =
|
||||
display::Screen::GetScreen()->GetDisplayNearestPoint(GetPosition());
|
||||
SetBounds(display.work_area(), false);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (IsVisible())
|
||||
widget()->Maximize();
|
||||
else
|
||||
widget()->native_widget_private()->Show(ui::SHOW_STATE_MAXIMIZED,
|
||||
gfx::Rect());
|
||||
}
|
||||
#endif
|
||||
|
||||
void NativeWindowViews::Unmaximize() {
|
||||
#if defined(OS_WIN)
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
#include "ui/views/widget/widget_observer.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include "atom/browser/ui/win/message_handler_delegate.h"
|
||||
#include "atom/browser/ui/win/taskbar_host.h"
|
||||
#include "base/win/scoped_gdi_object.h"
|
||||
#endif
|
||||
@@ -30,16 +29,11 @@ class GlobalMenuBarX11;
|
||||
class RootView;
|
||||
class WindowStateWatcher;
|
||||
|
||||
#if defined(OS_WIN)
|
||||
class AtomDesktopWindowTreeHostWin;
|
||||
#elif defined(USE_X11)
|
||||
#if defined(USE_X11)
|
||||
class EventDisabler;
|
||||
#endif
|
||||
|
||||
class NativeWindowViews : public NativeWindow,
|
||||
#if defined(OS_WIN)
|
||||
public MessageHandlerDelegate,
|
||||
#endif
|
||||
public views::WidgetObserver,
|
||||
public ui::EventHandler {
|
||||
public:
|
||||
@@ -142,6 +136,16 @@ class NativeWindowViews : public NativeWindow,
|
||||
void DecrementChildModals();
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// Catch-all message handling and filtering. Called before
|
||||
// HWNDMessageHandler's built-in handling, which may pre-empt some
|
||||
// expectations in Views/Aura if messages are consumed. Returns true if the
|
||||
// message was consumed by the delegate and should not be processed further
|
||||
// by the HWNDMessageHandler. In this case, |result| is returned. |result| is
|
||||
// not modified otherwise.
|
||||
bool PreHandleMSG(UINT message,
|
||||
WPARAM w_param,
|
||||
LPARAM l_param,
|
||||
LRESULT* result);
|
||||
void SetIcon(HICON small_icon, HICON app_icon);
|
||||
#elif defined(USE_X11)
|
||||
void SetIcon(const gfx::ImageSkia& icon);
|
||||
@@ -180,11 +184,6 @@ class NativeWindowViews : public NativeWindow,
|
||||
#endif
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// MessageHandlerDelegate:
|
||||
bool PreHandleMSG(UINT message,
|
||||
WPARAM w_param,
|
||||
LPARAM l_param,
|
||||
LRESULT* result) override;
|
||||
void HandleSizeEvent(WPARAM w_param, LPARAM l_param);
|
||||
void SetForwardMouseMessages(bool forward);
|
||||
static LRESULT CALLBACK SubclassProc(HWND hwnd,
|
||||
@@ -237,8 +236,6 @@ class NativeWindowViews : public NativeWindow,
|
||||
#endif
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// Weak ref.
|
||||
AtomDesktopWindowTreeHostWin* atom_desktop_window_tree_host_win_;
|
||||
|
||||
ui::WindowShowState last_window_state_;
|
||||
|
||||
|
||||
@@ -2,14 +2,19 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include <dwmapi.h>
|
||||
#include <shellapi.h>
|
||||
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/browser/native_window_views.h"
|
||||
#include "atom/browser/ui/views/root_view.h"
|
||||
#include "atom/common/atom_constants.h"
|
||||
#include "content/public/browser/browser_accessibility_state.h"
|
||||
#include "ui/base/win/accessibility_misc_utils.h"
|
||||
#include "ui/display/display.h"
|
||||
#include "ui/display/win/screen_win.h"
|
||||
#include "ui/gfx/geometry/insets.h"
|
||||
#include "ui/views/widget/native_widget_private.h"
|
||||
|
||||
// Must be included after other Windows headers.
|
||||
#include <UIAutomationCoreApi.h>
|
||||
@@ -138,11 +143,155 @@ bool IsScreenReaderActive() {
|
||||
return screenReader && UiaClientsAreListening();
|
||||
}
|
||||
|
||||
// We use "enum" instead of "enum class" because we need to do bitwise compare.
|
||||
enum AppbarAutohideEdge {
|
||||
TOP = 1 << 0,
|
||||
LEFT = 1 << 1,
|
||||
BOTTOM = 1 << 2,
|
||||
RIGHT = 1 << 3,
|
||||
};
|
||||
|
||||
// The thickness of an auto-hide taskbar in pixel.
|
||||
constexpr int kAutoHideTaskbarThicknessPx = 2;
|
||||
|
||||
// Code is copied from chrome_views_delegate_win.cc.
|
||||
bool MonitorHasAutohideTaskbarForEdge(UINT edge, HMONITOR monitor) {
|
||||
APPBARDATA taskbar_data = {sizeof(APPBARDATA), NULL, 0, edge};
|
||||
taskbar_data.hWnd = ::GetForegroundWindow();
|
||||
|
||||
// MSDN documents an ABM_GETAUTOHIDEBAREX, which supposedly takes a monitor
|
||||
// rect and returns autohide bars on that monitor. This sounds like a good
|
||||
// idea for multi-monitor systems. Unfortunately, it appears to not work at
|
||||
// least some of the time (erroneously returning NULL) and there's almost no
|
||||
// online documentation or other sample code using it that suggests ways to
|
||||
// address this problem. We do the following:-
|
||||
// 1. Use the ABM_GETAUTOHIDEBAR message. If it works, i.e. returns a valid
|
||||
// window we are done.
|
||||
// 2. If the ABM_GETAUTOHIDEBAR message does not work we query the auto hide
|
||||
// state of the taskbar and then retrieve its position. That call returns
|
||||
// the edge on which the taskbar is present. If it matches the edge we
|
||||
// are looking for, we are done.
|
||||
// NOTE: This call spins a nested run loop.
|
||||
HWND taskbar = reinterpret_cast<HWND>(
|
||||
SHAppBarMessage(ABM_GETAUTOHIDEBAR, &taskbar_data));
|
||||
if (!::IsWindow(taskbar)) {
|
||||
APPBARDATA taskbar_data = {sizeof(APPBARDATA), 0, 0, 0};
|
||||
unsigned int taskbar_state = SHAppBarMessage(ABM_GETSTATE, &taskbar_data);
|
||||
if (!(taskbar_state & ABS_AUTOHIDE))
|
||||
return false;
|
||||
|
||||
taskbar_data.hWnd = ::FindWindow(L"Shell_TrayWnd", NULL);
|
||||
if (!::IsWindow(taskbar_data.hWnd))
|
||||
return false;
|
||||
|
||||
SHAppBarMessage(ABM_GETTASKBARPOS, &taskbar_data);
|
||||
if (taskbar_data.uEdge == edge)
|
||||
taskbar = taskbar_data.hWnd;
|
||||
}
|
||||
|
||||
// There is a potential race condition here:
|
||||
// 1. A maximized chrome window is fullscreened.
|
||||
// 2. It is switched back to maximized.
|
||||
// 3. In the process the window gets a WM_NCCACLSIZE message which calls us to
|
||||
// get the autohide state.
|
||||
// 4. The worker thread is invoked. It calls the API to get the autohide
|
||||
// state. On Windows versions earlier than Windows 7, taskbars could
|
||||
// easily be always on top or not.
|
||||
// This meant that we only want to look for taskbars which have the topmost
|
||||
// bit set. However this causes problems in cases where the window on the
|
||||
// main thread is still in the process of switching away from fullscreen.
|
||||
// In this case the taskbar might not yet have the topmost bit set.
|
||||
// 5. The main thread resumes and does not leave space for the taskbar and
|
||||
// hence it does not pop when hovered.
|
||||
//
|
||||
// To address point 4 above, it is best to not check for the WS_EX_TOPMOST
|
||||
// window style on the taskbar, as starting from Windows 7, the topmost
|
||||
// style is always set. We don't support XP and Vista anymore.
|
||||
if (::IsWindow(taskbar)) {
|
||||
if (MonitorFromWindow(taskbar, MONITOR_DEFAULTTONEAREST) == monitor)
|
||||
return true;
|
||||
// In some cases like when the autohide taskbar is on the left of the
|
||||
// secondary monitor, the MonitorFromWindow call above fails to return the
|
||||
// correct monitor the taskbar is on. We fallback to MonitorFromPoint for
|
||||
// the cursor position in that case, which seems to work well.
|
||||
POINT cursor_pos = {0};
|
||||
GetCursorPos(&cursor_pos);
|
||||
if (MonitorFromPoint(cursor_pos, MONITOR_DEFAULTTONEAREST) == monitor)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int GetAppbarAutohideEdges(HWND hwnd) {
|
||||
HMONITOR monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONULL);
|
||||
if (!monitor)
|
||||
return 0;
|
||||
|
||||
int edges = 0;
|
||||
if (MonitorHasAutohideTaskbarForEdge(ABE_LEFT, monitor))
|
||||
edges |= AppbarAutohideEdge::LEFT;
|
||||
if (MonitorHasAutohideTaskbarForEdge(ABE_TOP, monitor))
|
||||
edges |= AppbarAutohideEdge::TOP;
|
||||
if (MonitorHasAutohideTaskbarForEdge(ABE_RIGHT, monitor))
|
||||
edges |= AppbarAutohideEdge::RIGHT;
|
||||
if (MonitorHasAutohideTaskbarForEdge(ABE_BOTTOM, monitor))
|
||||
edges |= AppbarAutohideEdge::BOTTOM;
|
||||
return edges;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
std::set<NativeWindowViews*> NativeWindowViews::forwarding_windows_;
|
||||
HHOOK NativeWindowViews::mouse_hook_ = NULL;
|
||||
|
||||
void NativeWindowViews::Maximize() {
|
||||
int autohide_edges = 0;
|
||||
if (!has_frame())
|
||||
autohide_edges = GetAppbarAutohideEdges(GetAcceleratedWidget());
|
||||
|
||||
// Only use Maximize() when:
|
||||
// 1. window has WS_THICKFRAME style;
|
||||
// 2. and window is not frameless when there is autohide taskbar.
|
||||
if ((::GetWindowLong(GetAcceleratedWidget(), GWL_STYLE) & WS_THICKFRAME) &&
|
||||
(has_frame() || autohide_edges == 0)) {
|
||||
if (IsVisible())
|
||||
widget()->Maximize();
|
||||
else
|
||||
widget()->native_widget_private()->Show(ui::SHOW_STATE_MAXIMIZED,
|
||||
gfx::Rect());
|
||||
return;
|
||||
}
|
||||
|
||||
gfx::Insets insets;
|
||||
if (!has_frame()) {
|
||||
// When taskbar is autohide, we need to leave some space so the window
|
||||
// isn't treated as a "fullscreen app", which would cause the taskbars
|
||||
// to disappear.
|
||||
//
|
||||
// This trick comes from hwnd_message_handler.cc. While Chromium already
|
||||
// does this for normal window, somehow it is not applying the trick when
|
||||
// using frameless window, and we have to do it ourselves.
|
||||
float scale_factor =
|
||||
display::win::ScreenWin::GetScaleFactorForHWND(GetAcceleratedWidget());
|
||||
int thickness = std::ceil(kAutoHideTaskbarThicknessPx / scale_factor);
|
||||
if (autohide_edges & AppbarAutohideEdge::LEFT)
|
||||
insets.set_left(-thickness);
|
||||
if (autohide_edges & AppbarAutohideEdge::TOP)
|
||||
insets.set_top(-thickness);
|
||||
if (autohide_edges & AppbarAutohideEdge::RIGHT)
|
||||
insets.set_right(thickness);
|
||||
if (autohide_edges & AppbarAutohideEdge::BOTTOM)
|
||||
insets.set_bottom(thickness);
|
||||
}
|
||||
|
||||
restore_bounds_ = GetBounds();
|
||||
auto display =
|
||||
display::Screen::GetScreen()->GetDisplayNearestPoint(GetPosition());
|
||||
gfx::Rect bounds = display.work_area();
|
||||
bounds.Inset(insets);
|
||||
SetBounds(bounds, false);
|
||||
}
|
||||
|
||||
bool NativeWindowViews::ExecuteWindowsCommand(int command_id) {
|
||||
std::string command = AppCommandToString(command_id);
|
||||
NotifyWindowExecuteAppCommand(command);
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "atom/browser/atom_browser_client.h"
|
||||
#include "atom/browser/io_thread.h"
|
||||
#include "atom/common/application_info.h"
|
||||
#include "atom/common/options_switches.h"
|
||||
@@ -166,8 +167,7 @@ SystemNetworkContextManager::CreateDefaultNetworkContextParams() {
|
||||
network::mojom::NetworkContextParamsPtr network_context_params =
|
||||
network::mojom::NetworkContextParams::New();
|
||||
|
||||
network_context_params->enable_brotli =
|
||||
base::FeatureList::IsEnabled(features::kBrotliEncoding);
|
||||
network_context_params->enable_brotli = true;
|
||||
|
||||
network_context_params->enable_referrers = true;
|
||||
|
||||
@@ -247,7 +247,8 @@ SystemNetworkContextManager::CreateNetworkContextParams() {
|
||||
|
||||
network_context_params->context_name = std::string("system");
|
||||
|
||||
network_context_params->user_agent = atom::GetApplicationUserAgent();
|
||||
network_context_params->user_agent =
|
||||
atom::AtomBrowserClient::Get()->GetUserAgent();
|
||||
|
||||
network_context_params->http_cache_enabled = false;
|
||||
|
||||
|
||||
@@ -38,6 +38,20 @@ void BeforeStartInUI(base::WeakPtr<URLRequestAsyncAsarJob> job,
|
||||
error = net::ERR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
// sanitize custom headers
|
||||
if (request_options && request_options->is_dict()) {
|
||||
const base::Value* headersDict = request_options->FindDictKey("headers");
|
||||
if (headersDict) {
|
||||
for (const auto& iter : headersDict->DictItems()) {
|
||||
if (!iter.second.is_string()) {
|
||||
args->ThrowError("Value of '" + iter.first +
|
||||
"' header has to be a string");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {content::BrowserThread::IO},
|
||||
base::BindOnce(&URLRequestAsyncAsarJob::StartAsync, job,
|
||||
|
||||
@@ -122,9 +122,13 @@ URLRequestContextGetter::Handle::CreateMainRequestContextGetter(
|
||||
content::URLRequestInterceptorScopedVector protocol_interceptors) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||
DCHECK(!main_request_context_getter_.get());
|
||||
DCHECK(g_browser_process->io_thread());
|
||||
|
||||
LazyInitialize();
|
||||
main_request_context_getter_ = new URLRequestContextGetter(
|
||||
this, protocol_handlers, std::move(protocol_interceptors));
|
||||
g_browser_process->io_thread()->RegisterURLRequestContextGetter(
|
||||
main_request_context_getter_.get());
|
||||
return main_request_context_getter_;
|
||||
}
|
||||
|
||||
@@ -203,13 +207,13 @@ void URLRequestContextGetter::Handle::LazyInitialize() {
|
||||
|
||||
void URLRequestContextGetter::Handle::ShutdownOnUIThread() {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||
if (main_request_context_getter_.get()) {
|
||||
|
||||
if (main_request_context_getter_) {
|
||||
if (BrowserThread::IsThreadInitialized(BrowserThread::IO)) {
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {BrowserThread::IO},
|
||||
base::BindOnce(&URLRequestContextGetter::NotifyContextShuttingDown,
|
||||
base::RetainedRef(main_request_context_getter_),
|
||||
std::move(resource_context_)));
|
||||
base::RetainedRef(main_request_context_getter_)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -238,18 +242,20 @@ URLRequestContextGetter::~URLRequestContextGetter() {
|
||||
DCHECK(context_shutting_down_);
|
||||
}
|
||||
|
||||
void URLRequestContextGetter::NotifyContextShuttingDown(
|
||||
std::unique_ptr<content::ResourceContext> resource_context) {
|
||||
void URLRequestContextGetter::NotifyContextShuttingDown() {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
||||
DCHECK(g_browser_process->io_thread());
|
||||
DCHECK(context_handle_);
|
||||
|
||||
// todo(brenca): remove once C70 lands
|
||||
if (url_request_context_ && url_request_context_->cookie_store()) {
|
||||
url_request_context_->cookie_store()->FlushStore(base::NullCallback());
|
||||
}
|
||||
if (context_shutting_down_)
|
||||
return;
|
||||
|
||||
g_browser_process->io_thread()->DeregisterURLRequestContextGetter(this);
|
||||
|
||||
context_shutting_down_ = true;
|
||||
resource_context.reset();
|
||||
context_handle_->resource_context_.reset();
|
||||
net::URLRequestContextGetter::NotifyContextShuttingDown();
|
||||
network_context_.reset();
|
||||
}
|
||||
|
||||
net::URLRequestContext* URLRequestContextGetter::GetURLRequestContext() {
|
||||
|
||||
@@ -37,7 +37,7 @@ class URLRequestContextGetter : public net::URLRequestContextGetter {
|
||||
|
||||
// Discard reference to URLRequestContext and inform observers to
|
||||
// shutdown. Must be called only on IO thread.
|
||||
void NotifyContextShuttingDown(std::unique_ptr<content::ResourceContext>);
|
||||
void NotifyContextShuttingDown();
|
||||
|
||||
AtomURLRequestJobFactory* job_factory() const {
|
||||
return top_job_factory_.get();
|
||||
|
||||
@@ -270,10 +270,16 @@ LRESULT DesktopNotificationController::Toast::WndProc(HWND hwnd,
|
||||
case WM_MOUSEACTIVATE:
|
||||
return MA_NOACTIVATE;
|
||||
|
||||
case WM_TIMER:
|
||||
case WM_TIMER: {
|
||||
if (wparam == TimerID_AutoDismiss) {
|
||||
Get(hwnd)->AutoDismiss();
|
||||
auto* inst = Get(hwnd);
|
||||
|
||||
Notification notification(inst->data_);
|
||||
inst->data_->controller->OnNotificationDismissed(notification);
|
||||
|
||||
inst->AutoDismiss();
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
case WM_LBUTTONDOWN: {
|
||||
|
||||
@@ -47,8 +47,12 @@ void Win32Notification::Show(const NotificationOptions& options) {
|
||||
|
||||
if (existing) {
|
||||
existing->tag_.clear();
|
||||
|
||||
this->notification_ref_ = std::move(existing->notification_ref_);
|
||||
this->notification_ref_.Set(options.title, options.msg, image);
|
||||
// Need to remove the entry in the notifications set that
|
||||
// NotificationPresenter is holding
|
||||
existing->Destroy();
|
||||
} else {
|
||||
this->notification_ref_ =
|
||||
presenter->AddNotification(options.title, options.msg, image);
|
||||
|
||||
@@ -112,13 +112,13 @@ class ToastEventHandler : public RuntimeClass<RuntimeClassFlags<ClassicCom>,
|
||||
|
||||
IFACEMETHODIMP Invoke(
|
||||
ABI::Windows::UI::Notifications::IToastNotification* sender,
|
||||
IInspectable* args);
|
||||
IInspectable* args) override;
|
||||
IFACEMETHODIMP Invoke(
|
||||
ABI::Windows::UI::Notifications::IToastNotification* sender,
|
||||
ABI::Windows::UI::Notifications::IToastDismissedEventArgs* e);
|
||||
ABI::Windows::UI::Notifications::IToastDismissedEventArgs* e) override;
|
||||
IFACEMETHODIMP Invoke(
|
||||
ABI::Windows::UI::Notifications::IToastNotification* sender,
|
||||
ABI::Windows::UI::Notifications::IToastFailedEventArgs* e);
|
||||
ABI::Windows::UI::Notifications::IToastFailedEventArgs* e) override;
|
||||
|
||||
private:
|
||||
base::WeakPtr<Notification> notification_; // weak ref.
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "base/callback_helpers.h"
|
||||
#include "base/location.h"
|
||||
#include "base/memory/ptr_util.h"
|
||||
#include "base/optional.h"
|
||||
#include "base/single_thread_task_runner.h"
|
||||
#include "base/task/post_task.h"
|
||||
#include "base/time/time.h"
|
||||
@@ -383,10 +384,10 @@ void OffScreenRenderWidgetHostView::Show() {
|
||||
delegated_frame_host_->AttachToCompositor(compositor_.get());
|
||||
delegated_frame_host_->WasShown(
|
||||
GetLocalSurfaceIdAllocation().local_surface_id(),
|
||||
GetRootLayer()->bounds().size(), false);
|
||||
GetRootLayer()->bounds().size(), base::nullopt);
|
||||
|
||||
if (render_widget_host_)
|
||||
render_widget_host_->WasShown(false);
|
||||
render_widget_host_->WasShown(base::nullopt);
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::Hide() {
|
||||
|
||||
@@ -17,9 +17,9 @@
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>electron.icns</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>6.0.0-beta.3</string>
|
||||
<string>6.0.0-beta.13</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>6.0.0-beta.3</string>
|
||||
<string>6.0.0-beta.13</string>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string>public.app-category.developer-tools</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
|
||||
@@ -50,8 +50,8 @@ END
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 6,0,0,3
|
||||
PRODUCTVERSION 6,0,0,3
|
||||
FILEVERSION 6,0,0,13
|
||||
PRODUCTVERSION 6,0,0,13
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
|
||||
@@ -21,7 +21,7 @@ class AtomNativeWidgetMac : public views::NativeWidgetMac {
|
||||
protected:
|
||||
// NativeWidgetMac:
|
||||
NativeWidgetMacNSWindow* CreateNSWindow(
|
||||
const views_bridge_mac::mojom::CreateWindowParams* params) override;
|
||||
const remote_cocoa::mojom::CreateWindowParams* params) override;
|
||||
|
||||
private:
|
||||
NativeWindowMac* shell_;
|
||||
|
||||
@@ -19,9 +19,9 @@ AtomNativeWidgetMac::AtomNativeWidgetMac(
|
||||
AtomNativeWidgetMac::~AtomNativeWidgetMac() {}
|
||||
|
||||
NativeWidgetMacNSWindow* AtomNativeWidgetMac::CreateNSWindow(
|
||||
const views_bridge_mac::mojom::CreateWindowParams* params) {
|
||||
return [[[AtomNSWindow alloc] initWithShell:shell_ styleMask:style_mask_]
|
||||
autorelease];
|
||||
const remote_cocoa::mojom::CreateWindowParams* params) {
|
||||
return [[[AtomNSWindow alloc] initWithShell:shell_
|
||||
styleMask:style_mask_] autorelease];
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
#define ATOM_BROWSER_UI_COCOA_ATOM_NS_WINDOW_H_
|
||||
|
||||
#include "atom/browser/ui/cocoa/event_dispatching_window.h"
|
||||
#include "components/remote_cocoa/app_shim/native_widget_mac_nswindow.h"
|
||||
#include "ui/views/widget/native_widget_mac.h"
|
||||
#include "ui/views_bridge_mac/native_widget_mac_nswindow.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#include <Quartz/Quartz.h>
|
||||
|
||||
#include "ui/views_bridge_mac/views_nswindow_delegate.h" // nogncheck
|
||||
#include "components/remote_cocoa/app_shim/views_nswindow_delegate.h"
|
||||
|
||||
namespace atom {
|
||||
class NativeWindowMac;
|
||||
|
||||
@@ -9,9 +9,9 @@
|
||||
#include "atom/browser/ui/cocoa/atom_preview_item.h"
|
||||
#include "atom/browser/ui/cocoa/atom_touch_bar.h"
|
||||
#include "base/mac/mac_util.h"
|
||||
#include "components/remote_cocoa/app_shim/bridged_native_widget_impl.h"
|
||||
#include "ui/views/cocoa/bridged_native_widget_host_impl.h"
|
||||
#include "ui/views/widget/native_widget_mac.h"
|
||||
#include "ui/views_bridge_mac/bridged_native_widget_impl.h"
|
||||
|
||||
@implementation AtomNSWindowDelegate
|
||||
|
||||
@@ -84,11 +84,11 @@
|
||||
return frame;
|
||||
}
|
||||
|
||||
- (void)windowDidBecomeMain:(NSNotification*)notification {
|
||||
- (void)windowDidBecomeKey:(NSNotification*)notification {
|
||||
shell_->NotifyWindowFocus();
|
||||
}
|
||||
|
||||
- (void)windowDidResignMain:(NSNotification*)notification {
|
||||
- (void)windowDidResignKey:(NSNotification*)notification {
|
||||
shell_->NotifyWindowBlur();
|
||||
}
|
||||
|
||||
|
||||
@@ -23,9 +23,7 @@ const char kChromeUIDevToolsHost[] = "devtools";
|
||||
const char kChromeUIDevToolsBundledPath[] = "bundled";
|
||||
|
||||
std::string PathWithoutParams(const std::string& path) {
|
||||
return GURL(std::string("chrome-devtools://devtools/") + path)
|
||||
.path()
|
||||
.substr(1);
|
||||
return GURL(std::string("devtools://devtools/") + path).path().substr(1);
|
||||
}
|
||||
|
||||
std::string GetMimeTypeForPath(const std::string& path) {
|
||||
|
||||
@@ -97,7 +97,7 @@ void RunOpenDialogInNewThread(const RunState& run_state,
|
||||
bool result = ShowOpenDialogSync(settings, &paths);
|
||||
run_state.ui_task_runner->PostTask(
|
||||
FROM_HERE,
|
||||
base::BindOnce(&OnDialogOpened, std::move(promise), result, paths));
|
||||
base::BindOnce(&OnDialogOpened, std::move(promise), !result, paths));
|
||||
run_state.ui_task_runner->DeleteSoon(FROM_HERE, run_state.dialog_thread);
|
||||
}
|
||||
|
||||
@@ -117,7 +117,7 @@ void RunSaveDialogInNewThread(const RunState& run_state,
|
||||
bool result = ShowSaveDialogSync(settings, &path);
|
||||
run_state.ui_task_runner->PostTask(
|
||||
FROM_HERE,
|
||||
base::BindOnce(&OnSaveDialogDone, std::move(promise), result, path));
|
||||
base::BindOnce(&OnSaveDialogDone, std::move(promise), !result, path));
|
||||
run_state.ui_task_runner->DeleteSoon(FROM_HERE, run_state.dialog_thread);
|
||||
}
|
||||
|
||||
@@ -320,7 +320,7 @@ void ShowSaveDialog(const DialogSettings& settings,
|
||||
RunState run_state;
|
||||
if (!CreateDialogThread(&run_state)) {
|
||||
mate::Dictionary dict = mate::Dictionary::CreateEmpty(promise.isolate());
|
||||
dict.Set("canceled", false);
|
||||
dict.Set("canceled", true);
|
||||
dict.Set("filePath", base::FilePath());
|
||||
promise.Resolve(dict.GetHandle());
|
||||
} else {
|
||||
|
||||
@@ -25,6 +25,8 @@ namespace atom {
|
||||
class InspectableWebContentsDelegate;
|
||||
class InspectableWebContentsView;
|
||||
|
||||
// TODO(zcbenz): Remove this abstract wrapper and rename
|
||||
// InspectableWebContentsImpl to InspectableWebContents instead.
|
||||
class InspectableWebContents {
|
||||
public:
|
||||
// The returned InspectableWebContents takes ownership of the passed-in
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE-CHROMIUM file.
|
||||
|
||||
#include "atom/browser/ui/inspectable_web_contents_impl.h"
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include "atom/browser/ui/inspectable_web_contents_impl.h"
|
||||
|
||||
#include "atom/browser/ui/inspectable_web_contents_delegate.h"
|
||||
#include "atom/browser/ui/inspectable_web_contents_view.h"
|
||||
#include "atom/browser/ui/inspectable_web_contents_view_delegate.h"
|
||||
@@ -54,14 +54,14 @@ const double kPresetZoomFactors[] = {0.25, 0.333, 0.5, 0.666, 0.75, 0.9,
|
||||
2.5, 3.0, 4.0, 5.0};
|
||||
|
||||
const char kChromeUIDevToolsURL[] =
|
||||
"chrome-devtools://devtools/bundled/devtools_app.html?"
|
||||
"devtools://devtools/bundled/devtools_app.html?"
|
||||
"remoteBase=%s&"
|
||||
"can_dock=%s&"
|
||||
"toolbarColor=rgba(223,223,223,1)&"
|
||||
"textColor=rgba(0,0,0,1)&"
|
||||
"experiments=true";
|
||||
const char kChromeUIDevToolsRemoteFrontendBase[] =
|
||||
"https://chrome-devtools-frontend.appspot.com/";
|
||||
"https://devtools-frontend.appspot.com/";
|
||||
const char kChromeUIDevToolsRemoteFrontendPath[] = "serve_file";
|
||||
|
||||
const char kDevToolsBoundsPref[] = "electron.devtools.bounds";
|
||||
@@ -75,6 +75,9 @@ const char kTitleFormat[] = "Developer Tools - %s";
|
||||
|
||||
const size_t kMaxMessageChunkSize = IPC::Channel::kMaximumMessageSize / 4;
|
||||
|
||||
// Stores all instances of InspectableWebContentsImpl.
|
||||
InspectableWebContentsImpl::List g_web_contents_instances_;
|
||||
|
||||
base::Value RectToDictionary(const gfx::Rect& bounds) {
|
||||
base::Value dict(base::Value::Type::DICTIONARY);
|
||||
dict.SetKey("x", base::Value(bounds.x()));
|
||||
@@ -227,6 +230,12 @@ class InspectableWebContentsImpl::NetworkResourceLoader
|
||||
InspectableWebContentsView* CreateInspectableContentsView(
|
||||
InspectableWebContentsImpl* inspectable_web_contents_impl);
|
||||
|
||||
// static
|
||||
const InspectableWebContentsImpl::List& InspectableWebContentsImpl::GetAll() {
|
||||
return g_web_contents_instances_;
|
||||
}
|
||||
|
||||
// static
|
||||
void InspectableWebContentsImpl::RegisterPrefs(PrefRegistrySimple* registry) {
|
||||
registry->RegisterDictionaryPref(kDevToolsBoundsPref,
|
||||
RectToDictionary(gfx::Rect(0, 0, 800, 600)));
|
||||
@@ -270,9 +279,11 @@ InspectableWebContentsImpl::InspectableWebContentsImpl(
|
||||
display.y() + (display.height() - devtools_bounds_.height()) / 2);
|
||||
}
|
||||
}
|
||||
g_web_contents_instances_.push_back(this);
|
||||
}
|
||||
|
||||
InspectableWebContentsImpl::~InspectableWebContentsImpl() {
|
||||
g_web_contents_instances_.remove(this);
|
||||
// Unsubscribe from devtools and Clean up resources.
|
||||
if (GetDevToolsWebContents()) {
|
||||
if (managed_devtools_web_contents_)
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#ifndef ATOM_BROWSER_UI_INSPECTABLE_WEB_CONTENTS_IMPL_H_
|
||||
#define ATOM_BROWSER_UI_INSPECTABLE_WEB_CONTENTS_IMPL_H_
|
||||
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
@@ -38,6 +39,9 @@ class InspectableWebContentsImpl
|
||||
public content::WebContentsDelegate,
|
||||
public DevToolsEmbedderMessageDispatcher::Delegate {
|
||||
public:
|
||||
using List = std::list<InspectableWebContentsImpl*>;
|
||||
|
||||
static const List& GetAll();
|
||||
static void RegisterPrefs(PrefRegistrySimple* pref_registry);
|
||||
|
||||
InspectableWebContentsImpl(content::WebContents* web_contents,
|
||||
|
||||
@@ -30,6 +30,7 @@ class TrayIconCocoa : public TrayIcon, public AtomMenuModel::Observer {
|
||||
void SetHighlightMode(TrayIcon::HighlightMode mode) override;
|
||||
void SetIgnoreDoubleClickEvents(bool ignore) override;
|
||||
bool GetIgnoreDoubleClickEvents() override;
|
||||
void PopUpOnUI(AtomMenuModel* menu_model);
|
||||
void PopUpContextMenu(const gfx::Point& pos,
|
||||
AtomMenuModel* menu_model) override;
|
||||
void SetContextMenu(AtomMenuModel* menu_model) override;
|
||||
@@ -49,6 +50,8 @@ class TrayIconCocoa : public TrayIcon, public AtomMenuModel::Observer {
|
||||
// Used for unregistering observer.
|
||||
AtomMenuModel* menu_model_ = nullptr; // weak ref.
|
||||
|
||||
base::WeakPtrFactory<TrayIconCocoa> weak_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(TrayIconCocoa);
|
||||
};
|
||||
|
||||
|
||||
@@ -4,9 +4,15 @@
|
||||
|
||||
#include "atom/browser/ui/tray_icon_cocoa.h"
|
||||
|
||||
#include "atom/browser/mac/atom_application.h"
|
||||
#include "atom/browser/ui/cocoa/NSString+ANSI.h"
|
||||
#include "atom/browser/ui/cocoa/atom_menu_controller.h"
|
||||
#include "base/mac/sdk_forward_declarations.h"
|
||||
#include "base/message_loop/message_loop.h"
|
||||
#include "base/strings/sys_string_conversions.h"
|
||||
#include "base/task/post_task.h"
|
||||
#include "content/public/browser/browser_task_traits.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "ui/display/screen.h"
|
||||
#include "ui/events/cocoa/cocoa_event_utils.h"
|
||||
#include "ui/gfx/image/image.h"
|
||||
@@ -143,6 +149,10 @@ const CGFloat kVerticalTitleMargin = 2;
|
||||
}
|
||||
|
||||
- (BOOL)isDarkMode {
|
||||
if (@available(macOS 10.15, *)) {
|
||||
return [[NSApplication sharedApplication].effectiveAppearance.name
|
||||
isEqualToString:NSAppearanceNameDarkAqua];
|
||||
}
|
||||
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
|
||||
NSString* mode = [defaults stringForKey:@"AppleInterfaceStyle"];
|
||||
return mode && [mode isEqualToString:@"Dark"];
|
||||
@@ -324,13 +334,17 @@ const CGFloat kVerticalTitleMargin = 2;
|
||||
}
|
||||
|
||||
- (void)popUpContextMenu:(atom::AtomMenuModel*)menu_model {
|
||||
// Make sure events can be pumped while the menu is up.
|
||||
base::MessageLoopCurrent::ScopedNestableTaskAllower allow;
|
||||
|
||||
// Show a custom menu.
|
||||
if (menu_model) {
|
||||
base::scoped_nsobject<AtomMenuController> menuController([
|
||||
[AtomMenuController alloc] initWithModel:menu_model
|
||||
useDefaultAccelerator:NO]);
|
||||
base::scoped_nsobject<AtomMenuController> menuController(
|
||||
[[AtomMenuController alloc] initWithModel:menu_model
|
||||
useDefaultAccelerator:NO]);
|
||||
forceHighlight_ = YES; // Should highlight when showing menu.
|
||||
[self setNeedsDisplay:YES];
|
||||
|
||||
[statusItem_ popUpStatusItemMenu:[menuController menu]];
|
||||
forceHighlight_ = NO;
|
||||
[self setNeedsDisplay:YES];
|
||||
@@ -338,8 +352,12 @@ const CGFloat kVerticalTitleMargin = 2;
|
||||
}
|
||||
|
||||
if (menuController_ && ![menuController_ isMenuOpen]) {
|
||||
// Ensure the UI can update while the menu is fading out.
|
||||
base::ScopedPumpMessagesInPrivateModes pump_private;
|
||||
|
||||
// Redraw the tray icon to show highlight if it is enabled.
|
||||
[self setNeedsDisplay:YES];
|
||||
|
||||
[statusItem_ popUpStatusItemMenu:[menuController_ menu]];
|
||||
// The popUpStatusItemMenu returns only after the showing menu is closed.
|
||||
// When it returns, we need to redraw the tray icon to not show highlight.
|
||||
@@ -437,7 +455,7 @@ const CGFloat kVerticalTitleMargin = 2;
|
||||
|
||||
namespace atom {
|
||||
|
||||
TrayIconCocoa::TrayIconCocoa() {
|
||||
TrayIconCocoa::TrayIconCocoa() : weak_factory_(this) {
|
||||
status_item_view_.reset([[StatusItemView alloc] initWithIcon:this]);
|
||||
}
|
||||
|
||||
@@ -479,9 +497,16 @@ bool TrayIconCocoa::GetIgnoreDoubleClickEvents() {
|
||||
return [status_item_view_ getIgnoreDoubleClickEvents];
|
||||
}
|
||||
|
||||
void TrayIconCocoa::PopUpOnUI(AtomMenuModel* menu_model) {
|
||||
[status_item_view_ popUpContextMenu:menu_model];
|
||||
}
|
||||
|
||||
void TrayIconCocoa::PopUpContextMenu(const gfx::Point& pos,
|
||||
AtomMenuModel* menu_model) {
|
||||
[status_item_view_ popUpContextMenu:menu_model];
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {content::BrowserThread::UI},
|
||||
base::BindOnce(&TrayIconCocoa::PopUpOnUI, weak_factory_.GetWeakPtr(),
|
||||
base::Unretained(menu_model)));
|
||||
}
|
||||
|
||||
void TrayIconCocoa::SetContextMenu(AtomMenuModel* menu_model) {
|
||||
|
||||
@@ -212,7 +212,7 @@ void InspectableWebContentsViewViews::SetTitle(const base::string16& title) {
|
||||
}
|
||||
|
||||
void InspectableWebContentsViewViews::Layout() {
|
||||
if (!devtools_web_view_->visible()) {
|
||||
if (!devtools_web_view_->GetVisible()) {
|
||||
contents_web_view_->SetBoundsRect(GetContentsBounds());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -286,9 +286,8 @@ void MenuBar::OnMenuButtonClicked(views::Button* source,
|
||||
menu_delegate->AddObserver(this);
|
||||
}
|
||||
|
||||
void MenuBar::RefreshColorCache(const ui::NativeTheme* theme) {
|
||||
if (!theme)
|
||||
theme = ui::NativeTheme::GetInstanceForNativeUi();
|
||||
void MenuBar::RefreshColorCache() {
|
||||
const ui::NativeTheme* theme = GetNativeTheme();
|
||||
if (theme) {
|
||||
#if defined(USE_X11)
|
||||
background_color_ = libgtkui::GetBgColor("GtkMenuBar#menubar");
|
||||
@@ -306,8 +305,8 @@ void MenuBar::RefreshColorCache(const ui::NativeTheme* theme) {
|
||||
#endif
|
||||
}
|
||||
|
||||
void MenuBar::OnNativeThemeChanged(const ui::NativeTheme* theme) {
|
||||
RefreshColorCache(theme);
|
||||
void MenuBar::OnThemeChanged() {
|
||||
RefreshColorCache();
|
||||
UpdateViewColors();
|
||||
}
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@ class MenuBar : public views::AccessiblePaneView,
|
||||
void OnMenuButtonClicked(views::Button* source,
|
||||
const gfx::Point& point,
|
||||
const ui::Event* event) override;
|
||||
void OnNativeThemeChanged(const ui::NativeTheme* theme) override;
|
||||
void OnThemeChanged() override;
|
||||
|
||||
private:
|
||||
friend class MenuBarColorUpdater;
|
||||
@@ -90,7 +90,7 @@ class MenuBar : public views::AccessiblePaneView,
|
||||
void RebuildChildren();
|
||||
void UpdateViewColors();
|
||||
|
||||
void RefreshColorCache(const ui::NativeTheme* theme = nullptr);
|
||||
void RefreshColorCache();
|
||||
SkColor background_color_;
|
||||
#if defined(USE_X11)
|
||||
SkColor enabled_color_;
|
||||
|
||||
@@ -3,18 +3,32 @@
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/ui/win/atom_desktop_native_widget_aura.h"
|
||||
|
||||
#include "atom/browser/ui/win/atom_desktop_window_tree_host_win.h"
|
||||
#include "ui/views/corewm/tooltip_controller.h"
|
||||
#include "ui/wm/public/tooltip_client.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
AtomDesktopNativeWidgetAura::AtomDesktopNativeWidgetAura(
|
||||
views::internal::NativeWidgetDelegate* delegate)
|
||||
: views::DesktopNativeWidgetAura(delegate) {
|
||||
NativeWindowViews* native_window_view)
|
||||
: views::DesktopNativeWidgetAura(native_window_view->widget()),
|
||||
native_window_view_(native_window_view) {
|
||||
GetNativeWindow()->SetName("AtomDesktopNativeWidgetAura");
|
||||
// This is to enable the override of OnWindowActivated
|
||||
wm::SetActivationChangeObserver(GetNativeWindow(), this);
|
||||
}
|
||||
|
||||
void AtomDesktopNativeWidgetAura::InitNativeWidget(
|
||||
const views::Widget::InitParams& params) {
|
||||
views::Widget::InitParams modified_params = params;
|
||||
desktop_window_tree_host_ = new AtomDesktopWindowTreeHostWin(
|
||||
native_window_view_,
|
||||
static_cast<views::DesktopNativeWidgetAura*>(params.native_widget));
|
||||
modified_params.desktop_window_tree_host = desktop_window_tree_host_;
|
||||
views::DesktopNativeWidgetAura::InitNativeWidget(modified_params);
|
||||
}
|
||||
|
||||
void AtomDesktopNativeWidgetAura::Activate() {
|
||||
// Activate can cause the focused window to be blurred so only
|
||||
// call when the window being activated is visible. This prevents
|
||||
|
||||
@@ -8,12 +8,18 @@
|
||||
#include "atom/browser/native_window_views.h"
|
||||
#include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
|
||||
|
||||
namespace views {
|
||||
class DesktopWindowTreeHost;
|
||||
}
|
||||
|
||||
namespace atom {
|
||||
|
||||
class AtomDesktopNativeWidgetAura : public views::DesktopNativeWidgetAura {
|
||||
public:
|
||||
explicit AtomDesktopNativeWidgetAura(
|
||||
views::internal::NativeWidgetDelegate* delegate);
|
||||
explicit AtomDesktopNativeWidgetAura(NativeWindowViews* native_window_view);
|
||||
|
||||
// views::DesktopNativeWidgetAura:
|
||||
void InitNativeWidget(const views::Widget::InitParams& params) override;
|
||||
|
||||
// internal::NativeWidgetPrivate:
|
||||
void Activate() override;
|
||||
@@ -22,6 +28,12 @@ class AtomDesktopNativeWidgetAura : public views::DesktopNativeWidgetAura {
|
||||
void OnWindowActivated(wm::ActivationChangeObserver::ActivationReason reason,
|
||||
aura::Window* gained_active,
|
||||
aura::Window* lost_active) override;
|
||||
|
||||
NativeWindowViews* native_window_view_;
|
||||
|
||||
// Owned by DesktopNativeWidgetAura.
|
||||
views::DesktopWindowTreeHost* desktop_window_tree_host_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomDesktopNativeWidgetAura);
|
||||
};
|
||||
|
||||
|
||||
@@ -4,17 +4,14 @@
|
||||
|
||||
#include "atom/browser/ui/win/atom_desktop_window_tree_host_win.h"
|
||||
|
||||
#include "atom/browser/ui/win/message_handler_delegate.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
AtomDesktopWindowTreeHostWin::AtomDesktopWindowTreeHostWin(
|
||||
MessageHandlerDelegate* delegate,
|
||||
views::internal::NativeWidgetDelegate* native_widget_delegate,
|
||||
NativeWindowViews* native_window_view,
|
||||
views::DesktopNativeWidgetAura* desktop_native_widget_aura)
|
||||
: views::DesktopWindowTreeHostWin(native_widget_delegate,
|
||||
: views::DesktopWindowTreeHostWin(native_window_view->widget(),
|
||||
desktop_native_widget_aura),
|
||||
delegate_(delegate) {}
|
||||
native_window_view_(native_window_view) {}
|
||||
|
||||
AtomDesktopWindowTreeHostWin::~AtomDesktopWindowTreeHostWin() {}
|
||||
|
||||
@@ -22,7 +19,7 @@ bool AtomDesktopWindowTreeHostWin::PreHandleMSG(UINT message,
|
||||
WPARAM w_param,
|
||||
LPARAM l_param,
|
||||
LRESULT* result) {
|
||||
return delegate_->PreHandleMSG(message, w_param, l_param, result);
|
||||
return native_window_view_->PreHandleMSG(message, w_param, l_param, result);
|
||||
}
|
||||
|
||||
bool AtomDesktopWindowTreeHostWin::HasNativeFrame() const {
|
||||
|
||||
@@ -7,20 +7,15 @@
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "atom/browser/native_window.h"
|
||||
#include "atom/browser/native_window_views.h"
|
||||
#include "ui/views/widget/desktop_aura/desktop_window_tree_host_win.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
class MessageHandlerDelegate;
|
||||
|
||||
class AtomDesktopWindowTreeHostWin : public views::DesktopWindowTreeHostWin {
|
||||
public:
|
||||
AtomDesktopWindowTreeHostWin(
|
||||
MessageHandlerDelegate* delegate,
|
||||
views::internal::NativeWidgetDelegate* native_widget_delegate,
|
||||
NativeWindowViews* native_window_view,
|
||||
views::DesktopNativeWidgetAura* desktop_native_widget_aura);
|
||||
~AtomDesktopWindowTreeHostWin() override;
|
||||
|
||||
@@ -32,7 +27,7 @@ class AtomDesktopWindowTreeHostWin : public views::DesktopWindowTreeHostWin {
|
||||
bool HasNativeFrame() const override;
|
||||
|
||||
private:
|
||||
MessageHandlerDelegate* delegate_; // weak ref
|
||||
NativeWindowViews* native_window_view_; // weak ref
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomDesktopWindowTreeHostWin);
|
||||
};
|
||||
|
||||
@@ -23,6 +23,7 @@ bool AppendTask(const JumpListItem& item, IObjectCollection* collection) {
|
||||
if (FAILED(link.CoCreateInstance(CLSID_ShellLink)) ||
|
||||
FAILED(link->SetPath(item.path.value().c_str())) ||
|
||||
FAILED(link->SetArguments(item.arguments.c_str())) ||
|
||||
FAILED(link->SetWorkingDirectory(item.working_dir.value().c_str())) ||
|
||||
FAILED(link->SetDescription(item.description.c_str())))
|
||||
return false;
|
||||
|
||||
@@ -86,6 +87,8 @@ bool ConvertShellLinkToJumpListItem(IShellLink* shell_link,
|
||||
if (FAILED(shell_link->GetPath(path, MAX_PATH, nullptr, 0)))
|
||||
return false;
|
||||
|
||||
item->path = base::FilePath(path);
|
||||
|
||||
CComQIPtr<IPropertyStore> property_store = shell_link;
|
||||
base::win::ScopedPropVariant prop;
|
||||
if (SUCCEEDED(
|
||||
@@ -99,6 +102,9 @@ bool ConvertShellLinkToJumpListItem(IShellLink* shell_link,
|
||||
item->title = prop.get().pwszVal;
|
||||
}
|
||||
|
||||
if (SUCCEEDED(shell_link->GetWorkingDirectory(path, base::size(path))))
|
||||
item->working_dir = base::FilePath(path);
|
||||
|
||||
int icon_index;
|
||||
if (SUCCEEDED(shell_link->GetIconLocation(path, MAX_PATH, &icon_index))) {
|
||||
item->icon_path = base::FilePath(path);
|
||||
|
||||
@@ -49,6 +49,7 @@ struct JumpListItem {
|
||||
base::string16 arguments;
|
||||
base::string16 title;
|
||||
base::string16 description;
|
||||
base::FilePath working_dir;
|
||||
base::FilePath icon_path;
|
||||
int icon_index = 0;
|
||||
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
// Copyright (c) 2015 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/ui/win/message_handler_delegate.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
bool MessageHandlerDelegate::PreHandleMSG(UINT message,
|
||||
WPARAM w_param,
|
||||
LPARAM l_param,
|
||||
LRESULT* result) {
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
@@ -1,28 +0,0 @@
|
||||
// Copyright (c) 2015 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_UI_WIN_MESSAGE_HANDLER_DELEGATE_H_
|
||||
#define ATOM_BROWSER_UI_WIN_MESSAGE_HANDLER_DELEGATE_H_
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
namespace atom {
|
||||
|
||||
class MessageHandlerDelegate {
|
||||
public:
|
||||
// Catch-all message handling and filtering. Called before
|
||||
// HWNDMessageHandler's built-in handling, which may pre-empt some
|
||||
// expectations in Views/Aura if messages are consumed. Returns true if the
|
||||
// message was consumed by the delegate and should not be processed further
|
||||
// by the HWNDMessageHandler. In this case, |result| is returned. |result| is
|
||||
// not modified otherwise.
|
||||
virtual bool PreHandleMSG(UINT message,
|
||||
WPARAM w_param,
|
||||
LPARAM l_param,
|
||||
LRESULT* result);
|
||||
};
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_UI_WIN_MESSAGE_HANDLER_DELEGATE_H_
|
||||
@@ -147,6 +147,8 @@ WebContentsPreferences::WebContentsPreferences(
|
||||
#endif
|
||||
SetDefaultBoolIfUndefined(options::kOffscreen, false);
|
||||
|
||||
SetDefaults();
|
||||
|
||||
// If this is a <webview> tag, and the embedder is offscreen-rendered, then
|
||||
// this WebContents is also offscreen-rendered.
|
||||
int guest_instance_id = 0;
|
||||
@@ -172,6 +174,12 @@ WebContentsPreferences::~WebContentsPreferences() {
|
||||
instances_.end());
|
||||
}
|
||||
|
||||
void WebContentsPreferences::SetDefaults() {
|
||||
if (IsEnabled(options::kSandbox)) {
|
||||
SetBool(options::kNativeWindowOpen, true);
|
||||
}
|
||||
}
|
||||
|
||||
bool WebContentsPreferences::SetDefaultBoolIfUndefined(
|
||||
const base::StringPiece& key,
|
||||
bool val) {
|
||||
@@ -185,6 +193,10 @@ bool WebContentsPreferences::SetDefaultBoolIfUndefined(
|
||||
}
|
||||
}
|
||||
|
||||
void WebContentsPreferences::SetBool(const base::StringPiece& key, bool value) {
|
||||
preference_.SetKey(key, base::Value(value));
|
||||
}
|
||||
|
||||
bool WebContentsPreferences::IsEnabled(const base::StringPiece& name,
|
||||
bool default_value) const {
|
||||
auto* current_value =
|
||||
@@ -197,6 +209,8 @@ bool WebContentsPreferences::IsEnabled(const base::StringPiece& name,
|
||||
void WebContentsPreferences::Merge(const base::DictionaryValue& extend) {
|
||||
if (preference_.is_dict())
|
||||
static_cast<base::DictionaryValue*>(&preference_)->MergeDictionary(&extend);
|
||||
|
||||
SetDefaults();
|
||||
}
|
||||
|
||||
void WebContentsPreferences::Clear() {
|
||||
|
||||
@@ -36,6 +36,9 @@ class WebContentsPreferences
|
||||
const mate::Dictionary& web_preferences);
|
||||
~WebContentsPreferences() override;
|
||||
|
||||
// Set WebPreferences defaults onto the JS object.
|
||||
void SetDefaults();
|
||||
|
||||
// A simple way to know whether a Boolean property is enabled.
|
||||
bool IsEnabled(const base::StringPiece& name,
|
||||
bool default_value = false) const;
|
||||
@@ -75,6 +78,9 @@ class WebContentsPreferences
|
||||
// Set preference value to given bool if user did not provide value
|
||||
bool SetDefaultBoolIfUndefined(const base::StringPiece& key, bool val);
|
||||
|
||||
// Set preference value to given bool
|
||||
void SetBool(const base::StringPiece& key, bool value);
|
||||
|
||||
static std::vector<WebContentsPreferences*> instances_;
|
||||
|
||||
content::WebContents* web_contents_;
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "content/public/browser/render_view_host.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
#include "content/public/browser/web_contents_observer.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "net/base/mime_util.h"
|
||||
#include "ui/shell_dialogs/selected_file_info.h"
|
||||
|
||||
@@ -51,9 +52,10 @@ class FileSelectHelper : public base::RefCounted<FileSelectHelper>,
|
||||
v8::Isolate* isolate = v8::Isolate::GetCurrent();
|
||||
atom::util::Promise promise(isolate);
|
||||
|
||||
file_dialog::ShowOpenDialog(settings, std::move(promise));
|
||||
auto callback = base::Bind(&FileSelectHelper::OnOpenDialogDone, this);
|
||||
ignore_result(promise.Then(callback));
|
||||
|
||||
file_dialog::ShowOpenDialog(settings, std::move(promise));
|
||||
}
|
||||
|
||||
void ShowSaveDialog(const file_dialog::DialogSettings& settings) {
|
||||
@@ -74,45 +76,43 @@ class FileSelectHelper : public base::RefCounted<FileSelectHelper>,
|
||||
|
||||
~FileSelectHelper() override {}
|
||||
|
||||
#if defined(MAS_BUILD)
|
||||
void OnOpenDialogDone(bool result,
|
||||
const std::vector<base::FilePath>& paths,
|
||||
const std::vector<std::string>& bookmarks)
|
||||
#else
|
||||
void OnOpenDialogDone(bool result, const std::vector<base::FilePath>& paths)
|
||||
#endif
|
||||
{
|
||||
void OnOpenDialogDone(mate::Dictionary result) {
|
||||
std::vector<FileChooserFileInfoPtr> file_info;
|
||||
if (result) {
|
||||
for (auto& path : paths) {
|
||||
file_info.push_back(FileChooserFileInfo::NewNativeFile(
|
||||
blink::mojom::NativeFileInfo::New(
|
||||
path, path.BaseName().AsUTF16Unsafe())));
|
||||
}
|
||||
bool canceled = true;
|
||||
result.Get("canceled", &canceled);
|
||||
|
||||
if (render_frame_host_ && !paths.empty()) {
|
||||
auto* browser_context = static_cast<atom::AtomBrowserContext*>(
|
||||
render_frame_host_->GetProcess()->GetBrowserContext());
|
||||
browser_context->prefs()->SetFilePath(prefs::kSelectFileLastDirectory,
|
||||
paths[0].DirName());
|
||||
if (!canceled) {
|
||||
std::vector<base::FilePath> paths;
|
||||
if (result.Get("filePaths", &paths)) {
|
||||
for (auto& path : paths) {
|
||||
file_info.push_back(FileChooserFileInfo::NewNativeFile(
|
||||
blink::mojom::NativeFileInfo::New(
|
||||
path, path.BaseName().AsUTF16Unsafe())));
|
||||
}
|
||||
|
||||
if (render_frame_host_ && !paths.empty()) {
|
||||
auto* browser_context = static_cast<atom::AtomBrowserContext*>(
|
||||
render_frame_host_->GetProcess()->GetBrowserContext());
|
||||
browser_context->prefs()->SetFilePath(prefs::kSelectFileLastDirectory,
|
||||
paths[0].DirName());
|
||||
}
|
||||
}
|
||||
}
|
||||
OnFilesSelected(std::move(file_info));
|
||||
}
|
||||
|
||||
#if defined(MAS_BUILD)
|
||||
void OnSaveDialogDone(bool result,
|
||||
const base::FilePath& path,
|
||||
const std::string& bookmark)
|
||||
#else
|
||||
void OnSaveDialogDone(bool result, const base::FilePath& path)
|
||||
#endif
|
||||
{
|
||||
void OnSaveDialogDone(mate::Dictionary result) {
|
||||
std::vector<FileChooserFileInfoPtr> file_info;
|
||||
if (result) {
|
||||
file_info.push_back(
|
||||
FileChooserFileInfo::NewNativeFile(blink::mojom::NativeFileInfo::New(
|
||||
path, path.BaseName().AsUTF16Unsafe())));
|
||||
bool canceled = true;
|
||||
result.Get("canceled", &canceled);
|
||||
|
||||
if (!canceled) {
|
||||
base::FilePath path;
|
||||
if (result.Get("filePath", &path)) {
|
||||
file_info.push_back(FileChooserFileInfo::NewNativeFile(
|
||||
blink::mojom::NativeFileInfo::New(
|
||||
path, path.BaseName().AsUTF16Unsafe())));
|
||||
}
|
||||
}
|
||||
OnFilesSelected(std::move(file_info));
|
||||
}
|
||||
@@ -123,7 +123,6 @@ class FileSelectHelper : public base::RefCounted<FileSelectHelper>,
|
||||
listener_.reset();
|
||||
}
|
||||
render_frame_host_ = nullptr;
|
||||
Release();
|
||||
}
|
||||
|
||||
// content::WebContentsObserver:
|
||||
|
||||
@@ -10,6 +10,8 @@ interface ElectronRenderer {
|
||||
mojo_base.mojom.ListValue arguments,
|
||||
int32 sender_id);
|
||||
|
||||
UpdateCrashpadPipeName(string pipe_name);
|
||||
|
||||
TakeHeapSnapshot(handle file) => (bool success);
|
||||
};
|
||||
|
||||
|
||||
@@ -27,6 +27,14 @@ const char kSecureProtocolDescription[] =
|
||||
"The connection to this site is using a strong protocol version "
|
||||
"and cipher suite.";
|
||||
|
||||
#if defined(OS_WIN)
|
||||
const char kCrashpadPipeName[] = "ELECTRON_CRASHPAD_PIPE_NAME";
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(ENABLE_RUN_AS_NODE)
|
||||
const char kRunAsNode[] = "ELECTRON_RUN_AS_NODE";
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(ENABLE_PDF_VIEWER)
|
||||
const char kPdfPluginMimeType[] = "application/x-google-chrome-pdf";
|
||||
const char kPdfPluginPath[] = "chrome://pdf-viewer/";
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#ifndef ATOM_COMMON_ATOM_CONSTANTS_H_
|
||||
#define ATOM_COMMON_ATOM_CONSTANTS_H_
|
||||
|
||||
#include "build/build_config.h"
|
||||
#include "electron/buildflags/buildflags.h"
|
||||
|
||||
namespace atom {
|
||||
@@ -26,6 +27,15 @@ extern const char kValidCertificateDescription[];
|
||||
extern const char kSecureProtocol[];
|
||||
extern const char kSecureProtocolDescription[];
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// Crashpad pipe name.
|
||||
extern const char kCrashpadPipeName[];
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(ENABLE_RUN_AS_NODE)
|
||||
extern const char kRunAsNode[];
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(ENABLE_PDF_VIEWER)
|
||||
// The MIME type used for the PDF plugin.
|
||||
extern const char kPdfPluginMimeType[];
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#define ATOM_MINOR_VERSION 0
|
||||
#define ATOM_PATCH_VERSION 0
|
||||
// clang-format off
|
||||
#define ATOM_PRE_RELEASE_VERSION -beta.3
|
||||
#define ATOM_PRE_RELEASE_VERSION -beta.13
|
||||
// clang-format on
|
||||
|
||||
#ifndef ATOM_STRINGIFY
|
||||
|
||||
@@ -4,10 +4,14 @@
|
||||
|
||||
#include "atom/common/crash_reporter/crash_reporter.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/common/atom_constants.h"
|
||||
#include "atom/common/atom_version.h"
|
||||
#include "atom/common/native_mate_converters/file_path_converter.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/environment.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "base/strings/string_split.h"
|
||||
@@ -16,13 +20,31 @@
|
||||
|
||||
namespace crash_reporter {
|
||||
|
||||
const char kCrashpadProcess[] = "crash-handler";
|
||||
const char kCrashesDirectoryKey[] = "crashes-directory";
|
||||
|
||||
CrashReporter::CrashReporter() {
|
||||
auto* cmd = base::CommandLine::ForCurrentProcess();
|
||||
is_browser_ = cmd->GetSwitchValueASCII(switches::kProcessType).empty();
|
||||
#if BUILDFLAG(ENABLE_RUN_AS_NODE)
|
||||
bool run_as_node = base::Environment::Create()->HasVar(atom::kRunAsNode);
|
||||
#else
|
||||
bool run_as_node = false;
|
||||
#endif
|
||||
|
||||
if (run_as_node) {
|
||||
process_type_ = "node";
|
||||
} else {
|
||||
auto* cmd = base::CommandLine::ForCurrentProcess();
|
||||
process_type_ = cmd->GetSwitchValueASCII(switches::kProcessType);
|
||||
}
|
||||
// process_type_ will be empty for browser process
|
||||
}
|
||||
|
||||
CrashReporter::~CrashReporter() {}
|
||||
|
||||
bool CrashReporter::IsInitialized() {
|
||||
return is_initialized_;
|
||||
}
|
||||
|
||||
void CrashReporter::Start(const std::string& product_name,
|
||||
const std::string& company_name,
|
||||
const std::string& submit_url,
|
||||
@@ -30,15 +52,19 @@ void CrashReporter::Start(const std::string& product_name,
|
||||
bool upload_to_server,
|
||||
bool skip_system_crash_handler,
|
||||
const StringMap& extra_parameters) {
|
||||
is_initialized_ = true;
|
||||
SetUploadParameters(extra_parameters);
|
||||
|
||||
InitBreakpad(product_name, ATOM_VERSION_STRING, company_name, submit_url,
|
||||
crashes_dir, upload_to_server, skip_system_crash_handler);
|
||||
Init(product_name, company_name, submit_url, crashes_dir, upload_to_server,
|
||||
skip_system_crash_handler);
|
||||
}
|
||||
|
||||
void CrashReporter::SetUploadParameters(const StringMap& parameters) {
|
||||
upload_parameters_ = parameters;
|
||||
upload_parameters_["process_type"] = is_browser_ ? "browser" : "renderer";
|
||||
upload_parameters_["process_type"] =
|
||||
process_type_.empty() ? "browser" : process_type_;
|
||||
upload_parameters_["prod"] = ATOM_PRODUCT_NAME;
|
||||
upload_parameters_["ver"] = ATOM_VERSION_STRING;
|
||||
|
||||
// Setting platform dependent parameters.
|
||||
SetUploadParameters();
|
||||
@@ -74,13 +100,12 @@ CrashReporter::GetUploadedReports(const base::FilePath& crashes_dir) {
|
||||
return result;
|
||||
}
|
||||
|
||||
void CrashReporter::InitBreakpad(const std::string& product_name,
|
||||
const std::string& version,
|
||||
const std::string& company_name,
|
||||
const std::string& submit_url,
|
||||
const base::FilePath& crashes_dir,
|
||||
bool auto_submit,
|
||||
bool skip_system_crash_handler) {}
|
||||
void CrashReporter::Init(const std::string& product_name,
|
||||
const std::string& company_name,
|
||||
const std::string& submit_url,
|
||||
const base::FilePath& crashes_dir,
|
||||
bool auto_submit,
|
||||
bool skip_system_crash_handler) {}
|
||||
|
||||
void CrashReporter::SetUploadParameters() {}
|
||||
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
|
||||
namespace crash_reporter {
|
||||
|
||||
extern const char kCrashpadProcess[];
|
||||
extern const char kCrashesDirectoryKey[];
|
||||
|
||||
class CrashReporter {
|
||||
public:
|
||||
typedef std::map<std::string, std::string> StringMap;
|
||||
@@ -24,6 +27,7 @@ class CrashReporter {
|
||||
static CrashReporter* GetInstance();
|
||||
static void StartInstance(const mate::Dictionary& options);
|
||||
|
||||
bool IsInitialized();
|
||||
void Start(const std::string& product_name,
|
||||
const std::string& company_name,
|
||||
const std::string& submit_url,
|
||||
@@ -46,19 +50,19 @@ class CrashReporter {
|
||||
CrashReporter();
|
||||
virtual ~CrashReporter();
|
||||
|
||||
virtual void InitBreakpad(const std::string& product_name,
|
||||
const std::string& version,
|
||||
const std::string& company_name,
|
||||
const std::string& submit_url,
|
||||
const base::FilePath& crashes_dir,
|
||||
bool upload_to_server,
|
||||
bool skip_system_crash_handler);
|
||||
virtual void Init(const std::string& product_name,
|
||||
const std::string& company_name,
|
||||
const std::string& submit_url,
|
||||
const base::FilePath& crashes_dir,
|
||||
bool upload_to_server,
|
||||
bool skip_system_crash_handler);
|
||||
virtual void SetUploadParameters();
|
||||
|
||||
StringMap upload_parameters_;
|
||||
bool is_browser_;
|
||||
std::string process_type_;
|
||||
|
||||
private:
|
||||
bool is_initialized_ = false;
|
||||
void SetUploadParameters(const StringMap& parameters);
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CrashReporter);
|
||||
|
||||
118
atom/common/crash_reporter/crash_reporter_crashpad.cc
Normal file
118
atom/common/crash_reporter/crash_reporter_crashpad.cc
Normal file
@@ -0,0 +1,118 @@
|
||||
// Copyright (c) 2019 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/common/crash_reporter/crash_reporter_crashpad.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/strings/string_piece.h"
|
||||
#include "base/strings/stringprintf.h"
|
||||
#include "base/strings/sys_string_conversions.h"
|
||||
#include "base/threading/thread_restrictions.h"
|
||||
#include "third_party/crashpad/crashpad/client/settings.h"
|
||||
|
||||
namespace crash_reporter {
|
||||
|
||||
CrashReporterCrashpad::CrashReporterCrashpad() {}
|
||||
|
||||
CrashReporterCrashpad::~CrashReporterCrashpad() {}
|
||||
|
||||
bool CrashReporterCrashpad::GetUploadToServer() {
|
||||
bool enabled = true;
|
||||
if (database_) {
|
||||
database_->GetSettings()->GetUploadsEnabled(&enabled);
|
||||
}
|
||||
return enabled;
|
||||
}
|
||||
|
||||
void CrashReporterCrashpad::SetUploadToServer(const bool upload_to_server) {
|
||||
if (database_) {
|
||||
database_->GetSettings()->SetUploadsEnabled(upload_to_server);
|
||||
}
|
||||
}
|
||||
|
||||
void CrashReporterCrashpad::SetCrashKeyValue(const base::StringPiece& key,
|
||||
const base::StringPiece& value) {
|
||||
simple_string_dictionary_->SetKeyValue(key.data(), value.data());
|
||||
}
|
||||
|
||||
void CrashReporterCrashpad::SetInitialCrashKeyValues() {
|
||||
for (const auto& upload_parameter : upload_parameters_)
|
||||
SetCrashKeyValue(upload_parameter.first, upload_parameter.second);
|
||||
}
|
||||
|
||||
void CrashReporterCrashpad::AddExtraParameter(const std::string& key,
|
||||
const std::string& value) {
|
||||
if (simple_string_dictionary_) {
|
||||
SetCrashKeyValue(key, value);
|
||||
} else {
|
||||
upload_parameters_[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
void CrashReporterCrashpad::RemoveExtraParameter(const std::string& key) {
|
||||
if (simple_string_dictionary_)
|
||||
simple_string_dictionary_->RemoveKey(key.data());
|
||||
else
|
||||
upload_parameters_.erase(key);
|
||||
}
|
||||
|
||||
std::map<std::string, std::string> CrashReporterCrashpad::GetParameters()
|
||||
const {
|
||||
if (simple_string_dictionary_) {
|
||||
std::map<std::string, std::string> ret;
|
||||
crashpad::SimpleStringDictionary::Iterator iter(*simple_string_dictionary_);
|
||||
for (;;) {
|
||||
auto* const entry = iter.Next();
|
||||
if (!entry)
|
||||
break;
|
||||
ret[entry->key] = entry->value;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
return upload_parameters_;
|
||||
}
|
||||
|
||||
std::vector<CrashReporter::UploadReportResult>
|
||||
CrashReporterCrashpad::GetUploadedReports(const base::FilePath& crashes_dir) {
|
||||
std::vector<CrashReporter::UploadReportResult> uploaded_reports;
|
||||
|
||||
{
|
||||
base::ThreadRestrictions::ScopedAllowIO allow_io;
|
||||
if (!base::PathExists(crashes_dir)) {
|
||||
return uploaded_reports;
|
||||
}
|
||||
}
|
||||
// Load crashpad database.
|
||||
std::unique_ptr<crashpad::CrashReportDatabase> database =
|
||||
crashpad::CrashReportDatabase::Initialize(crashes_dir);
|
||||
DCHECK(database);
|
||||
|
||||
std::vector<crashpad::CrashReportDatabase::Report> completed_reports;
|
||||
crashpad::CrashReportDatabase::OperationStatus status =
|
||||
database->GetCompletedReports(&completed_reports);
|
||||
if (status != crashpad::CrashReportDatabase::kNoError) {
|
||||
return uploaded_reports;
|
||||
}
|
||||
|
||||
for (const crashpad::CrashReportDatabase::Report& completed_report :
|
||||
completed_reports) {
|
||||
if (completed_report.uploaded) {
|
||||
uploaded_reports.push_back(
|
||||
UploadReportResult(static_cast<int>(completed_report.creation_time),
|
||||
completed_report.id));
|
||||
}
|
||||
}
|
||||
|
||||
auto sort_by_time = [](const UploadReportResult& a,
|
||||
const UploadReportResult& b) {
|
||||
return a.first >= b.first;
|
||||
};
|
||||
std::sort(uploaded_reports.begin(), uploaded_reports.end(), sort_by_time);
|
||||
return uploaded_reports;
|
||||
}
|
||||
|
||||
} // namespace crash_reporter
|
||||
50
atom/common/crash_reporter/crash_reporter_crashpad.h
Normal file
50
atom/common/crash_reporter/crash_reporter_crashpad.h
Normal file
@@ -0,0 +1,50 @@
|
||||
// Copyright (c) 2013 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_COMMON_CRASH_REPORTER_CRASH_REPORTER_CRASHPAD_H_
|
||||
#define ATOM_COMMON_CRASH_REPORTER_CRASH_REPORTER_CRASHPAD_H_
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/common/crash_reporter/crash_reporter.h"
|
||||
#include "base/compiler_specific.h"
|
||||
#include "base/strings/string_piece.h"
|
||||
#include "third_party/crashpad/crashpad/client/crash_report_database.h"
|
||||
#include "third_party/crashpad/crashpad/client/simple_string_dictionary.h"
|
||||
|
||||
namespace crash_reporter {
|
||||
|
||||
class CrashReporterCrashpad : public CrashReporter {
|
||||
public:
|
||||
void SetUploadToServer(bool upload_to_server) override;
|
||||
bool GetUploadToServer() override;
|
||||
void AddExtraParameter(const std::string& key,
|
||||
const std::string& value) override;
|
||||
void RemoveExtraParameter(const std::string& key) override;
|
||||
std::map<std::string, std::string> GetParameters() const override;
|
||||
|
||||
protected:
|
||||
CrashReporterCrashpad();
|
||||
~CrashReporterCrashpad() override;
|
||||
|
||||
void SetUploadsEnabled(bool enable_uploads);
|
||||
void SetCrashKeyValue(const base::StringPiece& key,
|
||||
const base::StringPiece& value);
|
||||
void SetInitialCrashKeyValues();
|
||||
|
||||
std::vector<UploadReportResult> GetUploadedReports(
|
||||
const base::FilePath& crashes_dir) override;
|
||||
|
||||
std::unique_ptr<crashpad::SimpleStringDictionary> simple_string_dictionary_;
|
||||
std::unique_ptr<crashpad::CrashReportDatabase> database_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CrashReporterCrashpad);
|
||||
};
|
||||
|
||||
} // namespace crash_reporter
|
||||
|
||||
#endif // ATOM_COMMON_CRASH_REPORTER_CRASH_REPORTER_CRASHPAD_H_
|
||||
@@ -51,22 +51,18 @@ CrashReporterLinux::CrashReporterLinux() : pid_(getpid()) {
|
||||
|
||||
CrashReporterLinux::~CrashReporterLinux() {}
|
||||
|
||||
void CrashReporterLinux::InitBreakpad(const std::string& product_name,
|
||||
const std::string& version,
|
||||
const std::string& company_name,
|
||||
const std::string& submit_url,
|
||||
const base::FilePath& crashes_dir,
|
||||
bool upload_to_server,
|
||||
bool skip_system_crash_handler) {
|
||||
void CrashReporterLinux::Init(const std::string& product_name,
|
||||
const std::string& company_name,
|
||||
const std::string& submit_url,
|
||||
const base::FilePath& crashes_dir,
|
||||
bool upload_to_server,
|
||||
bool skip_system_crash_handler) {
|
||||
EnableCrashDumping(crashes_dir);
|
||||
|
||||
crash_keys_.reset(new CrashKeyStorage());
|
||||
|
||||
crash_keys_->SetKeyValue("prod", ATOM_PRODUCT_NAME);
|
||||
crash_keys_->SetKeyValue("ver", version.c_str());
|
||||
upload_url_ = submit_url;
|
||||
upload_to_server_ = upload_to_server;
|
||||
|
||||
crash_keys_.reset(new CrashKeyStorage());
|
||||
for (StringMap::const_iterator iter = upload_parameters_.begin();
|
||||
iter != upload_parameters_.end(); ++iter)
|
||||
crash_keys_->SetKeyValue(iter->first.c_str(), iter->second.c_str());
|
||||
|
||||
@@ -28,13 +28,12 @@ class CrashReporterLinux : public CrashReporter {
|
||||
public:
|
||||
static CrashReporterLinux* GetInstance();
|
||||
|
||||
void InitBreakpad(const std::string& product_name,
|
||||
const std::string& version,
|
||||
const std::string& company_name,
|
||||
const std::string& submit_url,
|
||||
const base::FilePath& crashes_dir,
|
||||
bool upload_to_server,
|
||||
bool skip_system_crash_handler) override;
|
||||
void Init(const std::string& product_name,
|
||||
const std::string& company_name,
|
||||
const std::string& submit_url,
|
||||
const base::FilePath& crashes_dir,
|
||||
bool upload_to_server,
|
||||
bool skip_system_crash_handler) override;
|
||||
void SetUploadToServer(bool upload_to_server) override;
|
||||
void SetUploadParameters() override;
|
||||
bool GetUploadToServer() override;
|
||||
|
||||
@@ -5,16 +5,10 @@
|
||||
#ifndef ATOM_COMMON_CRASH_REPORTER_CRASH_REPORTER_MAC_H_
|
||||
#define ATOM_COMMON_CRASH_REPORTER_CRASH_REPORTER_MAC_H_
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/common/crash_reporter/crash_reporter.h"
|
||||
#include "base/compiler_specific.h"
|
||||
#include "base/strings/string_piece.h"
|
||||
#include "crashpad/client/crash_report_database.h"
|
||||
#include "crashpad/client/simple_string_dictionary.h"
|
||||
#include "atom/common/crash_reporter/crash_reporter_crashpad.h"
|
||||
|
||||
namespace base {
|
||||
template <typename T>
|
||||
@@ -23,24 +17,17 @@ struct DefaultSingletonTraits;
|
||||
|
||||
namespace crash_reporter {
|
||||
|
||||
class CrashReporterMac : public CrashReporter {
|
||||
class CrashReporterMac : public CrashReporterCrashpad {
|
||||
public:
|
||||
static CrashReporterMac* GetInstance();
|
||||
|
||||
void InitBreakpad(const std::string& product_name,
|
||||
const std::string& version,
|
||||
const std::string& company_name,
|
||||
const std::string& submit_url,
|
||||
const base::FilePath& crashes_dir,
|
||||
bool upload_to_server,
|
||||
bool skip_system_crash_handler) override;
|
||||
void Init(const std::string& product_name,
|
||||
const std::string& company_name,
|
||||
const std::string& submit_url,
|
||||
const base::FilePath& crashes_dir,
|
||||
bool upload_to_server,
|
||||
bool skip_system_crash_handler) override;
|
||||
void SetUploadParameters() override;
|
||||
void SetUploadToServer(bool upload_to_server) override;
|
||||
bool GetUploadToServer() override;
|
||||
void AddExtraParameter(const std::string& key,
|
||||
const std::string& value) override;
|
||||
void RemoveExtraParameter(const std::string& key) override;
|
||||
std::map<std::string, std::string> GetParameters() const override;
|
||||
|
||||
private:
|
||||
friend struct base::DefaultSingletonTraits<CrashReporterMac>;
|
||||
@@ -48,16 +35,6 @@ class CrashReporterMac : public CrashReporter {
|
||||
CrashReporterMac();
|
||||
~CrashReporterMac() override;
|
||||
|
||||
void SetUploadsEnabled(bool enable_uploads);
|
||||
void SetCrashKeyValue(const base::StringPiece& key,
|
||||
const base::StringPiece& value);
|
||||
|
||||
std::vector<UploadReportResult> GetUploadedReports(
|
||||
const base::FilePath& crashes_dir) override;
|
||||
|
||||
std::unique_ptr<crashpad::SimpleStringDictionary> simple_string_dictionary_;
|
||||
std::unique_ptr<crashpad::CrashReportDatabase> database_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CrashReporterMac);
|
||||
};
|
||||
|
||||
|
||||
@@ -6,17 +6,11 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/mac/bundle_locations.h"
|
||||
#include "base/mac/mac_util.h"
|
||||
#include "base/memory/singleton.h"
|
||||
#include "base/strings/string_piece.h"
|
||||
#include "base/strings/stringprintf.h"
|
||||
#include "base/strings/sys_string_conversions.h"
|
||||
#include "base/threading/thread_restrictions.h"
|
||||
#include "crashpad/client/crashpad_client.h"
|
||||
#include "crashpad/client/crashpad_info.h"
|
||||
#include "crashpad/client/settings.h"
|
||||
#include "third_party/crashpad/crashpad/client/crashpad_client.h"
|
||||
#include "third_party/crashpad/crashpad/client/crashpad_info.h"
|
||||
|
||||
namespace crash_reporter {
|
||||
|
||||
@@ -24,19 +18,18 @@ CrashReporterMac::CrashReporterMac() {}
|
||||
|
||||
CrashReporterMac::~CrashReporterMac() {}
|
||||
|
||||
void CrashReporterMac::InitBreakpad(const std::string& product_name,
|
||||
const std::string& version,
|
||||
const std::string& company_name,
|
||||
const std::string& submit_url,
|
||||
const base::FilePath& crashes_dir,
|
||||
bool upload_to_server,
|
||||
bool skip_system_crash_handler) {
|
||||
void CrashReporterMac::Init(const std::string& product_name,
|
||||
const std::string& company_name,
|
||||
const std::string& submit_url,
|
||||
const base::FilePath& crashes_dir,
|
||||
bool upload_to_server,
|
||||
bool skip_system_crash_handler) {
|
||||
// check whether crashpad has been initialized.
|
||||
// Only need to initialize once.
|
||||
if (simple_string_dictionary_)
|
||||
return;
|
||||
|
||||
if (is_browser_) {
|
||||
if (process_type_.empty()) { // browser process
|
||||
@autoreleasepool {
|
||||
base::FilePath framework_bundle_path = base::mac::FrameworkBundlePath();
|
||||
base::FilePath handler_path =
|
||||
@@ -63,112 +56,17 @@ void CrashReporterMac::InitBreakpad(const std::string& product_name,
|
||||
simple_string_dictionary_.reset(new crashpad::SimpleStringDictionary());
|
||||
crashpad_info->set_simple_annotations(simple_string_dictionary_.get());
|
||||
|
||||
SetCrashKeyValue("prod", ATOM_PRODUCT_NAME);
|
||||
SetCrashKeyValue("process_type", is_browser_ ? "browser" : "renderer");
|
||||
SetCrashKeyValue("ver", version);
|
||||
|
||||
for (const auto& upload_parameter : upload_parameters_) {
|
||||
SetCrashKeyValue(upload_parameter.first, upload_parameter.second);
|
||||
}
|
||||
if (is_browser_) {
|
||||
SetInitialCrashKeyValues();
|
||||
if (process_type_.empty()) { // browser process
|
||||
database_ = crashpad::CrashReportDatabase::Initialize(crashes_dir);
|
||||
SetUploadToServer(upload_to_server);
|
||||
}
|
||||
}
|
||||
|
||||
bool CrashReporterMac::GetUploadToServer() {
|
||||
bool enabled = true;
|
||||
if (database_) {
|
||||
database_->GetSettings()->GetUploadsEnabled(&enabled);
|
||||
}
|
||||
return enabled;
|
||||
}
|
||||
|
||||
void CrashReporterMac::SetUploadToServer(const bool upload_to_server) {
|
||||
if (database_) {
|
||||
database_->GetSettings()->SetUploadsEnabled(upload_to_server);
|
||||
}
|
||||
}
|
||||
|
||||
void CrashReporterMac::SetUploadParameters() {
|
||||
upload_parameters_["platform"] = "darwin";
|
||||
}
|
||||
|
||||
void CrashReporterMac::SetCrashKeyValue(const base::StringPiece& key,
|
||||
const base::StringPiece& value) {
|
||||
simple_string_dictionary_->SetKeyValue(key.data(), value.data());
|
||||
}
|
||||
|
||||
void CrashReporterMac::AddExtraParameter(const std::string& key,
|
||||
const std::string& value) {
|
||||
if (simple_string_dictionary_) {
|
||||
SetCrashKeyValue(key, value);
|
||||
} else {
|
||||
upload_parameters_[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
void CrashReporterMac::RemoveExtraParameter(const std::string& key) {
|
||||
if (simple_string_dictionary_)
|
||||
simple_string_dictionary_->RemoveKey(key.data());
|
||||
else
|
||||
upload_parameters_.erase(key);
|
||||
}
|
||||
|
||||
std::map<std::string, std::string> CrashReporterMac::GetParameters() const {
|
||||
if (simple_string_dictionary_) {
|
||||
std::map<std::string, std::string> ret;
|
||||
crashpad::SimpleStringDictionary::Iterator iter(*simple_string_dictionary_);
|
||||
for (;;) {
|
||||
auto* const entry = iter.Next();
|
||||
if (!entry)
|
||||
break;
|
||||
ret[entry->key] = entry->value;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
return upload_parameters_;
|
||||
}
|
||||
|
||||
std::vector<CrashReporter::UploadReportResult>
|
||||
CrashReporterMac::GetUploadedReports(const base::FilePath& crashes_dir) {
|
||||
std::vector<CrashReporter::UploadReportResult> uploaded_reports;
|
||||
|
||||
{
|
||||
base::ThreadRestrictions::ScopedAllowIO allow_io;
|
||||
if (!base::PathExists(crashes_dir)) {
|
||||
return uploaded_reports;
|
||||
}
|
||||
}
|
||||
// Load crashpad database.
|
||||
std::unique_ptr<crashpad::CrashReportDatabase> database =
|
||||
crashpad::CrashReportDatabase::Initialize(crashes_dir);
|
||||
DCHECK(database);
|
||||
|
||||
std::vector<crashpad::CrashReportDatabase::Report> completed_reports;
|
||||
crashpad::CrashReportDatabase::OperationStatus status =
|
||||
database->GetCompletedReports(&completed_reports);
|
||||
if (status != crashpad::CrashReportDatabase::kNoError) {
|
||||
return uploaded_reports;
|
||||
}
|
||||
|
||||
for (const crashpad::CrashReportDatabase::Report& completed_report :
|
||||
completed_reports) {
|
||||
if (completed_report.uploaded) {
|
||||
uploaded_reports.push_back(
|
||||
UploadReportResult(static_cast<int>(completed_report.creation_time),
|
||||
completed_report.id));
|
||||
}
|
||||
}
|
||||
|
||||
auto sort_by_time = [](const UploadReportResult& a,
|
||||
const UploadReportResult& b) {
|
||||
return a.first >= b.first;
|
||||
};
|
||||
std::sort(uploaded_reports.begin(), uploaded_reports.end(), sort_by_time);
|
||||
return uploaded_reports;
|
||||
}
|
||||
|
||||
// static
|
||||
CrashReporterMac* CrashReporterMac::GetInstance() {
|
||||
return base::Singleton<CrashReporterMac>::get();
|
||||
|
||||
@@ -4,276 +4,128 @@
|
||||
|
||||
#include "atom/common/crash_reporter/crash_reporter_win.h"
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/logging.h"
|
||||
#include "atom/browser/ui/inspectable_web_contents_impl.h"
|
||||
#include "atom/common/atom_constants.h"
|
||||
#include "base/environment.h"
|
||||
#include "base/memory/singleton.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/path_service.h"
|
||||
#include "base/strings/stringprintf.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "content/public/common/result_codes.h"
|
||||
#include "electron/atom/common/api/api.mojom.h"
|
||||
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
|
||||
#include "third_party/crashpad/crashpad/client/crashpad_client.h"
|
||||
#include "third_party/crashpad/crashpad/client/crashpad_info.h"
|
||||
|
||||
#if defined(_WIN64)
|
||||
#include "gin/public/debug.h"
|
||||
#include "sandbox/win/src/nt_internals.h"
|
||||
|
||||
#pragma intrinsic(_AddressOfReturnAddress)
|
||||
#pragma intrinsic(_ReturnAddress)
|
||||
|
||||
#ifdef _WIN64
|
||||
// See http://msdn.microsoft.com/en-us/library/ddssxxy8.aspx
|
||||
typedef struct _UNWIND_INFO {
|
||||
unsigned char Version : 3;
|
||||
unsigned char Flags : 5;
|
||||
unsigned char SizeOfProlog;
|
||||
unsigned char CountOfCodes;
|
||||
unsigned char FrameRegister : 4;
|
||||
unsigned char FrameOffset : 4;
|
||||
ULONG ExceptionHandler;
|
||||
} UNWIND_INFO, *PUNWIND_INFO;
|
||||
#endif
|
||||
|
||||
namespace crash_reporter {
|
||||
|
||||
namespace {
|
||||
|
||||
// Minidump with stacks, PEB, TEB, and unloaded module list.
|
||||
const MINIDUMP_TYPE kSmallDumpType = static_cast<MINIDUMP_TYPE>(
|
||||
MiniDumpWithProcessThreadData | // Get PEB and TEB.
|
||||
MiniDumpWithUnloadedModules); // Get unloaded modules when available.
|
||||
|
||||
const wchar_t kWaitEventFormat[] = L"$1CrashServiceWaitEvent";
|
||||
const wchar_t kPipeNameFormat[] = L"\\\\.\\pipe\\$1 Crash Service";
|
||||
|
||||
// Matches breakpad/src/client/windows/common/ipc_protocol.h.
|
||||
const int kNameMaxLength = 64;
|
||||
const int kValueMaxLength = 64;
|
||||
|
||||
typedef NTSTATUS(WINAPI* NtTerminateProcessPtr)(HANDLE ProcessHandle,
|
||||
NTSTATUS ExitStatus);
|
||||
char* g_real_terminate_process_stub = NULL;
|
||||
|
||||
void TerminateProcessWithoutDump() {
|
||||
// Patched stub exists based on conditions (See InitCrashReporter).
|
||||
// As a side note this function also gets called from
|
||||
// WindowProcExceptionFilter.
|
||||
if (g_real_terminate_process_stub == NULL) {
|
||||
::TerminateProcess(::GetCurrentProcess(), content::RESULT_CODE_KILLED);
|
||||
} else {
|
||||
NtTerminateProcessPtr real_terminate_proc =
|
||||
reinterpret_cast<NtTerminateProcessPtr>(
|
||||
static_cast<char*>(g_real_terminate_process_stub));
|
||||
real_terminate_proc(::GetCurrentProcess(), content::RESULT_CODE_KILLED);
|
||||
}
|
||||
#if defined(_WIN64)
|
||||
int CrashForException(EXCEPTION_POINTERS* info) {
|
||||
auto* reporter = crash_reporter::CrashReporterWin::GetInstance();
|
||||
if (reporter->IsInitialized())
|
||||
reporter->GetCrashpadClient().DumpAndCrash(info);
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
#ifdef _WIN64
|
||||
int CrashForExceptionInNonABICompliantCodeRange(
|
||||
PEXCEPTION_RECORD ExceptionRecord,
|
||||
ULONG64 EstablisherFrame,
|
||||
PCONTEXT ContextRecord,
|
||||
PDISPATCHER_CONTEXT DispatcherContext) {
|
||||
EXCEPTION_POINTERS info = {ExceptionRecord, ContextRecord};
|
||||
if (!CrashReporter::GetInstance())
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
return static_cast<CrashReporterWin*>(CrashReporter::GetInstance())
|
||||
->CrashForException(&info);
|
||||
}
|
||||
|
||||
struct ExceptionHandlerRecord {
|
||||
RUNTIME_FUNCTION runtime_function;
|
||||
UNWIND_INFO unwind_info;
|
||||
unsigned char thunk[12];
|
||||
};
|
||||
|
||||
bool RegisterNonABICompliantCodeRange(void* start, size_t size_in_bytes) {
|
||||
ExceptionHandlerRecord* record =
|
||||
reinterpret_cast<ExceptionHandlerRecord*>(start);
|
||||
|
||||
// We assume that the first page of the code range is executable and
|
||||
// committed and reserved for breakpad. What could possibly go wrong?
|
||||
|
||||
// All addresses are 32bit relative offsets to start.
|
||||
record->runtime_function.BeginAddress = 0;
|
||||
#if defined(_M_ARM64)
|
||||
record->runtime_function.FunctionLength =
|
||||
base::checked_cast<DWORD>(size_in_bytes);
|
||||
#else
|
||||
record->runtime_function.EndAddress =
|
||||
base::checked_cast<DWORD>(size_in_bytes);
|
||||
#endif
|
||||
record->runtime_function.UnwindData =
|
||||
offsetof(ExceptionHandlerRecord, unwind_info);
|
||||
|
||||
// Create unwind info that only specifies an exception handler.
|
||||
record->unwind_info.Version = 1;
|
||||
record->unwind_info.Flags = UNW_FLAG_EHANDLER;
|
||||
record->unwind_info.SizeOfProlog = 0;
|
||||
record->unwind_info.CountOfCodes = 0;
|
||||
record->unwind_info.FrameRegister = 0;
|
||||
record->unwind_info.FrameOffset = 0;
|
||||
record->unwind_info.ExceptionHandler =
|
||||
offsetof(ExceptionHandlerRecord, thunk);
|
||||
|
||||
// Hardcoded thunk.
|
||||
// mov imm64, rax
|
||||
record->thunk[0] = 0x48;
|
||||
record->thunk[1] = 0xb8;
|
||||
void* handler =
|
||||
reinterpret_cast<void*>(&CrashForExceptionInNonABICompliantCodeRange);
|
||||
memcpy(&record->thunk[2], &handler, 8);
|
||||
|
||||
// jmp rax
|
||||
record->thunk[10] = 0xff;
|
||||
record->thunk[11] = 0xe0;
|
||||
|
||||
// Protect reserved page against modifications.
|
||||
DWORD old_protect;
|
||||
return VirtualProtect(start, sizeof(ExceptionHandlerRecord),
|
||||
PAGE_EXECUTE_READ, &old_protect) &&
|
||||
RtlAddFunctionTable(&record->runtime_function, 1,
|
||||
reinterpret_cast<DWORD64>(start));
|
||||
}
|
||||
|
||||
void UnregisterNonABICompliantCodeRange(void* start) {
|
||||
ExceptionHandlerRecord* record =
|
||||
reinterpret_cast<ExceptionHandlerRecord*>(start);
|
||||
|
||||
RtlDeleteFunctionTable(&record->runtime_function);
|
||||
}
|
||||
|
||||
#endif // _WIN64
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace crash_reporter {
|
||||
|
||||
CrashReporterWin::CrashReporterWin() {}
|
||||
|
||||
CrashReporterWin::~CrashReporterWin() {}
|
||||
|
||||
void CrashReporterWin::InitBreakpad(const std::string& product_name,
|
||||
const std::string& version,
|
||||
const std::string& company_name,
|
||||
const std::string& submit_url,
|
||||
const base::FilePath& crashes_dir,
|
||||
bool upload_to_server,
|
||||
bool skip_system_crash_handler) {
|
||||
skip_system_crash_handler_ = skip_system_crash_handler;
|
||||
#if defined(_WIN64)
|
||||
void CrashReporterWin::SetUnhandledExceptionFilter() {
|
||||
gin::Debug::SetUnhandledExceptionCallback(&CrashForException);
|
||||
}
|
||||
#endif
|
||||
|
||||
base::string16 pipe_name = base::ReplaceStringPlaceholders(
|
||||
kPipeNameFormat, base::UTF8ToUTF16(product_name), NULL);
|
||||
base::string16 wait_name = base::ReplaceStringPlaceholders(
|
||||
kWaitEventFormat, base::UTF8ToUTF16(product_name), NULL);
|
||||
void CrashReporterWin::Init(const std::string& product_name,
|
||||
const std::string& company_name,
|
||||
const std::string& submit_url,
|
||||
const base::FilePath& crashes_dir,
|
||||
bool upload_to_server,
|
||||
bool skip_system_crash_handler) {
|
||||
// check whether crashpad has been initialized.
|
||||
// Only need to initialize once.
|
||||
if (simple_string_dictionary_)
|
||||
return;
|
||||
if (process_type_.empty()) { // browser process
|
||||
base::FilePath handler_path;
|
||||
base::PathService::Get(base::FILE_EXE, &handler_path);
|
||||
|
||||
// Wait until the crash service is started.
|
||||
HANDLE wait_event = ::CreateEventW(NULL, TRUE, FALSE, wait_name.c_str());
|
||||
if (wait_event != NULL) {
|
||||
WaitForSingleObject(wait_event, 1000);
|
||||
CloseHandle(wait_event);
|
||||
}
|
||||
|
||||
// ExceptionHandler() attaches our handler and ~ExceptionHandler() detaches
|
||||
// it, so we must explicitly reset *before* we instantiate our new handler
|
||||
// to allow any previous handler to detach in the correct order.
|
||||
breakpad_.reset();
|
||||
|
||||
breakpad_.reset(new google_breakpad::ExceptionHandler(
|
||||
crashes_dir.DirName().value(), FilterCallback, MinidumpCallback, this,
|
||||
google_breakpad::ExceptionHandler::HANDLER_ALL, kSmallDumpType,
|
||||
pipe_name.c_str(),
|
||||
GetCustomInfo(product_name, version, company_name, upload_to_server)));
|
||||
|
||||
if (!breakpad_->IsOutOfProcess())
|
||||
LOG(ERROR) << "Cannot initialize out-of-process crash handler";
|
||||
|
||||
#ifdef _WIN64
|
||||
// Hook up V8 to breakpad.
|
||||
if (!code_range_registered_) {
|
||||
code_range_registered_ = true;
|
||||
// gin::Debug::SetCodeRangeCreatedCallback only runs the callback when
|
||||
// Isolate is just created, so we have to manually run following code here.
|
||||
void* code_range = nullptr;
|
||||
size_t size = 0;
|
||||
v8::Isolate::GetCurrent()->GetCodeRange(&code_range, &size);
|
||||
if (code_range && size &&
|
||||
RegisterNonABICompliantCodeRange(code_range, size)) {
|
||||
// FIXME(nornagon): This broke with https://crrev.com/c/1474703
|
||||
gin::Debug::SetCodeRangeDeletedCallback(
|
||||
UnregisterNonABICompliantCodeRange);
|
||||
std::vector<std::string> args = {
|
||||
"--no-rate-limit",
|
||||
"--no-upload-gzip", // not all servers accept gzip
|
||||
};
|
||||
args.push_back(base::StringPrintf("--type=%s", kCrashpadProcess));
|
||||
args.push_back(
|
||||
base::StringPrintf("--%s=%s", kCrashesDirectoryKey,
|
||||
base::UTF16ToUTF8(crashes_dir.value()).c_str()));
|
||||
crashpad_client_.StartHandler(handler_path, crashes_dir, crashes_dir,
|
||||
submit_url, StringMap(), args, true, false);
|
||||
UpdatePipeName();
|
||||
} else {
|
||||
std::unique_ptr<base::Environment> env(base::Environment::Create());
|
||||
std::string pipe_name_utf8;
|
||||
if (env->GetVar(atom::kCrashpadPipeName, &pipe_name_utf8)) {
|
||||
base::string16 pipe_name = base::UTF8ToUTF16(pipe_name_utf8);
|
||||
if (!crashpad_client_.SetHandlerIPCPipe(pipe_name))
|
||||
LOG(ERROR) << "Failed to set handler IPC pipe name: " << pipe_name;
|
||||
} else {
|
||||
LOG(ERROR) << "Unable to get pipe name for crashpad";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
crashpad::CrashpadInfo* crashpad_info =
|
||||
crashpad::CrashpadInfo::GetCrashpadInfo();
|
||||
if (skip_system_crash_handler) {
|
||||
crashpad_info->set_system_crash_reporter_forwarding(
|
||||
crashpad::TriState::kDisabled);
|
||||
}
|
||||
simple_string_dictionary_.reset(new crashpad::SimpleStringDictionary());
|
||||
crashpad_info->set_simple_annotations(simple_string_dictionary_.get());
|
||||
|
||||
SetInitialCrashKeyValues();
|
||||
if (process_type_.empty()) { // browser process
|
||||
database_ = crashpad::CrashReportDatabase::Initialize(crashes_dir);
|
||||
SetUploadToServer(upload_to_server);
|
||||
}
|
||||
}
|
||||
|
||||
void CrashReporterWin::SetUploadParameters() {
|
||||
upload_parameters_["platform"] = "win32";
|
||||
}
|
||||
|
||||
int CrashReporterWin::CrashForException(EXCEPTION_POINTERS* info) {
|
||||
if (breakpad_) {
|
||||
breakpad_->WriteMinidumpForException(info);
|
||||
if (skip_system_crash_handler_)
|
||||
TerminateProcessWithoutDump();
|
||||
else
|
||||
RaiseFailFastException(info->ExceptionRecord, info->ContextRecord, 0);
|
||||
}
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
crashpad::CrashpadClient& CrashReporterWin::GetCrashpadClient() {
|
||||
return crashpad_client_;
|
||||
}
|
||||
|
||||
// static
|
||||
bool CrashReporterWin::FilterCallback(void* context,
|
||||
EXCEPTION_POINTERS* exinfo,
|
||||
MDRawAssertionInfo* assertion) {
|
||||
return true;
|
||||
}
|
||||
void CrashReporterWin::UpdatePipeName() {
|
||||
std::string pipe_name =
|
||||
base::UTF16ToUTF8(crashpad_client_.GetHandlerIPCPipe());
|
||||
std::unique_ptr<base::Environment> env(base::Environment::Create());
|
||||
env->SetVar(atom::kCrashpadPipeName, pipe_name);
|
||||
|
||||
// static
|
||||
bool CrashReporterWin::MinidumpCallback(const wchar_t* dump_path,
|
||||
const wchar_t* minidump_id,
|
||||
void* context,
|
||||
EXCEPTION_POINTERS* exinfo,
|
||||
MDRawAssertionInfo* assertion,
|
||||
bool succeeded) {
|
||||
CrashReporterWin* self = static_cast<CrashReporterWin*>(context);
|
||||
if (succeeded && self->skip_system_crash_handler_)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
// Notify all WebContents of the pipe name.
|
||||
const auto& pages = atom::InspectableWebContentsImpl::GetAll();
|
||||
for (auto* page : pages) {
|
||||
auto* frame_host = page->GetWebContents()->GetMainFrame();
|
||||
if (!frame_host)
|
||||
continue;
|
||||
|
||||
google_breakpad::CustomClientInfo* CrashReporterWin::GetCustomInfo(
|
||||
const std::string& product_name,
|
||||
const std::string& version,
|
||||
const std::string& company_name,
|
||||
bool upload_to_server) {
|
||||
custom_info_entries_.clear();
|
||||
custom_info_entries_.reserve(3 + upload_parameters_.size());
|
||||
|
||||
custom_info_entries_.push_back(
|
||||
google_breakpad::CustomInfoEntry(L"prod", L"Electron"));
|
||||
custom_info_entries_.push_back(google_breakpad::CustomInfoEntry(
|
||||
L"ver", base::UTF8ToWide(version).c_str()));
|
||||
if (!upload_to_server) {
|
||||
custom_info_entries_.push_back(
|
||||
google_breakpad::CustomInfoEntry(L"skip_upload", L"1"));
|
||||
atom::mojom::ElectronRendererAssociatedPtr electron_ptr;
|
||||
frame_host->GetRemoteAssociatedInterfaces()->GetInterface(
|
||||
mojo::MakeRequest(&electron_ptr));
|
||||
electron_ptr->UpdateCrashpadPipeName(pipe_name);
|
||||
}
|
||||
|
||||
for (StringMap::const_iterator iter = upload_parameters_.begin();
|
||||
iter != upload_parameters_.end(); ++iter) {
|
||||
// breakpad has hardcoded the length of name/value, and doesn't truncate
|
||||
// the values itself, so we have to truncate them here otherwise weird
|
||||
// things may happen.
|
||||
std::wstring name = base::UTF8ToWide(iter->first);
|
||||
std::wstring value = base::UTF8ToWide(iter->second);
|
||||
if (name.length() > kNameMaxLength - 1)
|
||||
name.resize(kNameMaxLength - 1);
|
||||
if (value.length() > kValueMaxLength - 1)
|
||||
value.resize(kValueMaxLength - 1);
|
||||
|
||||
custom_info_entries_.push_back(
|
||||
google_breakpad::CustomInfoEntry(name.c_str(), value.c_str()));
|
||||
}
|
||||
|
||||
custom_info_.entries = &custom_info_entries_.front();
|
||||
custom_info_.count = custom_info_entries_.size();
|
||||
return &custom_info_;
|
||||
}
|
||||
|
||||
// static
|
||||
|
||||
@@ -7,11 +7,9 @@
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/common/crash_reporter/crash_reporter.h"
|
||||
#include "base/compiler_specific.h"
|
||||
#include "breakpad/src/client/windows/handler/exception_handler.h"
|
||||
#include "atom/common/crash_reporter/crash_reporter_crashpad.h"
|
||||
#include "third_party/crashpad/crashpad/client/crashpad_client.h"
|
||||
|
||||
namespace base {
|
||||
template <typename T>
|
||||
@@ -20,55 +18,31 @@ struct DefaultSingletonTraits;
|
||||
|
||||
namespace crash_reporter {
|
||||
|
||||
class CrashReporterWin : public CrashReporter {
|
||||
class CrashReporterWin : public CrashReporterCrashpad {
|
||||
public:
|
||||
static CrashReporterWin* GetInstance();
|
||||
#if defined(_WIN64)
|
||||
static void SetUnhandledExceptionFilter();
|
||||
#endif
|
||||
|
||||
void InitBreakpad(const std::string& product_name,
|
||||
const std::string& version,
|
||||
const std::string& company_name,
|
||||
const std::string& submit_url,
|
||||
const base::FilePath& crashes_dir,
|
||||
bool upload_to_server,
|
||||
bool skip_system_crash_handler) override;
|
||||
void Init(const std::string& product_name,
|
||||
const std::string& company_name,
|
||||
const std::string& submit_url,
|
||||
const base::FilePath& crashes_dir,
|
||||
bool upload_to_server,
|
||||
bool skip_system_crash_handler) override;
|
||||
void SetUploadParameters() override;
|
||||
|
||||
// Crashes the process after generating a dump for the provided exception.
|
||||
int CrashForException(EXCEPTION_POINTERS* info);
|
||||
crashpad::CrashpadClient& GetCrashpadClient();
|
||||
|
||||
private:
|
||||
friend struct base::DefaultSingletonTraits<CrashReporterWin>;
|
||||
|
||||
CrashReporterWin();
|
||||
~CrashReporterWin() override;
|
||||
|
||||
static bool FilterCallback(void* context,
|
||||
EXCEPTION_POINTERS* exinfo,
|
||||
MDRawAssertionInfo* assertion);
|
||||
void UpdatePipeName();
|
||||
|
||||
static bool MinidumpCallback(const wchar_t* dump_path,
|
||||
const wchar_t* minidump_id,
|
||||
void* context,
|
||||
EXCEPTION_POINTERS* exinfo,
|
||||
MDRawAssertionInfo* assertion,
|
||||
bool succeeded);
|
||||
|
||||
// Returns the custom info structure based on parameters.
|
||||
google_breakpad::CustomClientInfo* GetCustomInfo(
|
||||
const std::string& product_name,
|
||||
const std::string& version,
|
||||
const std::string& company_name,
|
||||
bool upload_to_server);
|
||||
|
||||
// Custom information to be passed to crash handler.
|
||||
std::vector<google_breakpad::CustomInfoEntry> custom_info_entries_;
|
||||
google_breakpad::CustomClientInfo custom_info_;
|
||||
|
||||
bool skip_system_crash_handler_ = false;
|
||||
#ifdef _WIN64
|
||||
bool code_range_registered_ = false;
|
||||
#endif
|
||||
std::unique_ptr<google_breakpad::ExceptionHandler> breakpad_;
|
||||
crashpad::CrashpadClient crashpad_client_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CrashReporterWin);
|
||||
};
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user