chore: make rpc-server reply to sender frame instead of the main frame (#15973)

* chore: make rpc-server reply to frame

* fix: check IsRenderFrameLive
This commit is contained in:
Cheng Zhao 2018-12-10 09:37:42 +09:00 committed by GitHub
parent eb8fcf833c
commit db2fda1b6f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 51 additions and 10 deletions

View file

@ -1674,6 +1674,23 @@ bool WebContents::SendIPCMessageWithSender(bool internal,
return false; return false;
} }
bool WebContents::SendIPCMessageToFrame(bool internal,
bool send_to_all,
int32_t frame_id,
const std::string& channel,
const base::ListValue& args) {
auto frames = web_contents()->GetAllFrames();
auto iter = std::find_if(frames.begin(), frames.end(), [frame_id](auto* f) {
return f->GetRoutingID() == frame_id;
});
if (iter == frames.end())
return false;
if (!(*iter)->IsRenderFrameLive())
return false;
return (*iter)->Send(new AtomFrameMsg_Message(
frame_id, internal, send_to_all, channel, args, 0 /* sender_id */));
}
void WebContents::SendInputEvent(v8::Isolate* isolate, void WebContents::SendInputEvent(v8::Isolate* isolate,
v8::Local<v8::Value> input_event) { v8::Local<v8::Value> input_event) {
content::RenderWidgetHostView* view = content::RenderWidgetHostView* view =
@ -2119,6 +2136,7 @@ void WebContents::BuildPrototype(v8::Isolate* isolate,
.SetMethod("isFocused", &WebContents::IsFocused) .SetMethod("isFocused", &WebContents::IsFocused)
.SetMethod("tabTraverse", &WebContents::TabTraverse) .SetMethod("tabTraverse", &WebContents::TabTraverse)
.SetMethod("_send", &WebContents::SendIPCMessage) .SetMethod("_send", &WebContents::SendIPCMessage)
.SetMethod("_sendToFrame", &WebContents::SendIPCMessageToFrame)
.SetMethod("sendInputEvent", &WebContents::SendInputEvent) .SetMethod("sendInputEvent", &WebContents::SendInputEvent)
.SetMethod("beginFrameSubscription", &WebContents::BeginFrameSubscription) .SetMethod("beginFrameSubscription", &WebContents::BeginFrameSubscription)
.SetMethod("endFrameSubscription", &WebContents::EndFrameSubscription) .SetMethod("endFrameSubscription", &WebContents::EndFrameSubscription)
@ -2183,7 +2201,7 @@ void WebContents::OnRendererMessage(content::RenderFrameHost* frame_host,
const std::string& channel, const std::string& channel,
const base::ListValue& args) { const base::ListValue& args) {
// webContents.emit(channel, new Event(), args...); // webContents.emit(channel, new Event(), args...);
Emit(channel, args); EmitWithSender(channel, frame_host, nullptr, args);
} }
void WebContents::OnRendererMessageSync(content::RenderFrameHost* frame_host, void WebContents::OnRendererMessageSync(content::RenderFrameHost* frame_host,

View file

@ -218,6 +218,12 @@ class WebContents : public mate::TrackableObject<WebContents>,
const base::ListValue& args, const base::ListValue& args,
int32_t sender_id = 0); int32_t sender_id = 0);
bool SendIPCMessageToFrame(bool internal,
bool send_to_all,
int32_t frame_id,
const std::string& channel,
const base::ListValue& args);
// Send WebInputEvent to the page. // Send WebInputEvent to the page.
void SendInputEvent(v8::Isolate* isolate, v8::Local<v8::Value> input_event); void SendInputEvent(v8::Isolate* isolate, v8::Local<v8::Value> input_event);

View file

@ -5,6 +5,7 @@
#include "atom/browser/api/event_emitter.h" #include "atom/browser/api/event_emitter.h"
#include "atom/browser/api/event.h" #include "atom/browser/api/event.h"
#include "content/public/browser/render_frame_host.h"
#include "native_mate/arguments.h" #include "native_mate/arguments.h"
#include "native_mate/dictionary.h" #include "native_mate/dictionary.h"
#include "native_mate/object_template_builder.h" #include "native_mate/object_template_builder.h"
@ -56,6 +57,8 @@ v8::Local<v8::Object> CreateJSEvent(v8::Isolate* isolate,
event = CreateEventObject(isolate); event = CreateEventObject(isolate);
} }
mate::Dictionary(isolate, event).Set("sender", object); mate::Dictionary(isolate, event).Set("sender", object);
if (sender)
mate::Dictionary(isolate, event).Set("frameId", sender->GetRoutingID());
return event; return event;
} }

View file

