From c7509b0a5328df461dffd3e9e7931ca76222e4e6 Mon Sep 17 00:00:00 2001 From: "trop[bot]" <37223003+trop[bot]@users.noreply.github.com> Date: Mon, 25 Jul 2022 09:59:22 +0200 Subject: [PATCH 01/30] fix: add support for --ozone-platform-hint flag on Linux (#35014) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Valentin Hăloiu --- filenames.gni | 1 + shell/browser/electron_browser_main_parts.cc | 1 + shell/browser/electron_browser_main_parts.h | 4 + .../electron_browser_main_parts_linux.cc | 134 ++++++++++++++++++ 4 files changed, 140 insertions(+) create mode 100644 shell/browser/electron_browser_main_parts_linux.cc diff --git a/filenames.gni b/filenames.gni index 3af6eb4e1d931..0a0617ee5c67c 100644 --- a/filenames.gni +++ b/filenames.gni @@ -23,6 +23,7 @@ filenames = { lib_sources_linux = [ "shell/browser/browser_linux.cc", + "shell/browser/electron_browser_main_parts_linux.cc", "shell/browser/lib/power_observer_linux.cc", "shell/browser/lib/power_observer_linux.h", "shell/browser/linux/unity_service.cc", diff --git a/shell/browser/electron_browser_main_parts.cc b/shell/browser/electron_browser_main_parts.cc index eaef6148d18f7..feaa3b04fe603 100644 --- a/shell/browser/electron_browser_main_parts.cc +++ b/shell/browser/electron_browser_main_parts.cc @@ -217,6 +217,7 @@ int ElectronBrowserMainParts::PreEarlyInitialization() { HandleSIGCHLD(); #endif #if BUILDFLAG(IS_LINUX) + DetectOzonePlatform(); ui::OzonePlatform::PreEarlyInitialization(); #endif #if BUILDFLAG(IS_MAC) diff --git a/shell/browser/electron_browser_main_parts.h b/shell/browser/electron_browser_main_parts.h index 95ced64ed7c9e..3c45ed29bfbb7 100644 --- a/shell/browser/electron_browser_main_parts.h +++ b/shell/browser/electron_browser_main_parts.h @@ -122,6 +122,10 @@ class ElectronBrowserMainParts : public content::BrowserMainParts { const scoped_refptr& task_runner); #endif +#if BUILDFLAG(IS_LINUX) + void DetectOzonePlatform(); +#endif + #if BUILDFLAG(IS_MAC) void FreeAppDelegate(); void RegisterURLHandler(); diff --git a/shell/browser/electron_browser_main_parts_linux.cc b/shell/browser/electron_browser_main_parts_linux.cc new file mode 100644 index 0000000000000..919cc085a2755 --- /dev/null +++ b/shell/browser/electron_browser_main_parts_linux.cc @@ -0,0 +1,134 @@ +// Copyright (c) 2022 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "shell/browser/electron_browser_main_parts.h" + +#include "base/command_line.h" +#include "base/environment.h" +#include "ui/ozone/public/ozone_switches.h" + +#if BUILDFLAG(OZONE_PLATFORM_WAYLAND) +#include "base/files/file_path.h" +#include "base/files/file_util.h" +#include "base/nix/xdg_util.h" +#include "base/threading/thread_restrictions.h" +#endif + +#if BUILDFLAG(OZONE_PLATFORM_WAYLAND) + +constexpr char kPlatformWayland[] = "wayland"; + +bool HasWaylandDisplay(base::Environment* env) { + std::string wayland_display; + const bool has_wayland_display = + env->GetVar("WAYLAND_DISPLAY", &wayland_display) && + !wayland_display.empty(); + if (has_wayland_display) + return true; + + std::string xdg_runtime_dir; + const bool has_xdg_runtime_dir = + env->GetVar("XDG_RUNTIME_DIR", &xdg_runtime_dir) && + !xdg_runtime_dir.empty(); + if (has_xdg_runtime_dir) { + auto wayland_server_pipe = + base::FilePath(xdg_runtime_dir).Append("wayland-0"); + // Normally, this should happen exactly once, at the startup of the main + // process. + base::ScopedAllowBlocking allow_blocking; + return base::PathExists(wayland_server_pipe); + } + + return false; +} + +#endif // BUILDFLAG(OZONE_PLATFORM_WAYLAND) + +#if BUILDFLAG(OZONE_PLATFORM_X11) +constexpr char kPlatformX11[] = "x11"; +#endif + +namespace electron { + +namespace { + +// Evaluates the environment and returns the effective platform name for the +// given |ozone_platform_hint|. +// For the "auto" value, returns "wayland" if the XDG session type is "wayland", +// "x11" otherwise. +// For the "wayland" value, checks if the Wayland server is available, and +// returns "x11" if it is not. +// See https://crbug.com/1246928. +std::string MaybeFixPlatformName(const std::string& ozone_platform_hint) { +#if BUILDFLAG(OZONE_PLATFORM_WAYLAND) + // Wayland is selected if both conditions below are true: + // 1. The user selected either 'wayland' or 'auto'. + // 2. The XDG session type is 'wayland', OR the user has selected 'wayland' + // explicitly and a Wayland server is running. + // Otherwise, fall back to X11. + if (ozone_platform_hint == kPlatformWayland || + ozone_platform_hint == "auto") { + auto env(base::Environment::Create()); + + std::string xdg_session_type; + const bool has_xdg_session_type = + env->GetVar(base::nix::kXdgSessionTypeEnvVar, &xdg_session_type) && + !xdg_session_type.empty(); + + if ((has_xdg_session_type && xdg_session_type == "wayland") || + (ozone_platform_hint == kPlatformWayland && + HasWaylandDisplay(env.get()))) { + return kPlatformWayland; + } + } +#endif // BUILDFLAG(OZONE_PLATFORM_WAYLAND) + +#if BUILDFLAG(OZONE_PLATFORM_X11) + if (ozone_platform_hint == kPlatformX11) { + return kPlatformX11; + } +#if BUILDFLAG(OZONE_PLATFORM_WAYLAND) + if (ozone_platform_hint == kPlatformWayland || + ozone_platform_hint == "auto") { + // We are here if: + // - The binary has both X11 and Wayland backends. + // - The user wanted Wayland but that did not work, otherwise it would have + // been returned above. + if (ozone_platform_hint == kPlatformWayland) { + LOG(WARNING) << "No Wayland server is available. Falling back to X11."; + } else { + LOG(WARNING) << "This is not a Wayland session. Falling back to X11. " + "If you need to run Chrome on Wayland using some " + "embedded compositor, e. g., Weston, please specify " + "Wayland as your preferred Ozone platform, or use " + "--ozone-platform=wayland."; + } + return kPlatformX11; + } +#endif // BUILDFLAG(OZONE_PLATFORM_WAYLAND) +#endif // BUILDFLAG(OZONE_PLATFORM_X11) + + return ozone_platform_hint; +} + +} // namespace + +void ElectronBrowserMainParts::DetectOzonePlatform() { + auto* const command_line = base::CommandLine::ForCurrentProcess(); + if (!command_line->HasSwitch(switches::kOzonePlatform)) { + const auto ozone_platform_hint = + command_line->GetSwitchValueASCII(switches::kOzonePlatformHint); + if (!ozone_platform_hint.empty()) { + command_line->AppendSwitchASCII( + switches::kOzonePlatform, MaybeFixPlatformName(ozone_platform_hint)); + } + } + + auto env = base::Environment::Create(); + std::string desktop_startup_id; + if (env->GetVar("DESKTOP_STARTUP_ID", &desktop_startup_id)) + command_line->AppendSwitchASCII("desktop-startup-id", desktop_startup_id); +} + +} // namespace electron From 4f3be68ad56e5ced8c9d7e29f2c4423840ce9a7f Mon Sep 17 00:00:00 2001 From: "trop[bot]" <37223003+trop[bot]@users.noreply.github.com> Date: Mon, 25 Jul 2022 10:11:12 +0200 Subject: [PATCH 02/30] refactor: only create webContents after 'will-attach-webview' (#35016) refactor: only create webContents after 'will-attach-webview' (#30311) Co-authored-by: Milan Burda --- lib/browser/guest-view-manager.ts | 81 +++++-------------- lib/common/ipc-messages.ts | 1 - lib/renderer/web-view/guest-view-internal.ts | 7 -- lib/renderer/web-view/web-view-element.ts | 3 +- lib/renderer/web-view/web-view-impl.ts | 2 +- .../api/electron_api_web_view_manager.cc | 4 - shell/browser/web_contents_preferences.cc | 4 - shell/browser/web_contents_preferences.h | 2 - typings/internal-electron.d.ts | 1 - 9 files changed, 21 insertions(+), 84 deletions(-) diff --git a/lib/browser/guest-view-manager.ts b/lib/browser/guest-view-manager.ts index c9c4585de28e4..2d88a0a017ea7 100644 --- a/lib/browser/guest-view-manager.ts +++ b/lib/browser/guest-view-manager.ts @@ -7,7 +7,7 @@ import { webViewEvents } from '@electron/internal/browser/web-view-events'; import { IPC_MESSAGES } from '@electron/internal/common/ipc-messages'; interface GuestInstance { - elementInstanceId?: number; + elementInstanceId: number; visibilityState?: VisibilityState; embedder: Electron.WebContents; guest: Electron.WebContents; @@ -46,6 +46,7 @@ function makeWebPreferences (embedder: Electron.WebContents, params: Record) { // Create a new guest instance. const createGuest = function (embedder: Electron.WebContents, embedderFrameId: number, elementInstanceId: number, params: Record) { + const webPreferences = makeWebPreferences(embedder, params); + const event = eventBinding.createWithSender(embedder); + + const { instanceId } = params; + + embedder.emit('will-attach-webview', event, webPreferences, params); + if (event.defaultPrevented) { + return -1; + } + // eslint-disable-next-line no-undef const guest = (webContents as typeof ElectronInternal.WebContents).create({ + ...webPreferences, type: 'webview', - partition: params.partition, embedder }); + const guestInstanceId = guest.id; guestInstances.set(guestInstanceId, { + elementInstanceId, guest, embedder }); @@ -108,11 +121,8 @@ const createGuest = function (embedder: Electron.WebContents, embedderFrameId: n // Init guest web view after attached. guest.once('did-attach' as any, function (this: Electron.WebContents, event: Electron.Event) { - const params = this.attachParams!; - delete this.attachParams; - const previouslyAttached = this.viewInstanceId != null; - this.viewInstanceId = params.instanceId; + this.viewInstanceId = instanceId; // Only load URL and set size on first attach if (previouslyAttached) { @@ -120,7 +130,7 @@ const createGuest = function (embedder: Electron.WebContents, embedderFrameId: n } if (params.src) { - this.loadURL(params.src, params.opts); + this.loadURL(params.src, makeLoadURLOptions(params)); } embedder.emit('did-attach-webview', event, guest); }); @@ -173,78 +183,25 @@ const createGuest = function (embedder: Electron.WebContents, embedderFrameId: n } }); - if (attachGuest(embedder, embedderFrameId, elementInstanceId, guestInstanceId, params)) { - return guestInstanceId; - } - - return -1; -}; - -// Attach the guest to an element of embedder. -const attachGuest = function (embedder: Electron.WebContents, embedderFrameId: number, elementInstanceId: number, guestInstanceId: number, params: Record) { // Destroy the old guest when attaching. const key = `${embedder.id}-${elementInstanceId}`; const oldGuestInstanceId = embedderElementsMap.get(key); if (oldGuestInstanceId != null) { - // Reattachment to the same guest is just a no-op. - if (oldGuestInstanceId === guestInstanceId) { - return false; - } - const oldGuestInstance = guestInstances.get(oldGuestInstanceId); if (oldGuestInstance) { oldGuestInstance.guest.detachFromOuterFrame(); } } - const guestInstance = guestInstances.get(guestInstanceId); - // If this isn't a valid guest instance then do nothing. - if (!guestInstance) { - console.error(new Error(`Guest attach failed: Invalid guestInstanceId ${guestInstanceId}`)); - return false; - } - const { guest } = guestInstance; - if (guest.hostWebContents !== embedder) { - console.error(new Error(`Guest attach failed: Access denied to guestInstanceId ${guestInstanceId}`)); - return false; - } - - const { instanceId } = params; - - // If this guest is already attached to an element then remove it - if (guestInstance.elementInstanceId) { - const oldKey = `${guestInstance.embedder.id}-${guestInstance.elementInstanceId}`; - embedderElementsMap.delete(oldKey); - - // Remove guest from embedder if moving across web views - if (guest.viewInstanceId !== instanceId) { - webViewManager.removeGuest(guestInstance.embedder, guestInstanceId); - guestInstance.embedder._sendInternal(`${IPC_MESSAGES.GUEST_VIEW_INTERNAL_DESTROY_GUEST}-${guest.viewInstanceId}`); - } - } - - const webPreferences = makeWebPreferences(embedder, params); - - const event = eventBinding.createWithSender(embedder); - embedder.emit('will-attach-webview', event, webPreferences, params); - if (event.defaultPrevented) { - if (guest.viewInstanceId == null) guest.viewInstanceId = instanceId; - guest.destroy(); - return false; - } - - guest.attachParams = { instanceId, src: params.src, opts: makeLoadURLOptions(params) }; embedderElementsMap.set(key, guestInstanceId); - guest.setEmbedder(embedder); - guestInstance.embedder = embedder; - guestInstance.elementInstanceId = elementInstanceId; watchEmbedder(embedder); webViewManager.addGuest(guestInstanceId, embedder, guest, webPreferences); guest.attachToIframe(embedder, embedderFrameId); - return true; + + return guestInstanceId; }; // Remove an guest-embedder relationship. diff --git a/lib/common/ipc-messages.ts b/lib/common/ipc-messages.ts index c6a881c3c0a23..3a85d592691c9 100644 --- a/lib/common/ipc-messages.ts +++ b/lib/common/ipc-messages.ts @@ -9,7 +9,6 @@ export const enum IPC_MESSAGES { GUEST_INSTANCE_VISIBILITY_CHANGE = 'GUEST_INSTANCE_VISIBILITY_CHANGE', - GUEST_VIEW_INTERNAL_DESTROY_GUEST = 'GUEST_VIEW_INTERNAL_DESTROY_GUEST', GUEST_VIEW_INTERNAL_DISPATCH_EVENT = 'GUEST_VIEW_INTERNAL_DISPATCH_EVENT', GUEST_VIEW_MANAGER_CREATE_AND_ATTACH_GUEST = 'GUEST_VIEW_MANAGER_CREATE_AND_ATTACH_GUEST', diff --git a/lib/renderer/web-view/guest-view-internal.ts b/lib/renderer/web-view/guest-view-internal.ts index d8b9b61c135f6..bd8a5a774a4d0 100644 --- a/lib/renderer/web-view/guest-view-internal.ts +++ b/lib/renderer/web-view/guest-view-internal.ts @@ -6,7 +6,6 @@ const { mainFrame: webFrame } = process._linkedBinding('electron_renderer_web_fr export interface GuestViewDelegate { dispatchEvent (eventName: string, props: Record): void; - reset(): void; } const DEPRECATED_EVENTS: Record = { @@ -14,11 +13,6 @@ const DEPRECATED_EVENTS: Record = { } as const; export function registerEvents (viewInstanceId: number, delegate: GuestViewDelegate) { - ipcRendererInternal.on(`${IPC_MESSAGES.GUEST_VIEW_INTERNAL_DESTROY_GUEST}-${viewInstanceId}`, function () { - delegate.reset(); - delegate.dispatchEvent('destroyed', {}); - }); - ipcRendererInternal.on(`${IPC_MESSAGES.GUEST_VIEW_INTERNAL_DISPATCH_EVENT}-${viewInstanceId}`, function (event, eventName, props) { if (DEPRECATED_EVENTS[eventName] != null) { delegate.dispatchEvent(DEPRECATED_EVENTS[eventName], props); @@ -29,7 +23,6 @@ export function registerEvents (viewInstanceId: number, delegate: GuestViewDeleg } export function deregisterEvents (viewInstanceId: number) { - ipcRendererInternal.removeAllListeners(`${IPC_MESSAGES.GUEST_VIEW_INTERNAL_DESTROY_GUEST}-${viewInstanceId}`); ipcRendererInternal.removeAllListeners(`${IPC_MESSAGES.GUEST_VIEW_INTERNAL_DISPATCH_EVENT}-${viewInstanceId}`); } diff --git a/lib/renderer/web-view/web-view-element.ts b/lib/renderer/web-view/web-view-element.ts index 84ac5a9ba79c4..ee290ce09b0fc 100644 --- a/lib/renderer/web-view/web-view-element.ts +++ b/lib/renderer/web-view/web-view-element.ts @@ -55,8 +55,7 @@ const defineWebViewElement = (hooks: WebViewImplHooks) => { } if (!internal.elementAttached) { hooks.guestViewInternal.registerEvents(internal.viewInstanceId, { - dispatchEvent: internal.dispatchEvent.bind(internal), - reset: internal.reset.bind(internal) + dispatchEvent: internal.dispatchEvent.bind(internal) }); internal.elementAttached = true; (internal.attributes.get(WEB_VIEW_CONSTANTS.ATTRIBUTE_SRC) as SrcAttribute).parse(); diff --git a/lib/renderer/web-view/web-view-impl.ts b/lib/renderer/web-view/web-view-impl.ts index 691b477e1bdb2..f3cad33534539 100644 --- a/lib/renderer/web-view/web-view-impl.ts +++ b/lib/renderer/web-view/web-view-impl.ts @@ -191,7 +191,7 @@ export class WebViewImpl { attachGuestInstance (guestInstanceId: number) { if (guestInstanceId === -1) { - // Do nothing + this.dispatchEvent('destroyed'); return; } diff --git a/shell/browser/api/electron_api_web_view_manager.cc b/shell/browser/api/electron_api_web_view_manager.cc index 7758c59cd5fd6..2bf03616b711c 100644 --- a/shell/browser/api/electron_api_web_view_manager.cc +++ b/shell/browser/api/electron_api_web_view_manager.cc @@ -28,10 +28,6 @@ void AddGuest(int guest_instance_id, electron::WebContentsZoomController::FromWebContents(guest_web_contents) ->SetDefaultZoomFactor(zoom_factor); } - - WebContentsPreferences::From(guest_web_contents)->Merge(options); - // Trigger re-calculation of webkit prefs. - guest_web_contents->NotifyPreferencesChanged(); } void RemoveGuest(content::WebContents* embedder, int guest_instance_id) { diff --git a/shell/browser/web_contents_preferences.cc b/shell/browser/web_contents_preferences.cc index a635b991fc6d7..c23c5ea39f6f0 100644 --- a/shell/browser/web_contents_preferences.cc +++ b/shell/browser/web_contents_preferences.cc @@ -176,11 +176,7 @@ void WebContentsPreferences::Clear() { void WebContentsPreferences::SetFromDictionary( const gin_helper::Dictionary& web_preferences) { Clear(); - Merge(web_preferences); -} -void WebContentsPreferences::Merge( - const gin_helper::Dictionary& web_preferences) { web_preferences.Get(options::kPlugins, &plugins_); web_preferences.Get(options::kExperimentalFeatures, &experimental_features_); web_preferences.Get(options::kNodeIntegration, &node_integration_); diff --git a/shell/browser/web_contents_preferences.h b/shell/browser/web_contents_preferences.h index 544bc54a80e46..8d72493d27f4b 100644 --- a/shell/browser/web_contents_preferences.h +++ b/shell/browser/web_contents_preferences.h @@ -40,8 +40,6 @@ class WebContentsPreferences WebContentsPreferences(const WebContentsPreferences&) = delete; WebContentsPreferences& operator=(const WebContentsPreferences&) = delete; - void Merge(const gin_helper::Dictionary& new_web_preferences); - void SetFromDictionary(const gin_helper::Dictionary& new_web_preferences); // Append command paramters according to preferences. diff --git a/typings/internal-electron.d.ts b/typings/internal-electron.d.ts index 49568925fa80b..156dbbc1d2615 100644 --- a/typings/internal-electron.d.ts +++ b/typings/internal-electron.d.ts @@ -81,7 +81,6 @@ declare namespace Electron { attachToIframe(embedderWebContents: Electron.WebContents, embedderFrameId: number): void; detachFromOuterFrame(): void; setEmbedder(embedder: Electron.WebContents): void; - attachParams?: { instanceId: number; src: string, opts: LoadURLOptions }; viewInstanceId: number; } From 8d68009abc758b4660374ceddac8b85381fe862c Mon Sep 17 00:00:00 2001 From: Sudowoodo Release Bot <88427002+sudowoodo-release-bot[bot]@users.noreply.github.com> Date: Mon, 25 Jul 2022 06:30:44 -0700 Subject: [PATCH 03/30] Bump v20.0.0-beta.12 --- ELECTRON_VERSION | 2 +- package.json | 2 +- shell/browser/resources/win/electron.rc | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ELECTRON_VERSION b/ELECTRON_VERSION index fae3222fe953c..5b6eaf4f52932 100644 --- a/ELECTRON_VERSION +++ b/ELECTRON_VERSION @@ -1 +1 @@ -20.0.0-beta.11 \ No newline at end of file +20.0.0-beta.12 \ No newline at end of file diff --git a/package.json b/package.json index 5b9b21e259449..bf27955f56d4d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "electron", - "version": "20.0.0-beta.11", + "version": "20.0.0-beta.12", "repository": "https://github.com/electron/electron", "description": "Build cross platform desktop apps with JavaScript, HTML, and CSS", "devDependencies": { diff --git a/shell/browser/resources/win/electron.rc b/shell/browser/resources/win/electron.rc index d42705c0e994e..065a76b12b917 100644 --- a/shell/browser/resources/win/electron.rc +++ b/shell/browser/resources/win/electron.rc @@ -50,8 +50,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 20,0,0,11 - PRODUCTVERSION 20,0,0,11 + FILEVERSION 20,0,0,12 + PRODUCTVERSION 20,0,0,12 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L From 3a079feb87ff6a1d3cea70cfdb20e77e9a5e3416 Mon Sep 17 00:00:00 2001 From: "trop[bot]" <37223003+trop[bot]@users.noreply.github.com> Date: Mon, 25 Jul 2022 16:36:59 -0400 Subject: [PATCH 04/30] fix: properly fire serial-port-added and serial-port-removed events (#35047) Based on 2309652: [webhid] Notify chooser context observers on shutdown | https://chromium-review.googlesource.com/c/chromium/src/+/2309652 Co-authored-by: John Kleinschmidt --- .../serial/electron_serial_delegate.cc | 33 ++++++++++++++++--- .../browser/serial/electron_serial_delegate.h | 18 +++++++++- .../browser/serial/serial_chooser_context.cc | 14 ++++---- shell/browser/serial/serial_chooser_context.h | 10 +++--- .../serial/serial_chooser_controller.cc | 10 +++--- .../serial/serial_chooser_controller.h | 7 ++++ 6 files changed, 71 insertions(+), 21 deletions(-) diff --git a/shell/browser/serial/electron_serial_delegate.cc b/shell/browser/serial/electron_serial_delegate.cc index 42b01a77f3d1b..bc3311f6e7a2e 100644 --- a/shell/browser/serial/electron_serial_delegate.cc +++ b/shell/browser/serial/electron_serial_delegate.cc @@ -70,15 +70,15 @@ device::mojom::SerialPortManager* ElectronSerialDelegate::GetPortManager( void ElectronSerialDelegate::AddObserver(content::RenderFrameHost* frame, Observer* observer) { - return GetChooserContext(frame)->AddPortObserver(observer); + observer_list_.AddObserver(observer); + auto* chooser_context = GetChooserContext(frame); + if (!port_observation_.IsObserving()) + port_observation_.Observe(chooser_context); } void ElectronSerialDelegate::RemoveObserver(content::RenderFrameHost* frame, Observer* observer) { - SerialChooserContext* serial_chooser_context = GetChooserContext(frame); - if (serial_chooser_context) { - return serial_chooser_context->RemovePortObserver(observer); - } + observer_list_.RemoveObserver(observer); } void ElectronSerialDelegate::RevokePortPermissionWebInitiated( @@ -119,4 +119,27 @@ void ElectronSerialDelegate::DeleteControllerForFrame( controller_map_.erase(render_frame_host); } +// SerialChooserContext::PortObserver: +void ElectronSerialDelegate::OnPortAdded( + const device::mojom::SerialPortInfo& port) { + for (auto& observer : observer_list_) + observer.OnPortAdded(port); +} + +void ElectronSerialDelegate::OnPortRemoved( + const device::mojom::SerialPortInfo& port) { + for (auto& observer : observer_list_) + observer.OnPortRemoved(port); +} + +void ElectronSerialDelegate::OnPortManagerConnectionError() { + port_observation_.Reset(); + for (auto& observer : observer_list_) + observer.OnPortManagerConnectionError(); +} + +void ElectronSerialDelegate::OnSerialChooserContextShutdown() { + port_observation_.Reset(); +} + } // namespace electron diff --git a/shell/browser/serial/electron_serial_delegate.h b/shell/browser/serial/electron_serial_delegate.h index 1153bcd8ad297..5876d7e511041 100644 --- a/shell/browser/serial/electron_serial_delegate.h +++ b/shell/browser/serial/electron_serial_delegate.h @@ -11,13 +11,15 @@ #include "base/memory/weak_ptr.h" #include "content/public/browser/serial_delegate.h" +#include "shell/browser/serial/serial_chooser_context.h" #include "shell/browser/serial/serial_chooser_controller.h" namespace electron { class SerialChooserController; -class ElectronSerialDelegate : public content::SerialDelegate { +class ElectronSerialDelegate : public content::SerialDelegate, + public SerialChooserContext::PortObserver { public: ElectronSerialDelegate(); ~ElectronSerialDelegate() override; @@ -48,6 +50,13 @@ class ElectronSerialDelegate : public content::SerialDelegate { void DeleteControllerForFrame(content::RenderFrameHost* render_frame_host); + // SerialChooserContext::PortObserver: + void OnPortAdded(const device::mojom::SerialPortInfo& port) override; + void OnPortRemoved(const device::mojom::SerialPortInfo& port) override; + void OnPortManagerConnectionError() override; + void OnPermissionRevoked(const url::Origin& origin) override {} + void OnSerialChooserContextShutdown() override; + private: SerialChooserController* ControllerForFrame( content::RenderFrameHost* render_frame_host); @@ -56,6 +65,13 @@ class ElectronSerialDelegate : public content::SerialDelegate { std::vector filters, content::SerialChooser::Callback callback); + base::ScopedObservation + port_observation_{this}; + base::ObserverList observer_list_; + std::unordered_map> controller_map_; diff --git a/shell/browser/serial/serial_chooser_context.cc b/shell/browser/serial/serial_chooser_context.cc index 356547f81a55f..57798ccf5692f 100644 --- a/shell/browser/serial/serial_chooser_context.cc +++ b/shell/browser/serial/serial_chooser_context.cc @@ -90,11 +90,13 @@ base::Value PortInfoToValue(const device::mojom::SerialPortInfo& port) { SerialChooserContext::SerialChooserContext(ElectronBrowserContext* context) : browser_context_(context) {} -SerialChooserContext::~SerialChooserContext() = default; - -void SerialChooserContext::OnPermissionRevoked(const url::Origin& origin) { - for (auto& observer : port_observer_list_) - observer.OnPermissionRevoked(origin); +SerialChooserContext::~SerialChooserContext() { + // Notify observers that the chooser context is about to be destroyed. + // Observers must remove themselves from the observer lists. + for (auto& observer : port_observer_list_) { + observer.OnSerialChooserContextShutdown(); + DCHECK(!port_observer_list_.HasObserver(&observer)); + } } void SerialChooserContext::GrantPortPermission( @@ -127,8 +129,6 @@ void SerialChooserContext::RevokePortPermissionWebInitiated( auto it = port_info_.find(token); if (it == port_info_.end()) return; - - return OnPermissionRevoked(origin); } // static diff --git a/shell/browser/serial/serial_chooser_context.h b/shell/browser/serial/serial_chooser_context.h index a0426c8b8f0c4..2424ed1e64f19 100644 --- a/shell/browser/serial/serial_chooser_context.h +++ b/shell/browser/serial/serial_chooser_context.h @@ -46,7 +46,12 @@ extern const char kUsbDriverKey[]; class SerialChooserContext : public KeyedService, public device::mojom::SerialPortManagerClient { public: - using PortObserver = content::SerialDelegate::Observer; + class PortObserver : public content::SerialDelegate::Observer { + public: + // Called when the SerialChooserContext is shutting down. Observers must + // remove themselves before returning. + virtual void OnSerialChooserContextShutdown() = 0; + }; explicit SerialChooserContext(ElectronBrowserContext* context); ~SerialChooserContext() override; @@ -55,9 +60,6 @@ class SerialChooserContext : public KeyedService, SerialChooserContext(const SerialChooserContext&) = delete; SerialChooserContext& operator=(const SerialChooserContext&) = delete; - // ObjectPermissionContextBase::PermissionObserver: - void OnPermissionRevoked(const url::Origin& origin); - // Serial-specific interface for granting and checking permissions. void GrantPortPermission(const url::Origin& origin, const device::mojom::SerialPortInfo& port, diff --git a/shell/browser/serial/serial_chooser_controller.cc b/shell/browser/serial/serial_chooser_controller.cc index 5adfc5e63c583..145b12b613a43 100644 --- a/shell/browser/serial/serial_chooser_controller.cc +++ b/shell/browser/serial/serial_chooser_controller.cc @@ -77,13 +77,11 @@ SerialChooserController::SerialChooserController( DCHECK(chooser_context_); chooser_context_->GetPortManager()->GetDevices(base::BindOnce( &SerialChooserController::OnGetDevices, weak_factory_.GetWeakPtr())); + observation_.Observe(chooser_context_.get()); } SerialChooserController::~SerialChooserController() { RunCallback(/*port=*/nullptr); - if (chooser_context_) { - chooser_context_->RemovePortObserver(this); - } } api::Session* SerialChooserController::GetSession() { @@ -117,7 +115,11 @@ void SerialChooserController::OnPortRemoved( } void SerialChooserController::OnPortManagerConnectionError() { - // TODO(nornagon/jkleinsc): report event + observation_.Reset(); +} + +void SerialChooserController::OnSerialChooserContextShutdown() { + observation_.Reset(); } void SerialChooserController::OnDeviceChosen(const std::string& port_id) { diff --git a/shell/browser/serial/serial_chooser_controller.h b/shell/browser/serial/serial_chooser_controller.h index 5635ea8bed743..761065763fbdb 100644 --- a/shell/browser/serial/serial_chooser_controller.h +++ b/shell/browser/serial/serial_chooser_controller.h @@ -48,6 +48,7 @@ class SerialChooserController final : public SerialChooserContext::PortObserver, void OnPortRemoved(const device::mojom::SerialPortInfo& port) override; void OnPortManagerConnectionError() override; void OnPermissionRevoked(const url::Origin& origin) override {} + void OnSerialChooserContextShutdown() override; private: api::Session* GetSession(); @@ -62,6 +63,12 @@ class SerialChooserController final : public SerialChooserContext::PortObserver, base::WeakPtr chooser_context_; + base::ScopedObservation + observation_{this}; + std::vector ports_; base::WeakPtr serial_delegate_; From 3777902abca7922d51b7864ae787aa1726fc73ec Mon Sep 17 00:00:00 2001 From: "electron-roller[bot]" <84116207+electron-roller[bot]@users.noreply.github.com> Date: Mon, 25 Jul 2022 19:57:37 -0400 Subject: [PATCH 05/30] chore: bump chromium to 104.0.5112.57 (20-x-y) (#35018) * chore: bump chromium in DEPS to 104.0.5112.57 * Trigger Build * chore: update patches Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com> Co-authored-by: John Kleinschmidt Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com> --- DEPS | 2 +- patches/chromium/can_create_window.patch | 10 +++++----- ...ebcontentscreationoverridden_with_full_params.patch | 4 ++-- patches/chromium/disable_color_correct_rendering.patch | 2 +- ...x_allow_guest_webcontents_to_enter_fullscreen.patch | 2 +- patches/chromium/frame_host_manager.patch | 2 +- patches/chromium/printing.patch | 4 ++-- ...ose_cursor_changes_to_the_webcontentsobserver.patch | 4 ++-- patches/chromium/web_contents.patch | 2 +- 9 files changed, 16 insertions(+), 16 deletions(-) diff --git a/DEPS b/DEPS index af343d390639e..4f5a485330044 100644 --- a/DEPS +++ b/DEPS @@ -2,7 +2,7 @@ gclient_gn_args_from = 'src' vars = { 'chromium_version': - '104.0.5112.48', + '104.0.5112.57', 'node_version': 'v16.15.0', 'nan_version': diff --git a/patches/chromium/can_create_window.patch b/patches/chromium/can_create_window.patch index 27a3a42e347bf..5d225a136d68c 100644 --- a/patches/chromium/can_create_window.patch +++ b/patches/chromium/can_create_window.patch @@ -21,10 +21,10 @@ index b857d325233430a5b79b3022d33823486e558309..83cc6ded4b3354f37b8e1dc0d9e4f328 &no_javascript_access); diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc -index 33f6efe4df4eecabcbcd08f908ed3ef12d056eb2..0e1e25d40ebf3ca92c57dfdfb52c5269198aa6f7 100644 +index 141f6e137f2d7e2a6779cad3e8729b9cfb557480..44c1f304cf2d88dca06ee1bd53c774022766ed35 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc -@@ -3947,6 +3947,14 @@ FrameTree* WebContentsImpl::CreateNewWindow( +@@ -3953,6 +3953,14 @@ FrameTree* WebContentsImpl::CreateNewWindow( } auto* new_contents_impl = new_contents.get(); @@ -39,7 +39,7 @@ index 33f6efe4df4eecabcbcd08f908ed3ef12d056eb2..0e1e25d40ebf3ca92c57dfdfb52c5269 new_contents_impl->GetController().SetSessionStorageNamespace( partition_config, session_storage_namespace); -@@ -3991,12 +3999,6 @@ FrameTree* WebContentsImpl::CreateNewWindow( +@@ -3997,12 +4005,6 @@ FrameTree* WebContentsImpl::CreateNewWindow( AddWebContentsDestructionObserver(new_contents_impl); } @@ -68,7 +68,7 @@ index 9c3a03faeee19f6f0a250680db36906ee64bf55a..0450700d02c74e047fa5124aa43b9f75 // Operation result when the renderer asks the browser to create a new window. diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc -index 69bcd725d0f86bf3b175fde86bd2dbd85b59f002..b72d89b19024a9074108dde4c5c9cd0f45b719bb 100644 +index c1beba6701e68255c212e56d78ae8259e2ffdab9..9f77c2a5df8f25876f875c4a7148d82c3dd79db8 100644 --- a/content/public/browser/content_browser_client.cc +++ b/content/public/browser/content_browser_client.cc @@ -595,6 +595,8 @@ bool ContentBrowserClient::CanCreateWindow( @@ -81,7 +81,7 @@ index 69bcd725d0f86bf3b175fde86bd2dbd85b59f002..b72d89b19024a9074108dde4c5c9cd0f bool opener_suppressed, bool* no_javascript_access) { diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h -index d0b7aed3162b8ea7673ab3ef31d2a3302f4e6456..6328fc21548f2b8277b461f9938dbcc50f6853f1 100644 +index a49794184baa977ddf03cd911f8d8d7d671df65f..7997c0de85315e30b350316f33e598a0221d583f 100644 --- a/content/public/browser/content_browser_client.h +++ b/content/public/browser/content_browser_client.h @@ -164,6 +164,7 @@ class NetworkService; diff --git a/patches/chromium/chore_provide_iswebcontentscreationoverridden_with_full_params.patch b/patches/chromium/chore_provide_iswebcontentscreationoverridden_with_full_params.patch index 29f2ab25c3a1d..c3f2b40ce261f 100644 --- a/patches/chromium/chore_provide_iswebcontentscreationoverridden_with_full_params.patch +++ b/patches/chromium/chore_provide_iswebcontentscreationoverridden_with_full_params.patch @@ -246,10 +246,10 @@ index c6bd5c19f8a7ceec17c9e32af5296a9617f3a619..02199b439fba7fdc617b7f7980d958b7 void AddNewContents(content::WebContents* source, std::unique_ptr new_contents, diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc -index 889da8724da515ab7e6b412fbaff434eb53289dc..7dba296aaa55b9aa6026ccdf288171f701601f46 100644 +index c4c6159fa9bb94b340a5fbc545e77ac696e8cc52..6ca8c2510a42b50651621831474da6aee783e4c0 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc -@@ -3880,8 +3880,7 @@ FrameTree* WebContentsImpl::CreateNewWindow( +@@ -3886,8 +3886,7 @@ FrameTree* WebContentsImpl::CreateNewWindow( if (delegate_ && delegate_->IsWebContentsCreationOverridden( source_site_instance, params.window_container_type, diff --git a/patches/chromium/disable_color_correct_rendering.patch b/patches/chromium/disable_color_correct_rendering.patch index 7d3fef6f99ffd..48d319f48a0a3 100644 --- a/patches/chromium/disable_color_correct_rendering.patch +++ b/patches/chromium/disable_color_correct_rendering.patch @@ -20,7 +20,7 @@ to deal with color spaces. That is being tracked at https://crbug.com/634542 and https://crbug.com/711107. diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc -index 5ab61f6045aea2bf35ed25bd05270f044cbd8dd6..85875fe07d9eaf60406f60e6ffcd10dd06a265a6 100644 +index aca208728d0dae78e57bf4b7f0af46ed5ad73e68..3ace9a5d0368fd1bd5116f4ca1057c7887a611c5 100644 --- a/cc/trees/layer_tree_host_impl.cc +++ b/cc/trees/layer_tree_host_impl.cc @@ -1852,6 +1852,9 @@ void LayerTreeHostImpl::SetIsLikelyToRequireADraw( diff --git a/patches/chromium/fix_allow_guest_webcontents_to_enter_fullscreen.patch b/patches/chromium/fix_allow_guest_webcontents_to_enter_fullscreen.patch index 475a66730aeda..c0a94820380de 100644 --- a/patches/chromium/fix_allow_guest_webcontents_to_enter_fullscreen.patch +++ b/patches/chromium/fix_allow_guest_webcontents_to_enter_fullscreen.patch @@ -6,7 +6,7 @@ Subject: fix: allow guest webcontents to enter fullscreen This can be upstreamed, a guest webcontents can't technically become the focused webContents. This DCHECK should allow all guest webContents to request fullscreen entrance. diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc -index 050e59567dfb72833d96a9331329b8235d0a4a07..3f740e42f2ca869c4f19632a5cfee6142702f02a 100644 +index 314459717b239f302cdd6485752f7c67e2d1b22b..1afc4f2064c89c5d586a41c7e4426cd91ea52da2 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc @@ -3417,7 +3417,7 @@ void WebContentsImpl::EnterFullscreenMode( diff --git a/patches/chromium/frame_host_manager.patch b/patches/chromium/frame_host_manager.patch index 8fa0bd430fe5a..d09d661112ce3 100644 --- a/patches/chromium/frame_host_manager.patch +++ b/patches/chromium/frame_host_manager.patch @@ -20,7 +20,7 @@ index 398358851f4ec3d1373091c352fe864b8901f08b..0fadcf6eb5aa9e7e6ca32ec252f1722a } diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h -index 6328fc21548f2b8277b461f9938dbcc50f6853f1..90058e16373ce92a9eede27f13010417cf51dae2 100644 +index 7997c0de85315e30b350316f33e598a0221d583f..e4a5c9fab5238f3e99fe0d44f1a5b47d059540cc 100644 --- a/content/public/browser/content_browser_client.h +++ b/content/public/browser/content_browser_client.h @@ -270,6 +270,11 @@ class CONTENT_EXPORT ContentBrowserClient { diff --git a/patches/chromium/printing.patch b/patches/chromium/printing.patch index 0cdf718d82c3d..a229104e82827 100644 --- a/patches/chromium/printing.patch +++ b/patches/chromium/printing.patch @@ -111,7 +111,7 @@ index 1e158ecd686e775f656d5a05a9d916ce8f075fa8..20613012d1e6f435c3211d78ec311cf0 void PrintJobWorkerOop::UnregisterServiceManagerClient() { diff --git a/chrome/browser/printing/print_view_manager_base.cc b/chrome/browser/printing/print_view_manager_base.cc -index e665eb42fad5f47b1643315d2cdcdf2eb66b069d..810c190e60bfc1bab4dcc5385c9cb30ae491a0fb 100644 +index 4bd871e5cadc693aea6e8c71b3fe3296b743d9ec..560e84fcddf1108114cc863ac0bd9cb7f7f4da4c 100644 --- a/chrome/browser/printing/print_view_manager_base.cc +++ b/chrome/browser/printing/print_view_manager_base.cc @@ -30,10 +30,10 @@ @@ -393,7 +393,7 @@ index e665eb42fad5f47b1643315d2cdcdf2eb66b069d..810c190e60bfc1bab4dcc5385c9cb30a return true; if (!cookie) { -@@ -1067,7 +1113,7 @@ void PrintViewManagerBase::SendPrintingEnabled(bool enabled, +@@ -1069,7 +1115,7 @@ void PrintViewManagerBase::SendPrintingEnabled(bool enabled, } void PrintViewManagerBase::CompletePrintNow(content::RenderFrameHost* rfh) { diff --git a/patches/chromium/refactor_expose_cursor_changes_to_the_webcontentsobserver.patch b/patches/chromium/refactor_expose_cursor_changes_to_the_webcontentsobserver.patch index 3150d3c2096aa..aab1a48a233fe 100644 --- a/patches/chromium/refactor_expose_cursor_changes_to_the_webcontentsobserver.patch +++ b/patches/chromium/refactor_expose_cursor_changes_to_the_webcontentsobserver.patch @@ -43,10 +43,10 @@ index 273750752cdef18ccd7d54b9b28c524375bb3e8d..3eec2e5c14186b39a67ca8ad410a3268 void RenderWidgetHostImpl::ShowContextMenuAtPoint( diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc -index 0e1e25d40ebf3ca92c57dfdfb52c5269198aa6f7..889da8724da515ab7e6b412fbaff434eb53289dc 100644 +index 44c1f304cf2d88dca06ee1bd53c774022766ed35..c4c6159fa9bb94b340a5fbc545e77ac696e8cc52 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc -@@ -4526,6 +4526,11 @@ TextInputManager* WebContentsImpl::GetTextInputManager() { +@@ -4532,6 +4532,11 @@ TextInputManager* WebContentsImpl::GetTextInputManager() { return text_input_manager_.get(); } diff --git a/patches/chromium/web_contents.patch b/patches/chromium/web_contents.patch index 5349fb89f413e..58642bb4583a6 100644 --- a/patches/chromium/web_contents.patch +++ b/patches/chromium/web_contents.patch @@ -9,7 +9,7 @@ is needed for OSR. Originally landed in https://github.com/electron/libchromiumcontent/pull/226. diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc -index 7dba296aaa55b9aa6026ccdf288171f701601f46..050e59567dfb72833d96a9331329b8235d0a4a07 100644 +index 6ca8c2510a42b50651621831474da6aee783e4c0..314459717b239f302cdd6485752f7c67e2d1b22b 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc @@ -3036,6 +3036,13 @@ void WebContentsImpl::Init(const WebContents::CreateParams& params, From 77d561a8a60b0a91a622d2182a2a5ff63b540e25 Mon Sep 17 00:00:00 2001 From: "trop[bot]" <37223003+trop[bot]@users.noreply.github.com> Date: Tue, 26 Jul 2022 17:37:23 +0900 Subject: [PATCH 06/30] fix: merge crash annotations instead of overwriting (#35045) ElectronCrashReporterClient::GetProcessSimpleAnnotations() merges annotations provided as argument with global_annotations_, preserving useful information. Co-authored-by: Alexander Petrov --- shell/app/electron_crash_reporter_client.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/shell/app/electron_crash_reporter_client.cc b/shell/app/electron_crash_reporter_client.cc index 245c55c90a13a..237c90c16f33a 100644 --- a/shell/app/electron_crash_reporter_client.cc +++ b/shell/app/electron_crash_reporter_client.cc @@ -190,7 +190,9 @@ bool ElectronCrashReporterClient::GetShouldCompressUploads() { void ElectronCrashReporterClient::GetProcessSimpleAnnotations( std::map* annotations) { - *annotations = global_annotations_; + for (auto&& pair : global_annotations_) { + (*annotations)[pair.first] = pair.second; + } (*annotations)["prod"] = ELECTRON_PRODUCT_NAME; (*annotations)["ver"] = ELECTRON_VERSION_STRING; } From 09c4fdd6d0a465065adbf46fdda0d6a1738aa2e3 Mon Sep 17 00:00:00 2001 From: "trop[bot]" <37223003+trop[bot]@users.noreply.github.com> Date: Tue, 26 Jul 2022 18:24:45 +0200 Subject: [PATCH 07/30] docs: Add missing link to tutorial page (#35041) Add missing link to tutorial page Co-authored-by: Mike Lee --- docs/tutorial/introduction.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/tutorial/introduction.md b/docs/tutorial/introduction.md index 8091434c01b0f..b12cabd60895d 100644 --- a/docs/tutorial/introduction.md +++ b/docs/tutorial/introduction.md @@ -66,6 +66,7 @@ Are you getting stuck anywhere? Here are a few links to places to look: +[tutorial]: tutorial-1-prerequisites.md [api documentation]: ../api/app.md [chromium]: https://www.chromium.org/ [discord]: https://discord.com/invite/APGC3k5yaH From 215ae2b012c6adaf31cb5931dfc1790a199020a3 Mon Sep 17 00:00:00 2001 From: "trop[bot]" <37223003+trop[bot]@users.noreply.github.com> Date: Wed, 27 Jul 2022 11:09:11 +0200 Subject: [PATCH 08/30] fix: crash on startup in X11 (#35092) Fixes #34996. Co-authored-by: Charles Kerr --- shell/browser/electron_browser_main_parts.cc | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/shell/browser/electron_browser_main_parts.cc b/shell/browser/electron_browser_main_parts.cc index feaa3b04fe603..5f2e3fc5a49c8 100644 --- a/shell/browser/electron_browser_main_parts.cc +++ b/shell/browser/electron_browser_main_parts.cc @@ -278,12 +278,6 @@ void ElectronBrowserMainParts::PostEarlyInitialization() { } int ElectronBrowserMainParts::PreCreateThreads() { -#if defined(USE_AURA) - if (!display::Screen::GetScreen()) { - screen_ = views::CreateDesktopScreen(); - } -#endif - if (!views::LayoutProvider::Get()) layout_provider_ = std::make_unique(); @@ -314,6 +308,14 @@ int ElectronBrowserMainParts::PreCreateThreads() { // Load resources bundle according to locale. std::string loaded_locale = LoadResourceBundle(locale); +#if defined(USE_AURA) + // NB: must be called _after_ locale resource bundle is loaded, + // because ui lib makes use of it in X11 + if (!display::Screen::GetScreen()) { + screen_ = views::CreateDesktopScreen(); + } +#endif + // Initialize the app locale. std::string app_locale = l10n_util::GetApplicationLocale(loaded_locale); ElectronBrowserClient::SetApplicationLocale(app_locale); From d8edf84cfc10e6ed4a6d610d72cb9a5aadd1c4c0 Mon Sep 17 00:00:00 2001 From: Devin Foley Date: Wed, 27 Jul 2022 02:09:45 -0700 Subject: [PATCH 09/30] fix: Make disable_color_correct_rendering patch work again (#35087) Fix disable_color_correct_rendering patch. --- .../disable_color_correct_rendering.patch | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/patches/chromium/disable_color_correct_rendering.patch b/patches/chromium/disable_color_correct_rendering.patch index 48d319f48a0a3..57cb5e62af3b6 100644 --- a/patches/chromium/disable_color_correct_rendering.patch +++ b/patches/chromium/disable_color_correct_rendering.patch @@ -20,14 +20,15 @@ to deal with color spaces. That is being tracked at https://crbug.com/634542 and https://crbug.com/711107. diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc -index aca208728d0dae78e57bf4b7f0af46ed5ad73e68..3ace9a5d0368fd1bd5116f4ca1057c7887a611c5 100644 +index aca208728d0dae78e57bf4b7f0af46ed5ad73e68..2afef2fb0d3890bdada7d5785a4a48494d580cab 100644 --- a/cc/trees/layer_tree_host_impl.cc +++ b/cc/trees/layer_tree_host_impl.cc -@@ -1852,6 +1852,9 @@ void LayerTreeHostImpl::SetIsLikelyToRequireADraw( +@@ -1852,6 +1852,10 @@ void LayerTreeHostImpl::SetIsLikelyToRequireADraw( TargetColorParams LayerTreeHostImpl::GetTargetColorParams( gfx::ContentColorUsage content_color_usage) const { TargetColorParams params; + if (!settings_.enable_color_correct_rendering) { ++ params.color_space = gfx::ColorSpace(); + return params; + } @@ -112,7 +113,7 @@ index 73a50b19f8bf75119b6af7698cdf7d569c504e77..9fdc3d5235a95cfc9ef3b94ba9c19630 sandbox::policy::switches::kDisableSeccompFilterSandbox, sandbox::policy::switches::kNoSandbox, diff --git a/third_party/blink/renderer/platform/graphics/canvas_color_params.cc b/third_party/blink/renderer/platform/graphics/canvas_color_params.cc -index 75d7af9a79d4e7f2cd39e45496ab5fff66407638..b4ddafdd126edd16172f00448bbbd56eaf509b1f 100644 +index 75d7af9a79d4e7f2cd39e45496ab5fff66407638..35b0bb908245330fbdc5205caa3299bf6fd8f7b4 100644 --- a/third_party/blink/renderer/platform/graphics/canvas_color_params.cc +++ b/third_party/blink/renderer/platform/graphics/canvas_color_params.cc @@ -4,6 +4,7 @@ @@ -131,7 +132,18 @@ index 75d7af9a79d4e7f2cd39e45496ab5fff66407638..b4ddafdd126edd16172f00448bbbd56e namespace blink { -@@ -118,6 +120,11 @@ uint8_t CanvasColorParams::BytesPerPixel() const { +@@ -19,6 +21,10 @@ namespace blink { + // Level 4 specification. + gfx::ColorSpace PredefinedColorSpaceToGfxColorSpace( + PredefinedColorSpace color_space) { ++ auto* cmd_line = base::CommandLine::ForCurrentProcess(); ++ if (cmd_line->HasSwitch(switches::kDisableColorCorrectRendering)) { ++ return gfx::ColorSpace(); ++ } + switch (color_space) { + case PredefinedColorSpace::kSRGB: + return gfx::ColorSpace::CreateSRGB(); +@@ -118,6 +124,11 @@ uint8_t CanvasColorParams::BytesPerPixel() const { } gfx::ColorSpace CanvasColorParams::GetStorageGfxColorSpace() const { From c10922f15f08d54c1d67c0fa8a1a57e1cde8c3af Mon Sep 17 00:00:00 2001 From: "trop[bot]" <37223003+trop[bot]@users.noreply.github.com> Date: Wed, 27 Jul 2022 11:13:15 +0200 Subject: [PATCH 10/30] fix: use win_clang_x64 binary for x86 extract symbols (#35091) fix: use win_clang_x64 for x86 extract symbols Co-authored-by: Keeley Hammond --- appveyor.yml | 9 +++------ build/extract_symbols.gni | 6 +++++- script/release/release.js | 5 ++--- script/release/uploaders/upload.py | 14 ++++++-------- 4 files changed, 16 insertions(+), 18 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 140ac66b20c7f..0282c36e750c2 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -170,19 +170,16 @@ build_script: - python %LOCAL_GOMA_DIR%\goma_ctl.py stat - python3 electron/build/profile_toolchain.py --output-json=out/Default/windows_toolchain_profile.json - 7z a node_headers.zip out\Default\gen\node_headers - # Temporarily disable symbol generation on 32-bit Windows due to failures - ps: >- - if ($env:GN_CONFIG -eq 'release' -And $env:TARGET_ARCH -ne 'ia32') { + if ($env:GN_CONFIG -eq 'release') { # 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 } - ps: >- if ($env:GN_CONFIG -eq 'release') { - if ($env:TARGET_ARCH -ne 'ia32') { - python electron\script\zip-symbols.py - appveyor-retry appveyor PushArtifact out/Default/symbols.zip - } + python electron\script\zip-symbols.py + appveyor-retry appveyor PushArtifact out/Default/symbols.zip } else { # It's useful to have pdb files when debugging testing builds that are # built on CI. diff --git a/build/extract_symbols.gni b/build/extract_symbols.gni index e3fa2a30f4ca0..2f98aa466ba15 100644 --- a/build/extract_symbols.gni +++ b/build/extract_symbols.gni @@ -24,7 +24,11 @@ template("extract_symbols") { assert(defined(invoker.binary), "Need binary to dump") assert(defined(invoker.symbol_dir), "Need directory for symbol output") - dump_syms_label = "//third_party/breakpad:dump_syms($host_toolchain)" + if (host_os == "win" && target_cpu == "x86") { + dump_syms_label = "//third_party/breakpad:dump_syms(//build/toolchain/win:win_clang_x64)" + } else { + dump_syms_label = "//third_party/breakpad:dump_syms($host_toolchain)" + } dump_syms_binary = get_label_info(dump_syms_label, "root_out_dir") + "/dump_syms$_host_executable_suffix" diff --git a/script/release/release.js b/script/release/release.js index e89d7ba920245..c3c8d6363b120 100755 --- a/script/release/release.js +++ b/script/release/release.js @@ -128,9 +128,8 @@ function assetsForVersion (version, validatingRelease) { `electron-${version}-mas-arm64-dsym-snapshot.zip`, `electron-${version}-mas-arm64-symbols.zip`, `electron-${version}-mas-arm64.zip`, - // TODO(vertedinde) Symbol generation on 32-bit Windows is temporarily disabled due to CI failures - // `electron-${version}-win32-ia32-pdb.zip`, - // `electron-${version}-win32-ia32-symbols.zip`, + `electron-${version}-win32-ia32-pdb.zip`, + `electron-${version}-win32-ia32-symbols.zip`, `electron-${version}-win32-ia32.zip`, `electron-${version}-win32-x64-pdb.zip`, `electron-${version}-win32-x64-symbols.zip`, diff --git a/script/release/uploaders/upload.py b/script/release/uploaders/upload.py index 69c4bbfa5720d..a73955786e47c 100755 --- a/script/release/uploaders/upload.py +++ b/script/release/uploaders/upload.py @@ -76,10 +76,9 @@ def main(): shutil.copy2(os.path.join(OUT_DIR, 'dist.zip'), electron_zip) upload_electron(release, electron_zip, args) if get_target_arch() != 'mips64el': - if (get_target_arch() != 'ia32' or PLATFORM != 'win32'): - symbols_zip = os.path.join(OUT_DIR, SYMBOLS_NAME) - shutil.copy2(os.path.join(OUT_DIR, 'symbols.zip'), symbols_zip) - upload_electron(release, symbols_zip, args) + symbols_zip = os.path.join(OUT_DIR, SYMBOLS_NAME) + shutil.copy2(os.path.join(OUT_DIR, 'symbols.zip'), symbols_zip) + upload_electron(release, symbols_zip, args) if PLATFORM == 'darwin': if get_platform_key() == 'darwin' and get_target_arch() == 'x64': api_path = os.path.join(ELECTRON_DIR, 'electron-api.json') @@ -96,10 +95,9 @@ def main(): shutil.copy2(os.path.join(OUT_DIR, 'dsym-snapshot.zip'), dsym_snaphot_zip) upload_electron(release, dsym_snaphot_zip, args) elif PLATFORM == 'win32': - if get_target_arch() != 'ia32': - pdb_zip = os.path.join(OUT_DIR, PDB_NAME) - shutil.copy2(os.path.join(OUT_DIR, 'pdb.zip'), pdb_zip) - upload_electron(release, pdb_zip, args) + pdb_zip = os.path.join(OUT_DIR, PDB_NAME) + shutil.copy2(os.path.join(OUT_DIR, 'pdb.zip'), pdb_zip) + upload_electron(release, pdb_zip, args) elif PLATFORM == 'linux': debug_zip = os.path.join(OUT_DIR, DEBUG_NAME) shutil.copy2(os.path.join(OUT_DIR, 'debug.zip'), debug_zip) From 7b1872dafed5e04b7b54f5b69011da4fc760b705 Mon Sep 17 00:00:00 2001 From: "trop[bot]" <37223003+trop[bot]@users.noreply.github.com> Date: Wed, 27 Jul 2022 11:14:21 +0200 Subject: [PATCH 11/30] fix: allow setsize to be called within a move or resize for preventDefault (#35084) fix: #34599 allow setsize to be called within a move or resize for preventDefault Co-authored-by: Ian German Mesner --- shell/browser/native_window_views.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/shell/browser/native_window_views.cc b/shell/browser/native_window_views.cc index 63070c633724a..51ccfef8c689f 100644 --- a/shell/browser/native_window_views.cc +++ b/shell/browser/native_window_views.cc @@ -729,7 +729,6 @@ void NativeWindowViews::SetBounds(const gfx::Rect& bounds, bool animate) { #if BUILDFLAG(IS_WIN) if (is_moving_ || is_resizing_) { pending_bounds_change_ = bounds; - return; } #endif From 5f1c3b4d1309b3f46c9062f3cb1b83412d23c011 Mon Sep 17 00:00:00 2001 From: "trop[bot]" <37223003+trop[bot]@users.noreply.github.com> Date: Wed, 27 Jul 2022 11:42:49 +0200 Subject: [PATCH 12/30] fix: handle WCO pressed state when going maximized -> minimized (#35074) Co-authored-by: Shelley Vohr --- shell/browser/native_window_views.h | 1 + shell/browser/native_window_views_win.cc | 20 +++++++++++++------- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/shell/browser/native_window_views.h b/shell/browser/native_window_views.h index 5454aafaec053..6672e3c2c7fcf 100644 --- a/shell/browser/native_window_views.h +++ b/shell/browser/native_window_views.h @@ -225,6 +225,7 @@ class NativeWindowViews : public NativeWindow, #if BUILDFLAG(IS_WIN) void HandleSizeEvent(WPARAM w_param, LPARAM l_param); + void ResetWindowControls(); void SetForwardMouseMessages(bool forward); static LRESULT CALLBACK SubclassProc(HWND hwnd, UINT msg, diff --git a/shell/browser/native_window_views_win.cc b/shell/browser/native_window_views_win.cc index 9c0b54393958b..dc6f089d06bf6 100644 --- a/shell/browser/native_window_views_win.cc +++ b/shell/browser/native_window_views_win.cc @@ -415,6 +415,7 @@ void NativeWindowViews::HandleSizeEvent(WPARAM w_param, LPARAM l_param) { last_window_state_ != ui::SHOW_STATE_MAXIMIZED) { last_window_state_ = ui::SHOW_STATE_MAXIMIZED; NotifyWindowMaximize(); + ResetWindowControls(); } else if (w_param == SIZE_MINIMIZED && last_window_state_ != ui::SHOW_STATE_MINIMIZED) { last_window_state_ = ui::SHOW_STATE_MINIMIZED; @@ -440,18 +441,23 @@ void NativeWindowViews::HandleSizeEvent(WPARAM w_param, LPARAM l_param) { default: break; } - // If a given window was minimized/maximized and has since been - // restored, ensure the WCO buttons are set to normal state. - auto* ncv = widget()->non_client_view(); - if (IsWindowControlsOverlayEnabled() && ncv) { - auto* frame_view = static_cast(ncv->frame_view()); - frame_view->caption_button_container()->ResetWindowControls(); - } + ResetWindowControls(); break; } } } +void NativeWindowViews::ResetWindowControls() { + // If a given window was minimized and has since been + // unminimized (restored/maximized), ensure the WCO buttons + // are reset to their default unpressed state. + auto* ncv = widget()->non_client_view(); + if (IsWindowControlsOverlayEnabled() && ncv) { + auto* frame_view = static_cast(ncv->frame_view()); + frame_view->caption_button_container()->ResetWindowControls(); + } +} + void NativeWindowViews::SetForwardMouseMessages(bool forward) { if (forward && !forwarding_mouse_messages_) { forwarding_mouse_messages_ = true; From 816e8e804c7817f650fe9a37b85027079f2748e9 Mon Sep 17 00:00:00 2001 From: Sudowoodo Release Bot <88427002+sudowoodo-release-bot[bot]@users.noreply.github.com> Date: Thu, 28 Jul 2022 06:32:12 -0700 Subject: [PATCH 13/30] Bump v20.0.0-beta.13 --- ELECTRON_VERSION | 2 +- package.json | 2 +- shell/browser/resources/win/electron.rc | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ELECTRON_VERSION b/ELECTRON_VERSION index 5b6eaf4f52932..ae67aca6aa876 100644 --- a/ELECTRON_VERSION +++ b/ELECTRON_VERSION @@ -1 +1 @@ -20.0.0-beta.12 \ No newline at end of file +20.0.0-beta.13 \ No newline at end of file diff --git a/package.json b/package.json index bf27955f56d4d..07732835c4d49 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "electron", - "version": "20.0.0-beta.12", + "version": "20.0.0-beta.13", "repository": "https://github.com/electron/electron", "description": "Build cross platform desktop apps with JavaScript, HTML, and CSS", "devDependencies": { diff --git a/shell/browser/resources/win/electron.rc b/shell/browser/resources/win/electron.rc index 065a76b12b917..a1c37a1b9afc8 100644 --- a/shell/browser/resources/win/electron.rc +++ b/shell/browser/resources/win/electron.rc @@ -50,8 +50,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 20,0,0,12 - PRODUCTVERSION 20,0,0,12 + FILEVERSION 20,0,0,13 + PRODUCTVERSION 20,0,0,13 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L From 2f9414dcc4a5ca9d920c82b267f7688ec3226092 Mon Sep 17 00:00:00 2001 From: "electron-roller[bot]" <84116207+electron-roller[bot]@users.noreply.github.com> Date: Thu, 28 Jul 2022 16:28:16 -0400 Subject: [PATCH 14/30] chore: bump chromium to 104.0.5112.65 (20-x-y) (#35114) * chore: bump chromium in DEPS to 104.0.5112.65 * chore: update patches * test: remove duplicate test that is causing hang in Windows (#35071) (cherry picked from commit 182ab9ad7646ccf42b25e539990f8cb0c40f68b5) Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com> Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com> Co-authored-by: John Kleinschmidt --- DEPS | 2 +- patches/chromium/can_create_window.patch | 4 ++-- .../chromium/expose_setuseragent_on_networkcontext.patch | 4 ++-- ...vice_allow_remote_certificate_verification_logic.patch | 4 ++-- patches/chromium/webview_fullscreen.patch | 4 ++-- spec/chromium-spec.js | 8 -------- 6 files changed, 9 insertions(+), 17 deletions(-) diff --git a/DEPS b/DEPS index 4f5a485330044..2431e3e4b9ab9 100644 --- a/DEPS +++ b/DEPS @@ -2,7 +2,7 @@ gclient_gn_args_from = 'src' vars = { 'chromium_version': - '104.0.5112.57', + '104.0.5112.65', 'node_version': 'v16.15.0', 'nan_version': diff --git a/patches/chromium/can_create_window.patch b/patches/chromium/can_create_window.patch index 5d225a136d68c..fce3cfc7168cb 100644 --- a/patches/chromium/can_create_window.patch +++ b/patches/chromium/can_create_window.patch @@ -9,10 +9,10 @@ potentially prevent a window from being created. TODO(loc): this patch is currently broken. diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc -index b857d325233430a5b79b3022d33823486e558309..83cc6ded4b3354f37b8e1dc0d9e4f3289863fa09 100644 +index 28c7136b21d058e3daa7570af558f5a415b000a7..d1b7d15a7e4dede5b030e4ae9fb2ab8aa8196446 100644 --- a/content/browser/renderer_host/render_frame_host_impl.cc +++ b/content/browser/renderer_host/render_frame_host_impl.cc -@@ -6966,6 +6966,7 @@ void RenderFrameHostImpl::CreateNewWindow( +@@ -7006,6 +7006,7 @@ void RenderFrameHostImpl::CreateNewWindow( last_committed_origin_, params->window_container_type, params->target_url, params->referrer.To(), params->frame_name, params->disposition, *params->features, diff --git a/patches/chromium/expose_setuseragent_on_networkcontext.patch b/patches/chromium/expose_setuseragent_on_networkcontext.patch index aa18104b8966a..8654435fbf6d5 100644 --- a/patches/chromium/expose_setuseragent_on_networkcontext.patch +++ b/patches/chromium/expose_setuseragent_on_networkcontext.patch @@ -33,10 +33,10 @@ index 14c71cc69388da46f62d9835e2a06fef0870da02..9481ea08401ae29ae9c1d960491b05b3 } // namespace net diff --git a/services/network/network_context.cc b/services/network/network_context.cc -index b8560d71365759680fd5e49d311b19df41d6fb3b..1c0451cd2f2f7e1aeb182fb4f803cb960b63ef63 100644 +index c90733c3f463a2b9a3f142a739061fa65d6905b8..372c00c77c4320847313bdba49ade7ae8ed3f699 100644 --- a/services/network/network_context.cc +++ b/services/network/network_context.cc -@@ -1412,6 +1412,13 @@ void NetworkContext::SetNetworkConditions( +@@ -1414,6 +1414,13 @@ void NetworkContext::SetNetworkConditions( std::move(network_conditions)); } diff --git a/patches/chromium/network_service_allow_remote_certificate_verification_logic.patch b/patches/chromium/network_service_allow_remote_certificate_verification_logic.patch index 8b28ad792f4db..6689fc2b9f740 100644 --- a/patches/chromium/network_service_allow_remote_certificate_verification_logic.patch +++ b/patches/chromium/network_service_allow_remote_certificate_verification_logic.patch @@ -7,7 +7,7 @@ This adds a callback from the network service that's used to implement session.setCertificateVerifyCallback. diff --git a/services/network/network_context.cc b/services/network/network_context.cc -index 89bbba4956965fda7743f122d05fb5dfc3862e72..b8560d71365759680fd5e49d311b19df41d6fb3b 100644 +index 13fc1b901b7b356836024c79db99ac2f3da431c9..c90733c3f463a2b9a3f142a739061fa65d6905b8 100644 --- a/services/network/network_context.cc +++ b/services/network/network_context.cc @@ -128,6 +128,11 @@ @@ -128,7 +128,7 @@ index 89bbba4956965fda7743f122d05fb5dfc3862e72..b8560d71365759680fd5e49d311b19df void NetworkContext::CreateURLLoaderFactory( mojo::PendingReceiver receiver, mojom::URLLoaderFactoryParamsPtr params) { -@@ -2307,6 +2404,9 @@ URLRequestContextOwner NetworkContext::MakeURLRequestContext( +@@ -2309,6 +2406,9 @@ URLRequestContextOwner NetworkContext::MakeURLRequestContext( std::move(cert_verifier)); cert_verifier = base::WrapUnique(cert_verifier_with_trust_anchors_); #endif // BUILDFLAG(IS_CHROMEOS) diff --git a/patches/chromium/webview_fullscreen.patch b/patches/chromium/webview_fullscreen.patch index e363b1ef4a0ed..4bc9f0cc48298 100644 --- a/patches/chromium/webview_fullscreen.patch +++ b/patches/chromium/webview_fullscreen.patch @@ -14,10 +14,10 @@ Note that we also need to manually update embedder's `api::WebContents::IsFullscreenForTabOrPending` value. diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc -index 83cc6ded4b3354f37b8e1dc0d9e4f3289863fa09..269a7b63c8afa14fbf3b48de020c89ea22f50a83 100644 +index d1b7d15a7e4dede5b030e4ae9fb2ab8aa8196446..3b14fdd3664970072f173ca494ccb924f4d55fff 100644 --- a/content/browser/renderer_host/render_frame_host_impl.cc +++ b/content/browser/renderer_host/render_frame_host_impl.cc -@@ -6325,6 +6325,15 @@ void RenderFrameHostImpl::EnterFullscreen( +@@ -6365,6 +6365,15 @@ void RenderFrameHostImpl::EnterFullscreen( notified_instances.insert(parent_site_instance); } diff --git a/spec/chromium-spec.js b/spec/chromium-spec.js index afcc2b668a756..a28546014aff0 100644 --- a/spec/chromium-spec.js +++ b/spec/chromium-spec.js @@ -63,14 +63,6 @@ describe('chromium feature', () => { }); describe('window.open', () => { - it('accepts "nodeIntegration" as feature', async () => { - const message = waitForEvent(window, 'message'); - const b = window.open(`file://${fixtures}/pages/window-opener-node.html`, '', 'nodeIntegration=no,show=no'); - const event = await message; - b.close(); - expect(event.data.isProcessGlobalUndefined).to.be.true(); - }); - it('inherit options of parent window', async () => { const message = waitForEvent(window, 'message'); const b = window.open(`file://${fixtures}/pages/window-open-size.html`, '', 'show=no'); From ecdfca8f1397b9e18e9d2a585913f42bb25c9140 Mon Sep 17 00:00:00 2001 From: John Kleinschmidt Date: Fri, 29 Jul 2022 01:17:10 -0400 Subject: [PATCH 15/30] ci: switch to GHA for WOA (#35120) ci: switch to GHA for WOA (#35109) * ci: switch to GHA for WOA Co-authored-by: Shelley Vohr (cherry picked from commit 674596d11e5ad72b6651073619d282fbfea74ae1) --- .github/workflows/electron_woa_testing.yml | 166 +++++++++++++++++++++ appveyor.yml | 2 +- azure-pipelines-arm.yml | 121 --------------- azure-pipelines-woa.yml | 130 ---------------- script/release/ci-release-build.js | 97 +++--------- vsts-arm-test-steps.yml | 110 -------------- vsts-arm32v7.yml | 13 -- vsts-arm64v8.yml | 13 -- 8 files changed, 188 insertions(+), 464 deletions(-) create mode 100644 .github/workflows/electron_woa_testing.yml delete mode 100644 azure-pipelines-arm.yml delete mode 100644 azure-pipelines-woa.yml delete mode 100644 vsts-arm-test-steps.yml delete mode 100644 vsts-arm32v7.yml delete mode 100644 vsts-arm64v8.yml diff --git a/.github/workflows/electron_woa_testing.yml b/.github/workflows/electron_woa_testing.yml new file mode 100644 index 0000000000000..1c20eda0aefb6 --- /dev/null +++ b/.github/workflows/electron_woa_testing.yml @@ -0,0 +1,166 @@ +name: Electron WOA Testing + +on: + push: + branches: '**' + workflow_dispatch: + inputs: + appveyor_job_id: + description: 'Job Id of Appveyor WOA job to test' + type: text + required: true + +jobs: + electron-woa-testing: + + runs-on: [self-hosted, woa] + + permissions: + checks: write + pull-requests: write + + steps: + - uses: LouisBrunner/checks-action@v1.1.1 + if: ${{ github.event_name == 'push' && github.repository == 'electron/electron' }} + with: + token: ${{ secrets.GITHUB_TOKEN }} + name: electron-woa-testing + status: in_progress + - name: Clean Workspace + if: ${{ github.event_name == 'workflow_dispatch' }} + run: | + Remove-Item * -Recurse -Force + shell: powershell + - name: Checkout + uses: actions/checkout@v3 + if: ${{ github.event_name == 'workflow_dispatch' }} + with: + path: src\electron + fetch-depth: 0 + - name: Yarn install + if: ${{ github.event_name == 'workflow_dispatch' }} + run: | + cd src\electron + node script/yarn.js install --frozen-lockfile + - name: Download and extract dist.zip for test + if: ${{ github.event_name == 'workflow_dispatch' }} + run: | + $localArtifactPath = "$pwd\dist.zip" + $serverArtifactPath = "https://ci.appveyor.com/api/buildjobs/${{ inputs.appveyor_job_id }}/artifacts/dist.zip" + Invoke-RestMethod -Method Get -Uri $serverArtifactPath -OutFile $localArtifactPath -Headers @{ "Authorization" = "Bearer ${{ secrets.APPVEYOR_TOKEN }}" } + & "${env:ProgramFiles(x86)}\7-Zip\7z.exe" x -osrc\out\Default -y $localArtifactPath + shell: powershell + - name: Download and extract native test executables for test + if: ${{ github.event_name == 'workflow_dispatch' }} + run: | + $localArtifactPath = "src\out\Default\shell_browser_ui_unittests.exe" + $serverArtifactPath = "https://ci.appveyor.com/api/buildjobs/${{ inputs.appveyor_job_id }}/artifacts/shell_browser_ui_unittests.exe" + Invoke-RestMethod -Method Get -Uri $serverArtifactPath -OutFile $localArtifactPath -Headers @{ "Authorization" = "Bearer ${{ secrets.APPVEYOR_TOKEN }}" } + shell: powershell + - name: Download and extract ffmpeg.zip for test + if: ${{ github.event_name == 'workflow_dispatch' }} + run: | + $localArtifactPath = "$pwd\ffmpeg.zip" + $serverArtifactPath = "https://ci.appveyor.com/api/buildjobs/${{ inputs.appveyor_job_id }}/artifacts/ffmpeg.zip" + Invoke-RestMethod -Method Get -Uri $serverArtifactPath -OutFile $localArtifactPath -Headers @{ "Authorization" = "Bearer ${{ secrets.APPVEYOR_TOKEN }}" } + & "${env:ProgramFiles(x86)}\7-Zip\7z.exe" x -osrc\out\ffmpeg $localArtifactPath + shell: powershell + - name: Download node headers for test + if: ${{ github.event_name == 'workflow_dispatch' }} + run: | + $localArtifactPath = "src\node_headers.zip" + $serverArtifactPath = "https://ci.appveyor.com/api/buildjobs/${{ inputs.appveyor_job_id }}/artifacts/node_headers.zip" + Invoke-RestMethod -Method Get -Uri $serverArtifactPath -OutFile $localArtifactPath -Headers @{ "Authorization" = "Bearer ${{ secrets.APPVEYOR_TOKEN }}" } + cd src + & "${env:ProgramFiles(x86)}\7-Zip\7z.exe" x -y node_headers.zip + shell: powershell + - name: Download electron.lib for test + if: ${{ github.event_name == 'workflow_dispatch' }} + run: | + $localArtifactPath = "src\out\Default\electron.lib" + $serverArtifactPath = "https://ci.appveyor.com/api/buildjobs/${{ inputs.appveyor_job_id }}/artifacts/electron.lib" + Invoke-RestMethod -Method Get -Uri $serverArtifactPath -OutFile $localArtifactPath -Headers @{ "Authorization" = "Bearer ${{ secrets.APPVEYOR_TOKEN }}" } + shell: powershell + # Uncomment the following block if pdb files are needed to debug issues + # - name: Download pdb files for detailed stacktraces + # if: ${{ github.event_name == 'workflow_dispatch' }} + # run: | + # try { + # $localArtifactPath = "src\pdb.zip" + # $serverArtifactPath = "https://ci.appveyor.com/api/buildjobs/${{ inputs.appveyor_job_id }}/artifacts/pdb.zip" + # Invoke-RestMethod -Method Get -Uri $serverArtifactPath -OutFile $localArtifactPath -Headers @{ "Authorization" = "Bearer ${{ secrets.APPVEYOR_TOKEN }}" } + # cd src + # & "${env:ProgramFiles(x86)}\7-Zip\7z.exe" x -y pdb.zip + # } catch { + # Write-Host "There was an exception encountered while downloading pdb files:" $_.Exception.Message + # } finally { + # $global:LASTEXITCODE = 0 + # } + # shell: powershell + - name: Setup node headers + if: ${{ github.event_name == 'workflow_dispatch' }} + run: | + New-Item src\out\Default\gen\node_headers\Release -Type directory + Copy-Item -path src\out\Default\electron.lib -destination src\out\Default\gen\node_headers\Release\node.lib + shell: powershell + - name: Run Electron Main process tests + if: ${{ github.event_name == 'workflow_dispatch' }} + run: | + cd src + set npm_config_nodedir=%cd%\out\Default\gen\node_headers + set npm_config_arch=arm64 + cd electron + node script/yarn test --runners=main --enable-logging --disable-features=CalculateNativeWinOcclusion + env: + ELECTRON_ENABLE_STACK_DUMPING: true + ELECTRON_OUT_DIR: Default + IGNORE_YARN_INSTALL_ERROR: 1 + ELECTRON_TEST_RESULTS_DIR: junit + MOCHA_MULTI_REPORTERS: 'mocha-junit-reporter, tap' + MOCHA_REPORTER: mocha-multi-reporters + ELECTRON_SKIP_NATIVE_MODULE_TESTS: true + - name: Run Electron Remote based tests + if: ${{ github.event_name == 'workflow_dispatch' && (success() || failure()) }} + run: | + cd src + set npm_config_nodedir=%cd%\out\Default\gen\node_headers + set npm_config_arch=arm64 + cd electron + node script/yarn test --runners=remote --enable-logging --disable-features=CalculateNativeWinOcclusion + env: + ELECTRON_OUT_DIR: Default + IGNORE_YARN_INSTALL_ERROR: 1 + ELECTRON_TEST_RESULTS_DIR: junit + MOCHA_MULTI_REPORTERS: 'mocha-junit-reporter, tap' + MOCHA_REPORTER: mocha-multi-reporters + ELECTRON_SKIP_NATIVE_MODULE_TESTS: true + - name: Publish Test Results + uses: EnricoMi/publish-unit-test-result-action/composite@v1 + if: ${{ github.event_name == 'workflow_dispatch' && (success() || failure()) }} + with: + files: "src/junit/**/*.xml" + check_name: "electron-woa-testing" + - name: Verify ffmpeg + if: ${{ github.event_name == 'workflow_dispatch' }} + run: | + cd src + echo "Verifying non proprietary ffmpeg" + python electron\script\verify-ffmpeg.py --build-dir out\Default --source-root %cd% --ffmpeg-path out\ffmpeg + shell: cmd + - name: Kill processes left running from last test run + if: ${{ github.event_name == 'workflow_dispatch' && (success() || failure()) || cancelled() }} + run: | + Get-Process | Where Name -Like "electron*" | Stop-Process + Get-Process | Where Name -Like "msedge*" | Stop-Process + shell: powershell + - name: Delete user app data directories + if: ${{ github.event_name == 'workflow_dispatch' && (success() || failure()) || cancelled() }} + run: | + Remove-Item -path $env:APPDATA/Electron* -Recurse -Force -ErrorAction Ignore + shell: powershell + - uses: LouisBrunner/checks-action@v1.1.1 + if: ${{ github.event_name == 'workflow_dispatch' && (success() || failure()) || cancelled() }} + with: + token: ${{ secrets.GITHUB_TOKEN }} + name: electron-woa-testing + conclusion: "${{ job.status }}" \ No newline at end of file diff --git a/appveyor.yml b/appveyor.yml index 0282c36e750c2..e8e16a345343b 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -224,7 +224,7 @@ deploy_script: & python script\release\uploaders\upload.py --verbose } } elseif (Test-Path Env:\TEST_WOA) { - node script/release/ci-release-build.js --job=electron-woa-testing --ci=VSTS --armTest --appveyorJobId=$env:APPVEYOR_JOB_ID $env:APPVEYOR_REPO_BRANCH + node script/release/ci-release-build.js --job=electron-woa-testing --ci=GHA --appveyorJobId=$env:APPVEYOR_JOB_ID $env:APPVEYOR_REPO_BRANCH } on_finish: # Uncomment this lines to enable RDP diff --git a/azure-pipelines-arm.yml b/azure-pipelines-arm.yml deleted file mode 100644 index 868b7753944e2..0000000000000 --- a/azure-pipelines-arm.yml +++ /dev/null @@ -1,121 +0,0 @@ -steps: -- task: CopyFiles@2 - displayName: 'Copy Files to: src/electron' - inputs: - TargetFolder: src/electron - -- bash: | - cd src/electron - node script/yarn.js install --frozen-lockfile - displayName: 'Yarn install' - -- bash: | - export ZIP_DEST=$PWD/src/out/Default - echo "##vso[task.setvariable variable=ZIP_DEST]$ZIP_DEST" - mkdir -p $ZIP_DEST - cd src/electron - node script/download-circleci-artifacts.js --buildNum=$CIRCLE_BUILD_NUM --name=dist.zip --dest=$ZIP_DEST - cd $ZIP_DEST - unzip -o dist.zip - xattr -cr Electron.app - displayName: 'Download and unzip dist files for test' - env: - CIRCLE_TOKEN: $(CIRCLECI_TOKEN) - -- bash: | - export FFMPEG_ZIP_DEST=$PWD/src/out/ffmpeg - mkdir -p $FFMPEG_ZIP_DEST - cd src/electron - node script/download-circleci-artifacts.js --buildNum=$CIRCLE_BUILD_NUM --name=ffmpeg.zip --dest=$FFMPEG_ZIP_DEST - cd $FFMPEG_ZIP_DEST - unzip -o ffmpeg.zip - displayName: 'Download and unzip ffmpeg for test' - env: - CIRCLE_TOKEN: $(CIRCLECI_TOKEN) - -- bash: | - export NODE_HEADERS_DEST=$PWD/src/out/Default/gen - mkdir -p $NODE_HEADERS_DEST - cd src/electron - node script/download-circleci-artifacts.js --buildNum=$CIRCLE_BUILD_NUM --name=node_headers.tar.gz --dest=$NODE_HEADERS_DEST - cd $NODE_HEADERS_DEST - tar xzf node_headers.tar.gz - displayName: 'Download and untar node header files for test' - env: - CIRCLE_TOKEN: $(CIRCLECI_TOKEN) - -- bash: | - export CROSS_ARCH_SNAPSHOTS=$PWD/src/out/Default/cross-arch-snapshots - mkdir -p $CROSS_ARCH_SNAPSHOTS - cd src/electron - node script/download-circleci-artifacts.js --buildNum=$CIRCLE_BUILD_NUM --name=cross-arch-snapshots/snapshot_blob.bin --dest=$CROSS_ARCH_SNAPSHOTS - node script/download-circleci-artifacts.js --buildNum=$CIRCLE_BUILD_NUM --name=cross-arch-snapshots/v8_context_snapshot.arm64.bin --dest=$CROSS_ARCH_SNAPSHOTS - displayName: 'Download cross arch snapshot files' - env: - CIRCLE_TOKEN: $(CIRCLECI_TOKEN) - -- bash: | - cd src - export ELECTRON_OUT_DIR=Default - export npm_config_arch=arm64 - (cd electron && node script/yarn test --enable-logging --runners main) - displayName: 'Run Electron main tests' - timeoutInMinutes: 20 - env: - ELECTRON_DISABLE_SECURITY_WARNINGS: 1 - IGNORE_YARN_INSTALL_ERROR: 1 - ELECTRON_TEST_RESULTS_DIR: junit - -- bash: | - cd src - export ELECTRON_OUT_DIR=Default - export npm_config_arch=arm64 - (cd electron && node script/yarn test --enable-logging --runners remote) - displayName: 'Run Electron remote tests' - timeoutInMinutes: 20 - condition: succeededOrFailed() - env: - ELECTRON_DISABLE_SECURITY_WARNINGS: 1 - IGNORE_YARN_INSTALL_ERROR: 1 - ELECTRON_TEST_RESULTS_DIR: junit - -- bash: | - cd src - python electron/script/verify-ffmpeg.py --source-root "$PWD" --build-dir out/Default --ffmpeg-path out/ffmpeg - displayName: Verify non proprietary ffmpeg - timeoutInMinutes: 5 - condition: succeededOrFailed() - env: - TARGET_ARCH: arm64 - -- bash: | - cd src - echo Verify cross arch snapshot - python electron/script/verify-mksnapshot.py --source-root "$PWD" --build-dir out/Default --snapshot-files-dir $PWD/out/Default/cross-arch-snapshots - displayName: Verify cross arch snapshot - timeoutInMinutes: 5 - condition: succeededOrFailed() - -- task: PublishTestResults@2 - displayName: 'Publish Test Results' - inputs: - testResultsFiles: '*.xml' - - searchFolder: '$(System.DefaultWorkingDirectory)/src/junit/' - - condition: succeededOrFailed() - -- bash: killall Electron || echo "No Electron processes left running" - displayName: 'Kill processes left running from last test run' - condition: always() - -- bash: | - rm -rf ~/Library/Application\ Support/Electron* - rm -rf ~/Library/Application\ Support/electron* - displayName: 'Delete user app data directories' - condition: always() - -- task: mspremier.PostBuildCleanup.PostBuildCleanup-task.PostBuildCleanup@3 - displayName: 'Clean Agent Directories' - - condition: always() diff --git a/azure-pipelines-woa.yml b/azure-pipelines-woa.yml deleted file mode 100644 index 9942f97f79dc3..0000000000000 --- a/azure-pipelines-woa.yml +++ /dev/null @@ -1,130 +0,0 @@ -workspace: - clean: all - -steps: -- checkout: self - path: src\electron - -- script: | - node script/yarn.js install --frozen-lockfile - displayName: 'Yarn install' - -- powershell: | - $localArtifactPath = "$pwd\dist.zip" - $serverArtifactPath = "$env:APPVEYOR_URL/buildjobs/$env:APPVEYOR_JOB_ID/artifacts/dist.zip" - Invoke-RestMethod -Method Get -Uri $serverArtifactPath -OutFile $localArtifactPath -Headers @{ "Authorization" = "Bearer $env:APPVEYOR_TOKEN" } - & "${env:ProgramFiles(x86)}\7-Zip\7z.exe" x -o$(Pipeline.Workspace)\src\out\Default -y $localArtifactPath - displayName: 'Download and extract dist.zip for test' - env: - APPVEYOR_TOKEN: $(APPVEYOR_TOKEN) - -- powershell: | - $localArtifactPath = "$(Pipeline.Workspace)\src\out\Default\shell_browser_ui_unittests.exe" - $serverArtifactPath = "$env:APPVEYOR_URL/buildjobs/$env:APPVEYOR_JOB_ID/artifacts/shell_browser_ui_unittests.exe" - Invoke-RestMethod -Method Get -Uri $serverArtifactPath -OutFile $localArtifactPath -Headers @{ "Authorization" = "Bearer $env:APPVEYOR_TOKEN" } - displayName: 'Download and extract native test executables for test' - env: - APPVEYOR_TOKEN: $(APPVEYOR_TOKEN) - -- powershell: | - $localArtifactPath = "$pwd\ffmpeg.zip" - $serverArtifactPath = "$env:APPVEYOR_URL/buildjobs/$env:APPVEYOR_JOB_ID/artifacts/ffmpeg.zip" - Invoke-RestMethod -Method Get -Uri $serverArtifactPath -OutFile $localArtifactPath -Headers @{ "Authorization" = "Bearer $env:APPVEYOR_TOKEN" } - & "${env:ProgramFiles(x86)}\7-Zip\7z.exe" x -o$(Pipeline.Workspace)\src\out\ffmpeg $localArtifactPath - displayName: 'Download and extract ffmpeg.zip for test' - env: - APPVEYOR_TOKEN: $(APPVEYOR_TOKEN) - -- powershell: | - $localArtifactPath = "$(Pipeline.Workspace)\src\node_headers.zip" - $serverArtifactPath = "$env:APPVEYOR_URL/buildjobs/$env:APPVEYOR_JOB_ID/artifacts/node_headers.zip" - Invoke-RestMethod -Method Get -Uri $serverArtifactPath -OutFile $localArtifactPath -Headers @{ "Authorization" = "Bearer $env:APPVEYOR_TOKEN" } - cd $(Pipeline.Workspace)\src - & "${env:ProgramFiles(x86)}\7-Zip\7z.exe" x -y node_headers.zip - displayName: 'Download node headers for test' - env: - APPVEYOR_TOKEN: $(APPVEYOR_TOKEN) - -- powershell: | - $localArtifactPath = "$(Pipeline.Workspace)\src\out\Default\electron.lib" - $serverArtifactPath = "$env:APPVEYOR_URL/buildjobs/$env:APPVEYOR_JOB_ID/artifacts/electron.lib" - Invoke-RestMethod -Method Get -Uri $serverArtifactPath -OutFile $localArtifactPath -Headers @{ "Authorization" = "Bearer $env:APPVEYOR_TOKEN" } - displayName: 'Download electron.lib for test' - env: - APPVEYOR_TOKEN: $(APPVEYOR_TOKEN) - -# Uncomment the following block if pdb files are needed to debug issues -# - powershell: | -# try { -# $localArtifactPath = "$(Pipeline.Workspace)\src\pdb.zip" -# $serverArtifactPath = "$env:APPVEYOR_URL/buildjobs/$env:APPVEYOR_JOB_ID/artifacts/pdb.zip" -# Invoke-RestMethod -Method Get -Uri $serverArtifactPath -OutFile $localArtifactPath -Headers @{ "Authorization" = "Bearer $env:APPVEYOR_TOKEN" } -# cd $(Pipeline.Workspace)\src -# & "${env:ProgramFiles(x86)}\7-Zip\7z.exe" x -y pdb.zip -# } catch { -# Write-Host "There was an exception encountered while downloading pdb files:" $_.Exception.Message -# } finally { -# $global:LASTEXITCODE = 0 -# } -# displayName: 'Download pdb files for detailed stacktraces' -# env: -# APPVEYOR_TOKEN: $(APPVEYOR_TOKEN) - -- powershell: | - New-Item $(Pipeline.Workspace)\src\out\Default\gen\node_headers\Release -Type directory - Copy-Item -path $(Pipeline.Workspace)\src\out\Default\electron.lib -destination $(Pipeline.Workspace)\src\out\Default\gen\node_headers\Release\node.lib - displayName: 'Setup node headers' - -- script: | - cd $(Pipeline.Workspace)\src - set npm_config_nodedir=%cd%\out\Default\gen\node_headers - set npm_config_arch=arm64 - cd electron - node script/yarn test --runners=main --enable-logging --disable-features=CalculateNativeWinOcclusion - displayName: 'Run Electron Main process tests' - env: - ELECTRON_ENABLE_STACK_DUMPING: true - ELECTRON_OUT_DIR: Default - IGNORE_YARN_INSTALL_ERROR: 1 - ELECTRON_TEST_RESULTS_DIR: junit - MOCHA_MULTI_REPORTERS: 'mocha-junit-reporter, tap' - MOCHA_REPORTER: mocha-multi-reporters - -- script: | - cd $(Pipeline.Workspace)\src - set npm_config_nodedir=%cd%\out\Default\gen\node_headers - set npm_config_arch=arm64 - cd electron - node script/yarn test --runners=remote --enable-logging --disable-features=CalculateNativeWinOcclusion - displayName: 'Run Electron Remote based tests' - env: - ELECTRON_OUT_DIR: Default - IGNORE_YARN_INSTALL_ERROR: 1 - ELECTRON_TEST_RESULTS_DIR: junit - MOCHA_MULTI_REPORTERS: 'mocha-junit-reporter, tap' - MOCHA_REPORTER: mocha-multi-reporters - condition: succeededOrFailed() - -- task: PublishTestResults@2 - displayName: 'Publish Test Results' - inputs: - testResultsFiles: '*.xml' - searchFolder: '$(Pipeline.Workspace)/src/junit/' - condition: always() - -- script: | - cd $(Pipeline.Workspace)\src - echo "Verifying non proprietary ffmpeg" - python electron\script\verify-ffmpeg.py --build-dir out\Default --source-root %cd% --ffmpeg-path out\ffmpeg - displayName: 'Verify ffmpeg' - -- powershell: | - Get-Process | Where Name –Like "electron*" | Stop-Process - Get-Process | Where Name –Like "msedge*" | Stop-Process - displayName: 'Kill processes left running from last test run' - condition: always() - -- powershell: | - Remove-Item -path $env:APPDATA/Electron* -Recurse -Force -ErrorAction Ignore - displayName: 'Delete user app data directories' - condition: always() diff --git a/script/release/ci-release-build.js b/script/release/ci-release-build.js index 31ac6a3b74962..c92dcf1b61307 100644 --- a/script/release/ci-release-build.js +++ b/script/release/ci-release-build.js @@ -2,11 +2,10 @@ if (!process.env.CI) require('dotenv-safe').load(); const assert = require('assert'); const got = require('got'); +const { Octokit } = require('@octokit/rest'); const BUILD_APPVEYOR_URL = 'https://ci.appveyor.com/api/builds'; const CIRCLECI_PIPELINE_URL = 'https://circleci.com/api/v2/project/gh/electron/electron/pipeline'; -const VSTS_URL = 'https://github.visualstudio.com/electron/_apis/build'; -const DEVOPS_URL = 'https://dev.azure.com/electron-ci/electron/_apis/build'; const CIRCLECI_WAIT_TIME = process.env.CIRCLECI_WAIT_TIME || 30000; const appVeyorJobs = { @@ -25,13 +24,7 @@ const circleCIPublishIndividualArches = { 'linux-publish': ['arm', 'arm64', 'x64'] }; -const vstsArmJobs = [ - 'electron-arm-testing', - 'electron-osx-arm64-testing', - 'electron-mas-arm64-testing', - 'electron-arm64-testing', - 'electron-woa-testing' -]; +const GHAJobs = ['electron-woa-testing']; let jobRequestedCount = 0; @@ -247,75 +240,28 @@ function buildCircleCI (targetBranch, options) { } } -async function buildVSTS (targetBranch, options) { - assert(options.armTest, `${options.ci} only works with the --armTest option.`); - assert(vstsArmJobs.includes(options.job), `Unknown VSTS CI arm test job name: ${options.job}. Valid values are: ${vstsArmJobs}.`); +async function buildGHA (targetBranch, options) { + const { GHA_TOKEN } = process.env; + assert(GHA_TOKEN, `${options.ci} requires the $GHA_TOKEN environment variable to be provided`); - console.log(`Triggering VSTS to run build on branch: ${targetBranch}.`); - const environmentVariables = {}; + const octokit = new Octokit({ auth: GHA_TOKEN }); - if (options.circleBuildNum) { - environmentVariables.CIRCLE_BUILD_NUM = options.circleBuildNum; - } else if (options.appveyorJobId) { - environmentVariables.APPVEYOR_JOB_ID = options.appveyorJobId; - } + assert(GHAJobs.includes(options.job), `Unknown GitHub Actions arm test job name: ${options.job}. Valid values are: ${GHAJobs}.`); + assert(options.commit !== null, 'commit is a required option for GitHub Actions'); - let vstsURL = VSTS_URL; - let vstsToken = process.env.VSTS_TOKEN; - assert(vstsToken, `${options.ci} requires the $VSTS_TOKEN environment variable to be provided`); - if (options.ci === 'DevOps') { - vstsURL = DEVOPS_URL; - vstsToken = process.env.DEVOPS_TOKEN; - } - const requestOpts = { - url: `${vstsURL}/definitions?api-version=4.1`, - auth: { - user: '', - password: vstsToken - }, - headers: { - 'Content-Type': 'application/json' - } - }; + console.log(`Triggering GitHub Actions to run build on branch: ${targetBranch}.`); jobRequestedCount++; try { - const vstsResponse = await makeRequest(requestOpts, true); - const buildToRun = vstsResponse.value.find(build => build.name === options.job); - callVSTSBuild(buildToRun, targetBranch, environmentVariables, vstsURL, vstsToken); - } catch (err) { - console.log('Problem calling VSTS to get build definitions: ', err); - } -} - -async function callVSTSBuild (build, targetBranch, environmentVariables, vstsURL, vstsToken) { - const buildBody = { - definition: build, - sourceBranch: targetBranch, - priority: 'high' - }; - if (Object.keys(environmentVariables).length !== 0) { - buildBody.parameters = JSON.stringify(environmentVariables); - } - const requestOpts = { - url: `${vstsURL}/builds?api-version=4.1`, - auth: { - user: '', - password: vstsToken - }, - headers: { - 'Content-Type': 'application/json' - }, - body: JSON.stringify(buildBody), - method: 'POST' - }; - - try { - const { _links } = await makeRequest(requestOpts, true); - console.log(`VSTS release build request for ${build.name} successful. Check ${_links.web.href} for status.`); + const response = await octokit.request('POST /repos/electron/electron/actions/workflows/electron_woa_testing.yml/dispatches', { + ref: targetBranch, + inputs: { + appveyor_job_id: `${options.appveyorJobId}` + } + }); } catch (err) { - console.log(`Could not call VSTS for job ${build.name}: `, err); + console.log('Problem calling GitHub Actions to get build definitions: ', err); } } @@ -330,9 +276,8 @@ function runRelease (targetBranch, options) { buildAppVeyor(targetBranch, options); break; } - case 'DevOps': - case 'VSTS': { - buildVSTS(targetBranch, options); + case 'GHA': { + buildGHA(targetBranch, options); break; } default: { @@ -351,13 +296,13 @@ module.exports = runRelease; if (require.main === module) { const args = require('minimist')(process.argv.slice(2), { - boolean: ['ghRelease', 'armTest'] + boolean: ['ghRelease'] }); const targetBranch = args._[0]; if (args._.length < 1) { console.log(`Trigger CI to build release builds of electron. - Usage: ci-release-build.js [--job=CI_JOB_NAME] [--arch=INDIVIDUAL_ARCH] [--ci=CircleCI|AppVeyor|VSTS|DevOps] - [--ghRelease] [--armTest] [--circleBuildNum=xxx] [--appveyorJobId=xxx] [--commit=sha] TARGET_BRANCH + Usage: ci-release-build.js [--job=CI_JOB_NAME] [--arch=INDIVIDUAL_ARCH] [--ci=CircleCI|AppVeyor|GHA] + [--ghRelease] [--circleBuildNum=xxx] [--appveyorJobId=xxx] [--commit=sha] TARGET_BRANCH `); process.exit(0); } diff --git a/vsts-arm-test-steps.yml b/vsts-arm-test-steps.yml deleted file mode 100644 index 5985e4d2637e4..0000000000000 --- a/vsts-arm-test-steps.yml +++ /dev/null @@ -1,110 +0,0 @@ -steps: -- task: CopyFiles@2 - displayName: 'Copy Files to: src/electron' - inputs: - TargetFolder: src/electron - -- bash: | - cd src/electron - node script/yarn.js install --frozen-lockfile - displayName: 'Yarn install' - -- bash: | - export ZIP_DEST=$PWD/src/out/Default - echo "##vso[task.setvariable variable=ZIP_DEST]$ZIP_DEST" - mkdir -p $ZIP_DEST - cd src/electron - node script/download-circleci-artifacts.js --buildNum=$CIRCLE_BUILD_NUM --name=dist.zip --dest=$ZIP_DEST - cd $ZIP_DEST - unzip -o dist.zip - displayName: 'Download and unzip dist files for test' - env: - CIRCLE_TOKEN: $(CIRCLECI_TOKEN) - -- bash: | - export FFMPEG_ZIP_DEST=$PWD/src/out/ffmpeg - mkdir -p $FFMPEG_ZIP_DEST - cd src/electron - node script/download-circleci-artifacts.js --buildNum=$CIRCLE_BUILD_NUM --name=ffmpeg.zip --dest=$FFMPEG_ZIP_DEST - cd $FFMPEG_ZIP_DEST - unzip -o ffmpeg.zip - displayName: 'Download and unzip ffmpeg for test' - env: - CIRCLE_TOKEN: $(CIRCLECI_TOKEN) - -- bash: | - export NODE_HEADERS_DEST=$PWD/src/out/Default/gen - mkdir -p $NODE_HEADERS_DEST - cd src/electron - node script/download-circleci-artifacts.js --buildNum=$CIRCLE_BUILD_NUM --name=node_headers.tar.gz --dest=$NODE_HEADERS_DEST - cd $NODE_HEADERS_DEST - tar xzf node_headers.tar.gz - displayName: 'Download and untar node header files for test' - env: - CIRCLE_TOKEN: $(CIRCLECI_TOKEN) - -- bash: | - export CROSS_ARCH_SNAPSHOTS=$PWD/src/out/Default/cross-arch-snapshots - mkdir -p $CROSS_ARCH_SNAPSHOTS - cd src/electron - node script/download-circleci-artifacts.js --buildNum=$CIRCLE_BUILD_NUM --name=cross-arch-snapshots/snapshot_blob.bin --dest=$CROSS_ARCH_SNAPSHOTS - node script/download-circleci-artifacts.js --buildNum=$CIRCLE_BUILD_NUM --name=cross-arch-snapshots/v8_context_snapshot.bin --dest=$CROSS_ARCH_SNAPSHOTS - displayName: 'Download cross arch snapshot files' - env: - CIRCLE_TOKEN: $(CIRCLECI_TOKEN) - -- bash: | - export NATIVE_UNITTESTS_DEST=$PWD/src/out/Default - cd src/electron - node script/download-circleci-artifacts.js --buildNum=$CIRCLE_BUILD_NUM --name=shell_browser_ui_unittests --dest=$NATIVE_UNITTESTS_DEST - chmod +x $NATIVE_UNITTESTS_DEST/shell_browser_ui_unittests - displayName: 'Download native unittest executables' - env: - CIRCLE_TOKEN: $(CIRCLECI_TOKEN) - -- bash: | - sh -e /etc/init.d/xvfb start - displayName: Setup for headless testing - env: - DISPLAY: ":99.0" - -- bash: | - # Next line needed to avoid crash on arm32 - sudo gdk-pixbuf-query-loaders --update-cache - cd src - export ELECTRON_OUT_DIR=Default - (cd electron && node script/yarn test -- --enable-logging) - displayName: 'Run Electron tests' - timeoutInMinutes: 20 - env: - ELECTRON_DISABLE_SECURITY_WARNINGS: 1 - IGNORE_YARN_INSTALL_ERROR: 1 - ELECTRON_TEST_RESULTS_DIR: junit - CI: 1 - -- bash: | - cd src - python electron/script/verify-ffmpeg.py --source-root "$PWD" --build-dir out/Default --ffmpeg-path out/ffmpeg - displayName: Verify non proprietary ffmpeg - timeoutInMinutes: 5 - -- bash: | - cd src - echo Verify cross arch snapshot - python electron/script/verify-mksnapshot.py --source-root "$PWD" --build-dir out/Default --snapshot-files-dir $PWD/out/Default/cross-arch-snapshots - displayName: Verify cross arch snapshot - timeoutInMinutes: 5 - -- task: PublishTestResults@2 - displayName: 'Publish Test Results' - inputs: - testResultsFiles: '*.xml' - - searchFolder: '$(System.DefaultWorkingDirectory)/src/junit/' - - condition: succeededOrFailed() - -- task: mspremier.PostBuildCleanup.PostBuildCleanup-task.PostBuildCleanup@3 - displayName: 'Clean Agent Directories' - - condition: always() diff --git a/vsts-arm32v7.yml b/vsts-arm32v7.yml deleted file mode 100644 index feeb920ba8f39..0000000000000 --- a/vsts-arm32v7.yml +++ /dev/null @@ -1,13 +0,0 @@ -resources: - containers: - - container: arm32v7-test-container - image: ghcr.io/electron/build:arm32v7-27db4a3e3512bfd2e47f58cea69922da0835f1d9 - options: --shm-size 128m - -jobs: -- job: Test_Arm32v7 - container: arm32v7-test-container - displayName: Test Arm on Arm32v7 hardware - timeoutInMinutes: 30 - steps: - - template: vsts-arm-test-steps.yml diff --git a/vsts-arm64v8.yml b/vsts-arm64v8.yml deleted file mode 100644 index e64708663b393..0000000000000 --- a/vsts-arm64v8.yml +++ /dev/null @@ -1,13 +0,0 @@ -resources: - containers: - - container: arm64v8-test-container - image: ghcr.io/electron/build:arm64v8-27db4a3e3512bfd2e47f58cea69922da0835f1d9 - options: --shm-size 128m - -jobs: -- job: Test_Arm64 - container: arm64v8-test-container - displayName: Test Arm64 on Arm64 hardware - timeoutInMinutes: 30 - steps: - - template: vsts-arm-test-steps.yml From c61a14c5d126ca3e36bce9b106ab23dcb1a0eff3 Mon Sep 17 00:00:00 2001 From: "trop[bot]" <37223003+trop[bot]@users.noreply.github.com> Date: Fri, 29 Jul 2022 11:26:33 -0700 Subject: [PATCH 16/30] fix: empty result of `webContents.getUserAgent()` (#35131) fix: empty result of webContents.getUserAgent() Co-authored-by: Shelley Vohr --- shell/browser/api/electron_api_web_contents.cc | 11 +++-------- shell/browser/electron_browser_context.cc | 5 ----- shell/browser/electron_browser_context.h | 1 - spec-main/api-web-contents-spec.ts | 6 ++++++ 4 files changed, 9 insertions(+), 14 deletions(-) diff --git a/shell/browser/api/electron_api_web_contents.cc b/shell/browser/api/electron_api_web_contents.cc index cf23b419c3fe7..a9d6626339ac9 100644 --- a/shell/browser/api/electron_api_web_contents.cc +++ b/shell/browser/api/electron_api_web_contents.cc @@ -675,10 +675,8 @@ WebContents::WebContents(v8::Isolate* isolate, auto session = Session::CreateFrom(isolate, GetBrowserContext()); session_.Reset(isolate, session.ToV8()); - absl::optional user_agent_override = - GetBrowserContext()->GetUserAgentOverride(); - if (user_agent_override) - SetUserAgent(*user_agent_override); + SetUserAgent(GetBrowserContext()->GetUserAgent()); + web_contents->SetUserData(kElectronApiWebContentsKey, std::make_unique(GetWeakPtr())); InitZoomController(web_contents, gin::Dictionary::CreateEmpty(isolate)); @@ -884,10 +882,7 @@ void WebContents::InitWithSessionAndOptions( AutofillDriverFactory::CreateForWebContents(web_contents()); - absl::optional user_agent_override = - GetBrowserContext()->GetUserAgentOverride(); - if (user_agent_override) - SetUserAgent(*user_agent_override); + SetUserAgent(GetBrowserContext()->GetUserAgent()); if (IsGuest()) { NativeWindow* owner_window = nullptr; diff --git a/shell/browser/electron_browser_context.cc b/shell/browser/electron_browser_context.cc index 0d1532b2b12da..abdf5d21c2d83 100644 --- a/shell/browser/electron_browser_context.cc +++ b/shell/browser/electron_browser_context.cc @@ -307,11 +307,6 @@ std::string ElectronBrowserContext::GetUserAgent() const { return user_agent_.value_or(ElectronBrowserClient::Get()->GetUserAgent()); } -absl::optional ElectronBrowserContext::GetUserAgentOverride() - const { - return user_agent_; -} - predictors::PreconnectManager* ElectronBrowserContext::GetPreconnectManager() { if (!preconnect_manager_.get()) { preconnect_manager_ = diff --git a/shell/browser/electron_browser_context.h b/shell/browser/electron_browser_context.h index 844df7f65e65b..36aa70bda6c0d 100644 --- a/shell/browser/electron_browser_context.h +++ b/shell/browser/electron_browser_context.h @@ -91,7 +91,6 @@ class ElectronBrowserContext : public content::BrowserContext { void SetUserAgent(const std::string& user_agent); std::string GetUserAgent() const; - absl::optional GetUserAgentOverride() const; bool CanUseHttpCache() const; int GetMaxCacheSize() const; ResolveProxyHelper* GetResolveProxyHelper(); diff --git a/spec-main/api-web-contents-spec.ts b/spec-main/api-web-contents-spec.ts index 4f0b17fc72df8..71ca36b9f94e9 100644 --- a/spec-main/api-web-contents-spec.ts +++ b/spec-main/api-web-contents-spec.ts @@ -903,6 +903,12 @@ describe('webContents module', () => { }); describe('userAgent APIs', () => { + it('is not empty by default', () => { + const w = new BrowserWindow({ show: false }); + const userAgent = w.webContents.getUserAgent(); + expect(userAgent).to.be.a('string').that.is.not.empty(); + }); + it('can set the user agent (functions)', () => { const w = new BrowserWindow({ show: false }); const userAgent = w.webContents.getUserAgent(); From 8ac0e2bdecbbf3abbf8fd07515f7b3784ca9827a Mon Sep 17 00:00:00 2001 From: "trop[bot]" <37223003+trop[bot]@users.noreply.github.com> Date: Fri, 29 Jul 2022 11:43:45 -0700 Subject: [PATCH 17/30] docs: update E21 release date (#35126) * docs: update E21 release date * chore: fix lint Co-authored-by: Sofia Nguy Co-authored-by: Keeley Hammond --- docs/tutorial/electron-timelines.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/tutorial/electron-timelines.md b/docs/tutorial/electron-timelines.md index e98f5b14ed11d..6af3e41815f35 100644 --- a/docs/tutorial/electron-timelines.md +++ b/docs/tutorial/electron-timelines.md @@ -24,10 +24,11 @@ check out our [Electron Versioning](./electron-versioning.md) doc. | 14.0.0 | -- | 2021-May-27 | 2021-Aug-31 | M93 | v14.17 | 🚫 | | 15.0.0 | 2021-Jul-20 | 2021-Sep-01 | 2021-Sep-21 | M94 | v16.5 | 🚫 | | 16.0.0 | 2021-Sep-23 | 2021-Oct-20 | 2021-Nov-16 | M96 | v16.9 | 🚫 | -| 17.0.0 | 2021-Nov-18 | 2022-Jan-06 | 2022-Feb-01 | M98 | v16.13 | ✅ | +| 17.0.0 | 2021-Nov-18 | 2022-Jan-06 | 2022-Feb-01 | M98 | v16.13 | 🚫 | | 18.0.0 | 2022-Feb-03 | 2022-Mar-03 | 2022-Mar-29 | M100 | v16.13 | ✅ | | 19.0.0 | 2022-Mar-31 | 2022-Apr-26 | 2022-May-24 | M102 | v16.14 | ✅ | -| 20.0.0 | 2022-May-26 | 2022-Jun-21 | 2022-Aug-02 | M104 | TBD | ✅ | +| 20.0.0 | 2022-May-26 | 2022-Jun-21 | 2022-Aug-02 | M104 | v16.15 | ✅ | +| 21.0.0 | 2022-Aug-04 | 2022-Aug-30 | 2022-Sep-27 | M106 | TBD | ✅ | **Notes:** From 76450afd474f710b826317336c2125ce6dc424ca Mon Sep 17 00:00:00 2001 From: Keeley Hammond Date: Fri, 29 Jul 2022 14:37:31 -0700 Subject: [PATCH 18/30] fix: ensure that v8 sandbox isnt enabled for arm (#35137) fix: ensure that v8 sandbox isnt enabled for arm (#34914) Co-authored-by: Samuel Attard --- ...pression_sandbox_is_enabled_on_64bit.patch | 31 ++++++++++++------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/patches/node/build_ensure_v8_pointer_compression_sandbox_is_enabled_on_64bit.patch b/patches/node/build_ensure_v8_pointer_compression_sandbox_is_enabled_on_64bit.patch index c47e4a2e92419..85795b3d1b921 100644 --- a/patches/node/build_ensure_v8_pointer_compression_sandbox_is_enabled_on_64bit.patch +++ b/patches/node/build_ensure_v8_pointer_compression_sandbox_is_enabled_on_64bit.patch @@ -8,29 +8,26 @@ Aligns common.gypi with the current build flag state of //v8. Specifically enables `V8_ENABLE_SANDBOX`, `V8_SANDBOXED_POINTERS`, `V8_COMPRESS_POINTERS` and `V8_COMPRESS_POINTERS_IN_SHARED_CAGE`. diff --git a/common.gypi b/common.gypi -index fd4e0b38eb6ecf81b23186ec663499d1e685fdf8..e20092d15d5f71f3e90a2ce655d660a8fa1e1385 100644 +index fd4e0b38eb6ecf81b23186ec663499d1e685fdf8..fe9c96722661071d4497e57d5a8d9ae7d6824159 100644 --- a/common.gypi +++ b/common.gypi -@@ -66,6 +66,8 @@ +@@ -65,6 +65,7 @@ + # node-gyp to build addons. 'v8_enable_pointer_compression%': 0, 'v8_enable_31bit_smis_on_64bit_arch%': 0, - + 'v8_enable_sandbox%': 0, -+ + # Disable V8 untrusted code mitigations. # See https://github.com/v8/v8/wiki/Untrusted-code-mitigations - 'v8_untrusted_code_mitigations': 0, -@@ -135,6 +137,9 @@ +@@ -134,6 +135,7 @@ + ['target_arch in "arm ia32 mips mipsel ppc"', { 'v8_enable_pointer_compression': 0, 'v8_enable_31bit_smis_on_64bit_arch': 0, - }], -+ ['target_arch in "arm64 x64"', { + 'v8_enable_sandbox': 0, -+ }], + }], ['target_arch in "ppc64 s390x"', { 'v8_enable_backtrace': 1, - }], -@@ -394,9 +399,15 @@ +@@ -394,9 +396,15 @@ ['v8_enable_pointer_compression == 1', { 'defines': [ 'V8_COMPRESS_POINTERS', @@ -47,3 +44,15 @@ index fd4e0b38eb6ecf81b23186ec663499d1e685fdf8..e20092d15d5f71f3e90a2ce655d660a8 ['v8_enable_pointer_compression == 1 or v8_enable_31bit_smis_on_64bit_arch == 1', { 'defines': ['V8_31BIT_SMIS_ON_64BIT_ARCH'], }], +diff --git a/configure.py b/configure.py +index 95b31769cb5756578d66193716c638f504bd44aa..fe741d15da821396883dd72b4e0a42c7758bd557 100755 +--- a/configure.py ++++ b/configure.py +@@ -1433,6 +1433,7 @@ def configure_v8(o): + o['variables']['v8_use_siphash'] = 0 if options.without_siphash else 1 + o['variables']['v8_enable_pointer_compression'] = 1 if options.enable_pointer_compression else 0 + o['variables']['v8_enable_31bit_smis_on_64bit_arch'] = 1 if options.enable_pointer_compression else 0 ++ o['variables']['v8_enable_sandbox'] = 1 if options.enable_pointer_compression else 0 + o['variables']['v8_trace_maps'] = 1 if options.trace_maps else 0 + o['variables']['node_use_v8_platform'] = b(not options.without_v8_platform) + o['variables']['node_use_bundled_v8'] = b(not options.without_bundled_v8) From 08aa57806edbd9b6fc5eb68835ffe8cb046b43bf Mon Sep 17 00:00:00 2001 From: Keeley Hammond Date: Fri, 29 Jul 2022 15:06:31 -0700 Subject: [PATCH 19/30] feat: sandbox preloads by default (#35125) feat: sandbox preloads by default (#32869) Co-authored-by: Jeremy Rose --- shell/browser/web_contents_preferences.cc | 4 +--- spec-main/fixtures/apps/libuv-hang/main.js | 3 ++- spec/webview-spec.js | 4 ++++ 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/shell/browser/web_contents_preferences.cc b/shell/browser/web_contents_preferences.cc index c23c5ea39f6f0..3af85d40d1b2c 100644 --- a/shell/browser/web_contents_preferences.cc +++ b/shell/browser/web_contents_preferences.cc @@ -312,9 +312,7 @@ bool WebContentsPreferences::IsSandboxed() const { if (sandbox_) return *sandbox_; bool sandbox_disabled_by_default = - node_integration_ || node_integration_in_worker_ || preload_path_ || - !SessionPreferences::GetValidPreloads(web_contents_->GetBrowserContext()) - .empty(); + node_integration_ || node_integration_in_worker_; return !sandbox_disabled_by_default; } diff --git a/spec-main/fixtures/apps/libuv-hang/main.js b/spec-main/fixtures/apps/libuv-hang/main.js index 4ca4ef15d9024..3c9b9d0b6f26a 100644 --- a/spec-main/fixtures/apps/libuv-hang/main.js +++ b/spec-main/fixtures/apps/libuv-hang/main.js @@ -5,7 +5,8 @@ async function createWindow () { const mainWindow = new BrowserWindow({ show: false, webPreferences: { - preload: path.join(__dirname, 'preload.js') + preload: path.join(__dirname, 'preload.js'), + sandbox: false } }); diff --git a/spec/webview-spec.js b/spec/webview-spec.js index 491f4a2cfdf57..3704e25a9f46b 100644 --- a/spec/webview-spec.js +++ b/spec/webview-spec.js @@ -243,6 +243,7 @@ describe(' tag', function () { it('preload script can require modules that still use "process" and "Buffer" when nodeintegration is off', async () => { const message = await startLoadingWebViewAndWaitForMessage(webview, { preload: `${fixtures}/module/preload-node-off-wrapper.js`, + webpreferences: 'sandbox=no', src: `file://${fixtures}/api/blank.html` }); @@ -288,6 +289,7 @@ describe(' tag', function () { it('works without script tag in page', async () => { const message = await startLoadingWebViewAndWaitForMessage(webview, { preload: `${fixtures}/module/preload.js`, + webpreferences: 'sandbox=no', src: `file://${fixtures}pages/base-page.html` }); @@ -303,6 +305,7 @@ describe(' tag', function () { it('resolves relative URLs', async () => { const message = await startLoadingWebViewAndWaitForMessage(webview, { preload: '../fixtures/module/preload.js', + webpreferences: 'sandbox=no', src: `file://${fixtures}/pages/e.html` }); @@ -390,6 +393,7 @@ describe(' tag', function () { const message = await startLoadingWebViewAndWaitForMessage(webview, { disablewebsecurity: '', preload: `${fixtures}/module/preload.js`, + webpreferences: 'sandbox=no', src: `file://${fixtures}/pages/e.html` }); From f1c7562d9c8b08d69fd1d83d2ded6f643df6497e Mon Sep 17 00:00:00 2001 From: "trop[bot]" <37223003+trop[bot]@users.noreply.github.com> Date: Fri, 29 Jul 2022 15:07:40 -0700 Subject: [PATCH 20/30] docs: new main -> renderers messageChannel example (#35134) * docs: new main -> renderers messageChannel example * consistent use of your * fix a typo * linting * markdown linting * Update docs/tutorial/message-ports.md Co-authored-by: Erick Zhao * update code example headings, reference contextIsolation example * remove nodeIntegration: false from browserWindows * rename "messagePort" to "electronMessagePort" for compatibility Co-authored-by: Kilian Valkhof Co-authored-by: Erick Zhao --- docs/tutorial/message-ports.md | 103 ++++++++++++++++++++++++++------- 1 file changed, 81 insertions(+), 22 deletions(-) diff --git a/docs/tutorial/message-ports.md b/docs/tutorial/message-ports.md index 9f1e9bf467aff..b236f4133e450 100644 --- a/docs/tutorial/message-ports.md +++ b/docs/tutorial/message-ports.md @@ -8,8 +8,7 @@ your app. Here is a very brief example of what a MessagePort is and how it works: -```js -// renderer.js /////////////////////////////////////////////////////////////// +```js title='renderer.js (Renderer Process)' // MessagePorts are created in pairs. A connected pair of message ports is // called a channel. const channel = new MessageChannel() @@ -28,8 +27,7 @@ port2.postMessage({ answer: 42 }) ipcRenderer.postMessage('port', null, [port1]) ``` -```js -// main.js /////////////////////////////////////////////////////////////////// +```js title='main.js (Main Process)' // In the main process, we receive the port. ipcMain.on('port', (event) => { // When we receive a MessagePort in the main process, it becomes a @@ -84,14 +82,84 @@ process, you can listen for the `close` event by calling `port.on('close', ## Example use cases +### Setting up a MessageChannel between two renderers + +In this example, the main process sets up a MessageChannel, then sends each port +to a different renderer. This allows renderers to send messages to each other +without needing to use the main process as an in-between. + +```js title='main.js (Main Process)' +const { BrowserWindow, app, MessageChannelMain } = require('electron') + +app.whenReady().then(async () => { + // create the windows. + const mainWindow = new BrowserWindow({ + show: false, + webPreferences: { + contextIsolation: false, + preload: 'preloadMain.js' + } + }) + + const secondaryWindow = BrowserWindow({ + show: false, + webPreferences: { + contextIsolation: false, + preload: 'preloadSecondary.js' + } + }) + + // set up the channel. + const { port1, port2 } = new MessageChannelMain() + + // once the webContents are ready, send a port to each webContents with postMessage. + mainWindow.once('ready-to-show', () => { + mainWindow.webContents.postMessage('port', null, [port1]) + }) + + secondaryWindow.once('ready-to-show', () => { + secondaryWindow.webContents.postMessage('port', null, [port2]) + }) +}) +``` + +Then, in your preload scripts you receive the port through IPC and set up the +listeners. + +```js title='preloadMain.js and preloadSecondary.js (Preload scripts)' +const { ipcRenderer } = require('electron') + +ipcRenderer.on('port', e => { + // port received, make it globally available. + window.electronMessagePort = e.ports[0] + + window.electronMessagePort.onmessage = messageEvent => { + // handle message + } +}) +``` + +In this example messagePort is bound to the `window` object directly. It is better +to use `contextIsolation` and set up specific contextBridge calls for each of your +expected messages, but for the simplicity of this example we don't. You can find an +example of context isolation further down this page at [Communicating directly between the main process and the main world of a context-isolated page](#communicating-directly-between-the-main-process-and-the-main-world-of-a-context-isolated-page) + +That means window.messagePort is globally available and you can call +`postMessage` on it from anywhere in your app to send a message to the other +renderer. + +```js title='renderer.js (Renderer Process)' +// elsewhere in your code to send a message to the other renderers message handler +window.electronMessagePort.postmessage('ping') +``` + ### Worker process In this example, your app has a worker process implemented as a hidden window. You want the app page to be able to communicate directly with the worker process, without the performance overhead of relaying via the main process. -```js -// main.js /////////////////////////////////////////////////////////////////// +```js title='main.js (Main Process)' const { BrowserWindow, app, ipcMain, MessageChannelMain } = require('electron') app.whenReady().then(async () => { @@ -129,8 +197,7 @@ app.whenReady().then(async () => { }) ``` -```html - +```html title='worker.html' ``` -```html - +```html title='app.html'