diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index c0fec936e9619..9668c8b3a332e 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -280,10 +280,12 @@ struct WebContents::FrameDispatchHelper { api_web_contents->OnGetZoomLevel(rfh, reply_msg); } - void OnRendererMessageSync(const std::string& channel, + void OnRendererMessageSync(bool internal, + const std::string& channel, const base::ListValue& args, IPC::Message* message) { - api_web_contents->OnRendererMessageSync(rfh, channel, args, message); + api_web_contents->OnRendererMessageSync(rfh, internal, channel, args, + message); } }; @@ -1070,6 +1072,7 @@ bool WebContents::OnMessageReceived(const IPC::Message& message, IPC_MESSAGE_FORWARD_DELAY_REPLY(AtomFrameHostMsg_Message_Sync, &helper, FrameDispatchHelper::OnRendererMessageSync) IPC_MESSAGE_HANDLER(AtomFrameHostMsg_Message_To, OnRendererMessageTo) + IPC_MESSAGE_HANDLER(AtomFrameHostMsg_Message_Host, OnRendererMessageHost) IPC_MESSAGE_FORWARD_DELAY_REPLY( AtomFrameHostMsg_SetTemporaryZoomLevel, &helper, FrameDispatchHelper::OnSetTemporaryZoomLevel) @@ -2206,18 +2209,22 @@ AtomBrowserContext* WebContents::GetBrowserContext() const { } void WebContents::OnRendererMessage(content::RenderFrameHost* frame_host, + bool internal, const std::string& channel, const base::ListValue& args) { - // webContents.emit(channel, new Event(), args...); - EmitWithSender(channel, frame_host, nullptr, args); + // webContents.emit('-ipc-message', new Event(), internal, channel, args); + EmitWithSender("-ipc-message", frame_host, nullptr, internal, channel, args); } void WebContents::OnRendererMessageSync(content::RenderFrameHost* frame_host, + bool internal, const std::string& channel, const base::ListValue& args, IPC::Message* message) { - // webContents.emit(channel, new Event(sender, message), args...); - EmitWithSender(channel, frame_host, message, args); + // webContents.emit('-ipc-message-sync', new Event(sender, message), internal, + // channel, args); + EmitWithSender("-ipc-message-sync", frame_host, message, internal, channel, + args); } void WebContents::OnRendererMessageTo(content::RenderFrameHost* frame_host, @@ -2235,6 +2242,13 @@ void WebContents::OnRendererMessageTo(content::RenderFrameHost* frame_host, } } +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, nullptr, 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 ee40928b3947c..e3e1989cb179b 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -480,11 +480,13 @@ class WebContents : public mate::TrackableObject, // Called when received a message from renderer. void OnRendererMessage(content::RenderFrameHost* frame_host, + bool internal, const std::string& channel, const base::ListValue& args); // Called when received a synchronous message from renderer. void OnRendererMessageSync(content::RenderFrameHost* frame_host, + bool internal, const std::string& channel, const base::ListValue& args, IPC::Message* message); @@ -497,6 +499,11 @@ class WebContents : public mate::TrackableObject, 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/common/api/api_messages.h b/atom/common/api/api_messages.h index 6bf95afe423a6..4ea3c12111872 100644 --- a/atom/common/api/api_messages.h +++ b/atom/common/api/api_messages.h @@ -25,11 +25,13 @@ IPC_STRUCT_TRAITS_BEGIN(atom::DraggableRegion) IPC_STRUCT_TRAITS_MEMBER(bounds) IPC_STRUCT_TRAITS_END() -IPC_MESSAGE_ROUTED2(AtomFrameHostMsg_Message, +IPC_MESSAGE_ROUTED3(AtomFrameHostMsg_Message, + bool /* internal */, std::string /* channel */, base::ListValue /* arguments */) -IPC_SYNC_MESSAGE_ROUTED2_1(AtomFrameHostMsg_Message_Sync, +IPC_SYNC_MESSAGE_ROUTED3_1(AtomFrameHostMsg_Message_Sync, + bool /* internal */, std::string /* channel */, base::ListValue /* arguments */, base::ListValue /* result */) @@ -41,6 +43,10 @@ IPC_MESSAGE_ROUTED5(AtomFrameHostMsg_Message_To, std::string /* channel */, base::ListValue /* arguments */) +IPC_MESSAGE_ROUTED2(AtomFrameHostMsg_Message_Host, + std::string /* channel */, + base::ListValue /* arguments */) + IPC_MESSAGE_ROUTED5(AtomFrameMsg_Message, bool /* internal */, bool /* send_to_all */, diff --git a/atom/common/api/remote_object_freer.cc b/atom/common/api/remote_object_freer.cc index 9712e19cbb4a3..da6ba6de8f657 100644 --- a/atom/common/api/remote_object_freer.cc +++ b/atom/common/api/remote_object_freer.cc @@ -56,13 +56,12 @@ void RemoteObjectFreer::RunDestructor() { if (!render_frame) return; - auto* channel = "ipc-internal-message"; + auto* channel = "ELECTRON_BROWSER_DEREFERENCE"; base::ListValue args; - args.AppendString("ELECTRON_BROWSER_DEREFERENCE"); args.AppendString(context_id_); args.AppendInteger(object_id_); render_frame->Send(new AtomFrameHostMsg_Message(render_frame->GetRoutingID(), - channel, args)); + true, channel, args)); } } // namespace atom diff --git a/atom/renderer/api/atom_api_renderer_ipc.cc b/atom/renderer/api/atom_api_renderer_ipc.cc index 7ec2ac6b4878a..ea7388e7b05b6 100644 --- a/atom/renderer/api/atom_api_renderer_ipc.cc +++ b/atom/renderer/api/atom_api_renderer_ipc.cc @@ -5,7 +5,6 @@ #include #include "atom/common/api/api_messages.h" -#include "atom/common/native_mate_converters/string16_converter.h" #include "atom/common/native_mate_converters/value_converter.h" #include "atom/common/node_bindings.h" #include "atom/common/node_includes.h" @@ -29,6 +28,7 @@ RenderFrame* GetCurrentRenderFrame() { } void Send(mate::Arguments* args, + bool internal, const std::string& channel, const base::ListValue& arguments) { RenderFrame* render_frame = GetCurrentRenderFrame(); @@ -36,13 +36,14 @@ void Send(mate::Arguments* args, return; bool success = render_frame->Send(new AtomFrameHostMsg_Message( - render_frame->GetRoutingID(), channel, arguments)); + render_frame->GetRoutingID(), internal, channel, arguments)); if (!success) args->ThrowError("Unable to send AtomFrameHostMsg_Message"); } base::ListValue SendSync(mate::Arguments* args, + bool internal, const std::string& channel, const base::ListValue& arguments) { base::ListValue result; @@ -52,7 +53,7 @@ base::ListValue SendSync(mate::Arguments* args, return result; IPC::SyncMessage* message = new AtomFrameHostMsg_Message_Sync( - render_frame->GetRoutingID(), channel, arguments, &result); + render_frame->GetRoutingID(), internal, channel, arguments, &result); bool success = render_frame->Send(message); if (!success) @@ -79,6 +80,20 @@ void SendTo(mate::Arguments* args, 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, @@ -87,6 +102,7 @@ void Initialize(v8::Local exports, dict.SetMethod("send", &Send); dict.SetMethod("sendSync", &SendSync); dict.SetMethod("sendTo", &SendTo); + dict.SetMethod("sendToHost", &SendToHost); } } // namespace diff --git a/atom/renderer/atom_render_frame_observer.cc b/atom/renderer/atom_render_frame_observer.cc index a3c99841a56d4..f8a54a199ee1c 100644 --- a/atom/renderer/atom_render_frame_observer.cc +++ b/atom/renderer/atom_render_frame_observer.cc @@ -212,11 +212,10 @@ void AtomRenderFrameObserver::OnTakeHeapSnapshot( bool success = TakeHeapSnapshot(blink::MainThreadIsolate(), &file); base::ListValue args; - args.AppendString(channel); args.AppendBoolean(success); render_frame_->Send(new AtomFrameHostMsg_Message( - render_frame_->GetRoutingID(), "ipc-internal-message", args)); + render_frame_->GetRoutingID(), true, channel, args)); } void AtomRenderFrameObserver::EmitIPCEvent(blink::WebLocalFrame* frame, diff --git a/atom/renderer/atom_sandboxed_renderer_client.cc b/atom/renderer/atom_sandboxed_renderer_client.cc index 9bf99db1f1c95..b02ab6983a874 100644 --- a/atom/renderer/atom_sandboxed_renderer_client.cc +++ b/atom/renderer/atom_sandboxed_renderer_client.cc @@ -114,11 +114,12 @@ class AtomSandboxedRenderFrameObserver : public AtomRenderFrameObserver { auto context = renderer_client_->GetContext(frame, isolate); v8::Context::Scope context_scope(context); - v8::Local argv[] = {mate::ConvertToV8(isolate, channel), + v8::Local argv[] = {mate::ConvertToV8(isolate, internal), + mate::ConvertToV8(isolate, channel), mate::ConvertToV8(isolate, args), mate::ConvertToV8(isolate, sender_id)}; renderer_client_->InvokeIpcCallback( - context, internal ? "onInternalMessage" : "onMessage", + context, "onMessage", std::vector>(argv, argv + node::arraysize(argv))); } diff --git a/lib/browser/api/web-contents.js b/lib/browser/api/web-contents.js index adbe7e5710d5a..9e36231964b4e 100644 --- a/lib/browser/api/web-contents.js +++ b/lib/browser/api/web-contents.js @@ -358,6 +358,13 @@ const addReplyInternalToEvent = (event) => { }) } +const addReturnValueToEvent = (event) => { + Object.defineProperty(event, 'returnValue', { + set: (value) => event.sendReply([value]), + get: () => {} + }) +} + // Add JavaScript wrappers for WebContents class. WebContents.prototype._init = function () { // The navigation controller. @@ -370,38 +377,27 @@ WebContents.prototype._init = function () { this.capturePage = deprecate.promisify(this.capturePage, 2) // Dispatch IPC messages to the ipc module. - this.on('-ipc-message', function (event, [channel, ...args]) { - addReplyToEvent(event) - this.emit('ipc-message', event, channel, ...args) - ipcMain.emit(channel, event, ...args) - }) - - this.on('-ipc-message-sync', function (event, [channel, ...args]) { - Object.defineProperty(event, 'returnValue', { - set: function (value) { - return event.sendReply([value]) - }, - get: function () {} - }) - addReplyToEvent(event) - this.emit('ipc-message-sync', event, channel, ...args) - ipcMain.emit(channel, event, ...args) - }) - - this.on('ipc-internal-message', function (event, [channel, ...args]) { - addReplyInternalToEvent(event) - ipcMainInternal.emit(channel, event, ...args) + this.on('-ipc-message', function (event, internal, channel, args) { + if (internal) { + addReplyInternalToEvent(event) + ipcMainInternal.emit(channel, event, ...args) + } else { + addReplyToEvent(event) + this.emit('ipc-message', event, channel, ...args) + ipcMain.emit(channel, event, ...args) + } }) - this.on('ipc-internal-message-sync', function (event, [channel, ...args]) { - Object.defineProperty(event, 'returnValue', { - set: function (value) { - return event.sendReply([value]) - }, - get: function () {} - }) - addReplyInternalToEvent(event) - ipcMainInternal.emit(channel, event, ...args) + this.on('-ipc-message-sync', function (event, internal, channel, args) { + addReturnValueToEvent(event) + if (internal) { + addReplyInternalToEvent(event) + ipcMainInternal.emit(channel, event, ...args) + } else { + addReplyToEvent(event) + this.emit('ipc-message-sync', event, channel, ...args) + ipcMain.emit(channel, event, ...args) + } }) // Handle context menu action request from pepper plugin. diff --git a/lib/browser/guest-view-manager.js b/lib/browser/guest-view-manager.js index 920b02021ae65..7e507fe2d2be3 100644 --- a/lib/browser/guest-view-manager.js +++ b/lib/browser/guest-view-manager.js @@ -140,7 +140,7 @@ const createGuest = function (embedder, params) { } // Dispatch guest's IPC messages to embedder. - guest.on('ipc-message-host', function (_, [channel, ...args]) { + guest.on('ipc-message-host', function (_, channel, args) { sendToEmbedder('ELECTRON_GUEST_VIEW_INTERNAL_IPC_MESSAGE', channel, ...args) }) diff --git a/lib/renderer/api/ipc-renderer.js b/lib/renderer/api/ipc-renderer.js index 1911543e42a7c..95b90280b06fd 100644 --- a/lib/renderer/api/ipc-renderer.js +++ b/lib/renderer/api/ipc-renderer.js @@ -7,16 +7,16 @@ const v8Util = process.atomBinding('v8_util') const ipcRenderer = v8Util.getHiddenValue(global, 'ipc') const internal = false -ipcRenderer.send = function (...args) { - return binding.send('-ipc-message', args) +ipcRenderer.send = function (channel, ...args) { + return binding.send(internal, channel, args) } -ipcRenderer.sendSync = function (...args) { - return binding.sendSync('-ipc-message-sync', args)[0] +ipcRenderer.sendSync = function (channel, ...args) { + return binding.sendSync(internal, channel, args)[0] } -ipcRenderer.sendToHost = function (...args) { - return binding.send('ipc-message-host', args) +ipcRenderer.sendToHost = function (channel, ...args) { + return binding.sendToHost(channel, args) } ipcRenderer.sendTo = function (webContentsId, channel, ...args) { diff --git a/lib/renderer/ipc-renderer-internal.js b/lib/renderer/ipc-renderer-internal.js index a8dda32632b6c..b3da4d8887f4a 100644 --- a/lib/renderer/ipc-renderer-internal.js +++ b/lib/renderer/ipc-renderer-internal.js @@ -7,12 +7,12 @@ const v8Util = process.atomBinding('v8_util') const ipcRenderer = v8Util.getHiddenValue(global, 'ipc-internal') const internal = true -ipcRenderer.send = function (...args) { - return binding.send('ipc-internal-message', args) +ipcRenderer.send = function (channel, ...args) { + return binding.send(internal, channel, args) } -ipcRenderer.sendSync = function (...args) { - return binding.sendSync('ipc-internal-message-sync', args)[0] +ipcRenderer.sendSync = function (channel, ...args) { + return binding.sendSync(internal, channel, args)[0] } ipcRenderer.sendTo = function (webContentsId, channel, ...args) { diff --git a/lib/sandboxed_renderer/init.js b/lib/sandboxed_renderer/init.js index f45e8edb35cce..232c4f4d3568a 100644 --- a/lib/sandboxed_renderer/init.js +++ b/lib/sandboxed_renderer/init.js @@ -56,12 +56,12 @@ const loadedModules = new Map([ const ipcNative = process.atomBinding('ipc') v8Util.setHiddenValue(global, 'ipcNative', ipcNative) -ipcNative.onInternalMessage = function (channel, args, senderId) { - ipcRenderer.emit(channel, { sender: ipcRenderer, senderId }, ...args) -} - -ipcNative.onMessage = function (channel, args, senderId) { - electron.ipcRenderer.emit(channel, { sender: electron.ipcRenderer, senderId }, ...args) +ipcNative.onMessage = function (internal, channel, args, senderId) { + if (internal) { + ipcRenderer.emit(channel, { sender: ipcRenderer, senderId }, ...args) + } else { + electron.ipcRenderer.emit(channel, { sender: electron.ipcRenderer, senderId }, ...args) + } } ipcNative.onExit = function () {