@ -142,6 +142,18 @@ WebContents.prototype._sendInternalToAll = function (channel, ...args) {
return this._send(internal, sendToAll, channel, args) return this._send(internal, sendToAll, channel, args)
} }
WebContents.prototype._sendToFrameInternal = function (frameId, channel, ...args) {
if (typeof channel !== 'string') {
throw new Error('Missing required channel argument')
} else if (typeof frameId !== 'number') {
throw new Error('Missing required frameId argument')
}
const internal = true
const sendToAll = false
return this._sendToFrame(internal, sendToAll, frameId, channel, args)
}
// Following methods are mapped to webFrame. // Following methods are mapped to webFrame.
const webFrameMethods = [ const webFrameMethods = [

View file

@ -174,7 +174,7 @@ const removeRemoteListenersAndLogWarning = (sender, callIntoRenderer) => {
} }
// Convert array of meta data from renderer into array of real values. // Convert array of meta data from renderer into array of real values.
const unwrapArgs = function (sender, contextId, args) { const unwrapArgs = function (sender, frameId, contextId, args) {
const metaToValue = function (meta) { const metaToValue = function (meta) {
switch (meta.type) { switch (meta.type) {
case 'value': case 'value':
@ -182,7 +182,7 @@ const unwrapArgs = function (sender, contextId, args) {
case 'remote-object': case 'remote-object':
return objectsRegistry.get(meta.id) return objectsRegistry.get(meta.id)
case 'array': case 'array':
return unwrapArgs(sender, contextId, meta.value) return unwrapArgs(sender, frameId, contextId, meta.value)
case 'buffer': case 'buffer':
return bufferUtils.metaToBuffer(meta.value) return bufferUtils.metaToBuffer(meta.value)
case 'date': case 'date':
@ -216,9 +216,11 @@ const unwrapArgs = function (sender, contextId, args) {
} }
const callIntoRenderer = function (...args) { const callIntoRenderer = function (...args) {
let succeed = false
if (!sender.isDestroyed()) { if (!sender.isDestroyed()) {
sender._sendInternal('ELECTRON_RENDERER_CALLBACK', contextId, meta.id, valueToMeta(sender, contextId, args)) succeed = sender._sendToFrameInternal(frameId, 'ELECTRON_RENDERER_CALLBACK', contextId, meta.id, valueToMeta(sender, contextId, args))
} else { }
if (!succeed) {
removeRemoteListenersAndLogWarning(this, callIntoRenderer) removeRemoteListenersAndLogWarning(this, callIntoRenderer)
} }
} }
@ -334,7 +336,7 @@ handleRemoteCommand('ELECTRON_BROWSER_CURRENT_WEB_CONTENTS', function (event, co
}) })
handleRemoteCommand('ELECTRON_BROWSER_CONSTRUCTOR', function (event, contextId, id, args) { handleRemoteCommand('ELECTRON_BROWSER_CONSTRUCTOR', function (event, contextId, id, args) {
args = unwrapArgs(event.sender, contextId, args) args = unwrapArgs(event.sender, event.frameId, contextId, args)
const constructor = objectsRegistry.get(id) const constructor = objectsRegistry.get(id)
if (constructor == null) { if (constructor == null) {
@ -345,7 +347,7 @@ handleRemoteCommand('ELECTRON_BROWSER_CONSTRUCTOR', function (event, contextId,
}) })
handleRemoteCommand('ELECTRON_BROWSER_FUNCTION_CALL', function (event, contextId, id, args) { handleRemoteCommand('ELECTRON_BROWSER_FUNCTION_CALL', function (event, contextId, id, args) {
args = unwrapArgs(event.sender, contextId, args) args = unwrapArgs(event.sender, event.frameId, contextId, args)
const func = objectsRegistry.get(id) const func = objectsRegistry.get(id)
if (func == null) { if (func == null) {
@ -356,7 +358,7 @@ handleRemoteCommand('ELECTRON_BROWSER_FUNCTION_CALL', function (event, contextId
}) })
handleRemoteCommand('ELECTRON_BROWSER_MEMBER_CONSTRUCTOR', function (event, contextId, id, method, args) { handleRemoteCommand('ELECTRON_BROWSER_MEMBER_CONSTRUCTOR', function (event, contextId, id, method, args) {
args = unwrapArgs(event.sender, contextId, args) args = unwrapArgs(event.sender, event.frameId, contextId, args)
const object = objectsRegistry.get(id) const object = objectsRegistry.get(id)
if (object == null) { if (object == null) {
@ -367,7 +369,7 @@ handleRemoteCommand('ELECTRON_BROWSER_MEMBER_CONSTRUCTOR', function (event, cont
}) })
handleRemoteCommand('ELECTRON_BROWSER_MEMBER_CALL', function (event, contextId, id, method, args) { handleRemoteCommand('ELECTRON_BROWSER_MEMBER_CALL', function (event, contextId, id, method, args) {
args = unwrapArgs(event.sender, contextId, args) args = unwrapArgs(event.sender, event.frameId, contextId, args)
const obj = objectsRegistry.get(id) const obj = objectsRegistry.get(id)
if (obj == null) { if (obj == null) {
@ -378,7 +380,7 @@ handleRemoteCommand('ELECTRON_BROWSER_MEMBER_CALL', function (event, contextId,
}) })
handleRemoteCommand('ELECTRON_BROWSER_MEMBER_SET', function (event, contextId, id, name, args) { handleRemoteCommand('ELECTRON_BROWSER_MEMBER_SET', function (event, contextId, id, name, args) {
args = unwrapArgs(event.sender, contextId, args) args = unwrapArgs(event.sender, event.frameId, contextId, args)
const obj = objectsRegistry.get(id) const obj = objectsRegistry.get(id)
if (obj == null) { if (obj == null) {