From 127b87c71379661e5e99152d81b368b544326173 Mon Sep 17 00:00:00 2001 From: Jeremy Apthorp Date: Wed, 3 Apr 2019 14:22:23 -0700 Subject: [PATCH] refactor: mojofy MessageTo and MessageHost (#17613) --- atom/browser/api/atom_api_web_contents.cc | 56 ++++++++++++---------- atom/browser/api/atom_api_web_contents.h | 20 +++----- atom/browser/ui/webui/pdf_viewer_ui.cc | 1 - atom/common/api/api.mojom | 18 +++++++ atom/common/api/api_messages.h | 16 ------- atom/renderer/api/atom_api_renderer_ipc.cc | 54 ++++++++------------- lib/renderer/api/ipc-renderer.js | 12 ++--- 7 files changed, 82 insertions(+), 95 deletions(-) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index ab9a5f2d5825..3c501e86b239 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -275,6 +275,8 @@ WebContents::WebContents(v8::Isolate* isolate, InitZoomController(web_contents, mate::Dictionary::CreateEmpty(isolate)); registry_.AddInterface(base::BindRepeating(&WebContents::BindElectronBrowser, base::Unretained(this))); + bindings_.set_connection_error_handler(base::BindRepeating( + &WebContents::OnElectronBrowserConnectionError, base::Unretained(this))); } WebContents::WebContents(v8::Isolate* isolate, @@ -424,6 +426,8 @@ void WebContents::InitWithSessionAndOptions( registry_.AddInterface(base::BindRepeating(&WebContents::BindElectronBrowser, base::Unretained(this))); + bindings_.set_connection_error_handler(base::BindRepeating( + &WebContents::OnElectronBrowserConnectionError, base::Unretained(this))); web_contents()->SetUserAgentOverride(GetBrowserContext()->GetUserAgent(), false); @@ -900,6 +904,12 @@ void WebContents::BindElectronBrowser( frame_to_bindings_map_[render_frame_host].push_back(id); } +void WebContents::OnElectronBrowserConnectionError() { + auto binding_id = bindings_.dispatch_binding(); + auto* frame_host = bindings_.dispatch_context(); + base::Erase(frame_to_bindings_map_[frame_host], binding_id); +} + void WebContents::Message(bool internal, const std::string& channel, base::Value arguments) { @@ -919,6 +929,28 @@ void WebContents::MessageSync(bool internal, std::move(callback), internal, channel, std::move(arguments)); } +void WebContents::MessageTo(bool internal, + bool send_to_all, + int32_t web_contents_id, + const std::string& channel, + base::Value arguments) { + auto* web_contents = mate::TrackableObject::FromWeakMapID( + isolate(), web_contents_id); + + if (web_contents) { + web_contents->SendIPCMessageWithSender(internal, send_to_all, channel, + base::ListValue(arguments.GetList()), + ID()); + } +} + +void WebContents::MessageHost(const std::string& channel, + base::Value arguments) { + // webContents.emit('ipc-message-host', new Event(), channel, args); + EmitWithSender("ipc-message-host", bindings_.dispatch_context(), + base::nullopt, channel, std::move(arguments)); +} + void WebContents::RenderFrameDeleted( content::RenderFrameHost* render_frame_host) { // A RenderFrameHost can be destroyed before the related Mojo binding is @@ -1097,8 +1129,6 @@ bool WebContents::OnMessageReceived(const IPC::Message& message, bool handled = true; FrameDispatchHelper helper = {this, frame_host}; IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(WebContents, message, frame_host) - IPC_MESSAGE_HANDLER(AtomFrameHostMsg_Message_To, OnRendererMessageTo) - IPC_MESSAGE_HANDLER(AtomFrameHostMsg_Message_Host, OnRendererMessageHost) IPC_MESSAGE_FORWARD_DELAY_REPLY( AtomFrameHostMsg_SetTemporaryZoomLevel, &helper, FrameDispatchHelper::OnSetTemporaryZoomLevel) @@ -2258,28 +2288,6 @@ AtomBrowserContext* WebContents::GetBrowserContext() const { return static_cast(web_contents()->GetBrowserContext()); } -void WebContents::OnRendererMessageTo(content::RenderFrameHost* frame_host, - bool internal, - bool send_to_all, - int32_t web_contents_id, - const std::string& channel, - const base::ListValue& args) { - auto* web_contents = mate::TrackableObject::FromWeakMapID( - isolate(), web_contents_id); - - if (web_contents) { - web_contents->SendIPCMessageWithSender(internal, send_to_all, channel, args, - ID()); - } -} - -void WebContents::OnRendererMessageHost(content::RenderFrameHost* frame_host, - const std::string& channel, - const base::ListValue& args) { - // webContents.emit('ipc-message-host', new Event(), channel, args); - EmitWithSender("ipc-message-host", frame_host, base::nullopt, channel, args); -} - // static mate::Handle WebContents::Create(v8::Isolate* isolate, const mate::Dictionary& options) { diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index 053c252bf894..dd3e83f79dc4 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -479,6 +479,7 @@ class WebContents : public mate::TrackableObject, // RenderFrameHost is destroyed, all related bindings will be removed. void BindElectronBrowser(mojom::ElectronBrowserRequest request, content::RenderFrameHost* render_frame_host); + void OnElectronBrowserConnectionError(); uint32_t GetNextRequestId() { return ++request_id_; } @@ -495,23 +496,16 @@ class WebContents : public mate::TrackableObject, const std::string& channel, base::Value arguments, MessageSyncCallback callback) override; + void MessageTo(bool internal, + bool send_to_all, + int32_t web_contents_id, + const std::string& channel, + base::Value arguments) override; + void MessageHost(const std::string& channel, base::Value arguments) override; // Called when we receive a CursorChange message from chromium. void OnCursorChange(const content::WebCursor& cursor); - // Called when received a message from renderer to be forwarded. - void OnRendererMessageTo(content::RenderFrameHost* frame_host, - bool internal, - bool send_to_all, - int32_t web_contents_id, - const std::string& channel, - const base::ListValue& args); - - // Called when received a message from renderer to host. - void OnRendererMessageHost(content::RenderFrameHost* frame_host, - const std::string& channel, - const base::ListValue& args); - // Called when received a synchronous message from renderer to // set temporary zoom level. void OnSetTemporaryZoomLevel(content::RenderFrameHost* frame_host, diff --git a/atom/browser/ui/webui/pdf_viewer_ui.cc b/atom/browser/ui/webui/pdf_viewer_ui.cc index e364050f1f8f..8750824c5ad0 100644 --- a/atom/browser/ui/webui/pdf_viewer_ui.cc +++ b/atom/browser/ui/webui/pdf_viewer_ui.cc @@ -222,7 +222,6 @@ bool PdfViewerUI::OnMessageReceived( content::RenderFrameHost* render_frame_host) { bool handled = true; IPC_BEGIN_MESSAGE_MAP(PdfViewerUI, message) - IPC_MESSAGE_HANDLER(AtomFrameHostMsg_PDFSaveURLAs, OnSaveURLAs) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() return handled; diff --git a/atom/common/api/api.mojom b/atom/common/api/api.mojom index 844080f46d51..abd87fe6a815 100644 --- a/atom/common/api/api.mojom +++ b/atom/common/api/api.mojom @@ -14,11 +14,16 @@ interface ElectronRenderer { }; interface ElectronBrowser { + // Emits an event on |channel| from the ipcMain JavaScript object in the main + // process. Message( bool internal, string channel, mojo_base.mojom.ListValue arguments); + // Emits an event on |channel| from the ipcMain JavaScript object in the main + // process, and waits synchronously for a response. + // // NB. this is not marked [Sync] because mojo synchronous methods can be // reordered with respect to asynchronous methods on the same channel. // Instead, callers can manually block on the response to this method. @@ -26,4 +31,17 @@ interface ElectronBrowser { bool internal, string channel, mojo_base.mojom.ListValue arguments) => (mojo_base.mojom.Value result); + + // Emits an event from the |ipcRenderer| JavaScript object in the target + // WebContents's main frame, specified by |web_contents_id|. + MessageTo( + bool internal, + bool send_to_all, + int32 web_contents_id, + string channel, + mojo_base.mojom.ListValue arguments); + + MessageHost( + string channel, + mojo_base.mojom.ListValue arguments); }; diff --git a/atom/common/api/api_messages.h b/atom/common/api/api_messages.h index ac416256bcc8..8f6a773cd850 100644 --- a/atom/common/api/api_messages.h +++ b/atom/common/api/api_messages.h @@ -25,17 +25,6 @@ IPC_STRUCT_TRAITS_BEGIN(atom::DraggableRegion) IPC_STRUCT_TRAITS_MEMBER(bounds) IPC_STRUCT_TRAITS_END() -IPC_MESSAGE_ROUTED5(AtomFrameHostMsg_Message_To, - bool /* internal */, - bool /* send_to_all */, - int32_t /* web_contents_id */, - std::string /* channel */, - base::ListValue /* arguments */) - -IPC_MESSAGE_ROUTED2(AtomFrameHostMsg_Message_Host, - std::string /* channel */, - base::ListValue /* arguments */) - IPC_MESSAGE_ROUTED0(AtomViewMsg_Offscreen) IPC_MESSAGE_ROUTED3(AtomAutofillFrameHostMsg_ShowPopup, @@ -62,8 +51,3 @@ IPC_SYNC_MESSAGE_ROUTED1_1(AtomFrameHostMsg_SetTemporaryZoomLevel, // Sent by renderer to get the zoom level. IPC_SYNC_MESSAGE_ROUTED0_1(AtomFrameHostMsg_GetZoomLevel, double /* result */) - -// Brings up SaveAs... dialog to save specified URL. -IPC_MESSAGE_ROUTED2(AtomFrameHostMsg_PDFSaveURLAs, - GURL /* url */, - content::Referrer /* referrer */) diff --git a/atom/renderer/api/atom_api_renderer_ipc.cc b/atom/renderer/api/atom_api_renderer_ipc.cc index d5df9f1012f9..295ead588c3b 100644 --- a/atom/renderer/api/atom_api_renderer_ipc.cc +++ b/atom/renderer/api/atom_api_renderer_ipc.cc @@ -47,7 +47,9 @@ class IPCRenderer : public mate::Wrappable { prototype->SetClassName(mate::StringToV8(isolate, "IPCRenderer")); mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate()) .SetMethod("send", &IPCRenderer::Send) - .SetMethod("sendSync", &IPCRenderer::SendSync); + .SetMethod("sendSync", &IPCRenderer::SendSync) + .SetMethod("sendTo", &IPCRenderer::SendTo) + .SetMethod("sendToHost", &IPCRenderer::SendToHost); } static mate::Handle Create(v8::Isolate* isolate) { return mate::CreateHandle(isolate, new IPCRenderer(isolate)); @@ -60,6 +62,22 @@ class IPCRenderer : public mate::Wrappable { electron_browser_ptr_->Message(internal, channel, arguments.Clone()); } + void SendTo(mate::Arguments* args, + bool internal, + bool send_to_all, + int32_t web_contents_id, + const std::string& channel, + const base::ListValue& arguments) { + electron_browser_ptr_->MessageTo(internal, send_to_all, web_contents_id, + channel, arguments.Clone()); + } + + void SendToHost(mate::Arguments* args, + const std::string& channel, + const base::ListValue& arguments) { + electron_browser_ptr_->MessageHost(channel, arguments.Clone()); + } + base::Value SendSync(mate::Arguments* args, bool internal, const std::string& channel, @@ -119,46 +137,12 @@ class IPCRenderer : public mate::Wrappable { atom::mojom::ElectronBrowserPtr electron_browser_ptr_; }; -void SendTo(mate::Arguments* args, - bool internal, - bool send_to_all, - int32_t web_contents_id, - const std::string& channel, - const base::ListValue& arguments) { - RenderFrame* render_frame = GetCurrentRenderFrame(); - if (render_frame == nullptr) - return; - - bool success = render_frame->Send(new AtomFrameHostMsg_Message_To( - render_frame->GetRoutingID(), internal, send_to_all, web_contents_id, - channel, arguments)); - - if (!success) - args->ThrowError("Unable to send AtomFrameHostMsg_Message_To"); -} - -void SendToHost(mate::Arguments* args, - const std::string& channel, - const base::ListValue& arguments) { - RenderFrame* render_frame = GetCurrentRenderFrame(); - if (render_frame == nullptr) - return; - - bool success = render_frame->Send(new AtomFrameHostMsg_Message_Host( - render_frame->GetRoutingID(), channel, arguments)); - - if (!success) - args->ThrowError("Unable to send AtomFrameHostMsg_Message_Host"); -} - void Initialize(v8::Local exports, v8::Local unused, v8::Local context, void* priv) { mate::Dictionary dict(context->GetIsolate(), exports); dict.Set("ipc", IPCRenderer::Create(context->GetIsolate())); - dict.SetMethod("sendTo", &SendTo); - dict.SetMethod("sendToHost", &SendToHost); } } // namespace diff --git a/lib/renderer/api/ipc-renderer.js b/lib/renderer/api/ipc-renderer.js index b0a242a12dd4..8705882d732c 100644 --- a/lib/renderer/api/ipc-renderer.js +++ b/lib/renderer/api/ipc-renderer.js @@ -1,6 +1,6 @@ 'use strict' -const binding = process.electronBinding('ipc') +const { ipc } = process.electronBinding('ipc') const v8Util = process.electronBinding('v8_util') // Created by init.js. @@ -8,23 +8,23 @@ const ipcRenderer = v8Util.getHiddenValue(global, 'ipc') const internal = false ipcRenderer.send = function (channel, ...args) { - return binding.ipc.send(internal, channel, args) + return ipc.send(internal, channel, args) } ipcRenderer.sendSync = function (channel, ...args) { - return binding.ipc.sendSync(internal, channel, args)[0] + return ipc.sendSync(internal, channel, args)[0] } ipcRenderer.sendToHost = function (channel, ...args) { - return binding.sendToHost(channel, args) + return ipc.sendToHost(channel, args) } ipcRenderer.sendTo = function (webContentsId, channel, ...args) { - return binding.sendTo(internal, false, webContentsId, channel, args) + return ipc.sendTo(internal, false, webContentsId, channel, args) } ipcRenderer.sendToAll = function (webContentsId, channel, ...args) { - return binding.sendTo(internal, true, webContentsId, channel, args) + return ipc.sendTo(internal, true, webContentsId, channel, args) } module.exports = ipcRenderer