Skip to content
This repository has been archived by the owner on Jan 4, 2019. It is now read-only.

Commit

Permalink
remote callbacks are still used in electron.remote.Menu in browser-la…
Browse files Browse the repository at this point in the history
…ptop
  • Loading branch information
bridiver committed Dec 5, 2017
1 parent 4419f6e commit 237a6ee
Show file tree
Hide file tree
Showing 6 changed files with 133 additions and 0 deletions.
2 changes: 2 additions & 0 deletions atom/common/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ source_set("common") {
"api/api_messages.h",
"api/object_life_monitor.cc",
"api/object_life_monitor.h",
"api/remote_callback_freer.cc",
"api/remote_callback_freer.h",
"api/remote_object_freer.cc",
"api/remote_object_freer.h",
"asar/archive.cc",
Expand Down
2 changes: 2 additions & 0 deletions atom/common/api/atom_api_v8_util.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <utility>

#include "atom/common/api/atom_api_key_weak_map.h"
#include "atom/common/api/remote_callback_freer.h"
#include "atom/common/api/remote_object_freer.h"
#include "atom/common/native_mate_converters/content_converter.h"
#include "atom/common/node_includes.h"
Expand Down Expand Up @@ -99,6 +100,7 @@ void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
dict.SetMethod("deleteHiddenValue", &DeleteHiddenValue);
dict.SetMethod("getObjectHash", &GetObjectHash);
dict.SetMethod("takeHeapSnapshot", &TakeHeapSnapshot);
dict.SetMethod("setRemoteCallbackFreer", &atom::RemoteCallbackFreer::BindTo);
dict.SetMethod("setRemoteObjectFreer", &atom::RemoteObjectFreer::BindTo);
dict.SetMethod("createIDWeakMap", &atom::api::KeyWeakMap<int32_t>::Create);
dict.SetMethod("createDoubleIDWeakMap",
Expand Down
51 changes: 51 additions & 0 deletions atom/common/api/remote_callback_freer.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright (c) 2016 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#include "atom/common/api/remote_callback_freer.h"

#include "atom/common/api/api_messages.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"

namespace atom {

// static
void RemoteCallbackFreer::BindTo(v8::Isolate* isolate,
v8::Local<v8::Object> target,
int object_id,
content::WebContents* web_contents) {
new RemoteCallbackFreer(isolate, target, object_id, web_contents);
}

RemoteCallbackFreer::RemoteCallbackFreer(v8::Isolate* isolate,
v8::Local<v8::Object> target,
int object_id,
content::WebContents* web_contents)
: ObjectLifeMonitor(isolate, target),
content::WebContentsObserver(web_contents),
object_id_(object_id) {
}

RemoteCallbackFreer::~RemoteCallbackFreer() {
}

void RemoteCallbackFreer::RunDestructor() {
base::string16 channel =
base::ASCIIToUTF16("ELECTRON_RENDERER_RELEASE_CALLBACK");
base::ListValue args;
args.AppendInteger(object_id_);
web_contents()->GetRenderViewHost()->Send(new AtomViewMsg_Message(
web_contents()->GetRenderViewHost()->GetRoutingID(), channel,
args));

Observe(nullptr);
}

void RemoteCallbackFreer::RenderViewDeleted(content::RenderViewHost*) {
delete this;
}

} // namespace atom
40 changes: 40 additions & 0 deletions atom/common/api/remote_callback_freer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Copyright (c) 2016 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#ifndef ATOM_COMMON_API_REMOTE_CALLBACK_FREER_H_
#define ATOM_COMMON_API_REMOTE_CALLBACK_FREER_H_
#include "atom/common/api/object_life_monitor.h"
#include "content/public/browser/web_contents_observer.h"

namespace atom {

class RemoteCallbackFreer : public ObjectLifeMonitor,
public content::WebContentsObserver {
public:
static void BindTo(v8::Isolate* isolate,
v8::Local<v8::Object> target,
int object_id,
content::WebContents* web_conents);

protected:
RemoteCallbackFreer(v8::Isolate* isolate,
v8::Local<v8::Object> target,
int object_id,
content::WebContents* web_conents);
~RemoteCallbackFreer() override;

void RunDestructor() override;

// content::WebContentsObserver:
void RenderViewDeleted(content::RenderViewHost*) override;

private:
int object_id_;

DISALLOW_COPY_AND_ASSIGN(RemoteCallbackFreer);
};

} // namespace atom

#endif // ATOM_COMMON_API_REMOTE_CALLBACK_FREER_H_
28 changes: 28 additions & 0 deletions lib/browser/rpc-server.js
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,34 @@ const unwrapArgs = function (sender, args) {
}
return ret
}
case 'function-with-return-value':
returnValue = metaToValue(meta.value)
return function () {
return returnValue
}
case 'function': {
// Merge webContentsId and meta.id, since meta.id can be the same in
// different webContents.
const webContentsId = sender.getId()
const objectId = [webContentsId, meta.id]

// Cache the callbacks in renderer.
if (rendererFunctions.has(objectId)) {
return rendererFunctions.get(objectId)
}

let callIntoRenderer = function (...args) {
if (!sender.isDestroyed() && webContentsId === sender.getId()) {
sender.send('ELECTRON_RENDERER_CALLBACK', meta.id, valueToMeta(sender, args))
} else {
throw new Error(`Attempting to call a function in a renderer window that has been closed or released. Function provided here: ${meta.location}.`)
}
}

v8Util.setRemoteCallbackFreer(callIntoRenderer, meta.id, sender)
rendererFunctions.set(objectId, callIntoRenderer)
return callIntoRenderer
}
default:
throw new TypeError(`Unknown type: ${meta.type}`)
}
Expand Down
10 changes: 10 additions & 0 deletions lib/renderer/api/remote.js
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,16 @@ const metaToPlainObject = function (meta) {
return obj
}

// Browser calls a callback in renderer.
ipcRenderer.on('ELECTRON_RENDERER_CALLBACK', function (event, id, args) {
callbacksRegistry.apply(id, metaToValue(args))
})

// // A callback in browser is released.
ipcRenderer.on('ELECTRON_RENDERER_RELEASE_CALLBACK', function (event, id) {
callbacksRegistry.remove(id)
})

var binding = {}

binding.require = function (module) {
Expand Down

0 comments on commit 237a6ee

Please sign in to comment.