mirror of https://github.com/electron/electron
90 lines
3.4 KiB
C++
90 lines
3.4 KiB
C++
// Copyright (c) 2025 Salesforce, Inc.
|
|
// Use of this source code is governed by the MIT license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#ifndef ELECTRON_SHELL_BROWSER_API_IPC_DISPATCHER_H_
|
|
#define ELECTRON_SHELL_BROWSER_API_IPC_DISPATCHER_H_
|
|
|
|
#include <string>
|
|
|
|
#include "base/trace_event/trace_event.h"
|
|
#include "base/values.h"
|
|
#include "gin/handle.h"
|
|
#include "shell/browser/api/message_port.h"
|
|
#include "shell/browser/javascript_environment.h"
|
|
#include "shell/common/api/api.mojom.h"
|
|
#include "shell/common/gin_converters/blink_converter.h"
|
|
#include "shell/common/gin_helper/dictionary.h"
|
|
#include "shell/common/gin_helper/event.h"
|
|
#include "shell/common/gin_helper/reply_channel.h"
|
|
#include "shell/common/v8_util.h"
|
|
|
|
namespace electron {
|
|
|
|
// Handles dispatching IPCs to JS.
|
|
// See ipc-dispatch.ts for JS listeners.
|
|
template <typename T>
|
|
class IpcDispatcher {
|
|
public:
|
|
void Message(gin::Handle<gin_helper::internal::Event>& event,
|
|
const std::string& channel,
|
|
blink::CloneableMessage args) {
|
|
TRACE_EVENT1("electron", "IpcDispatcher::Message", "channel", channel);
|
|
emitter()->EmitWithoutEvent("-ipc-message", event, channel, args);
|
|
}
|
|
|
|
void Invoke(gin::Handle<gin_helper::internal::Event>& event,
|
|
const std::string& channel,
|
|
blink::CloneableMessage arguments,
|
|
electron::mojom::ElectronApiIPC::InvokeCallback callback) {
|
|
TRACE_EVENT1("electron", "IpcHelper::Invoke", "channel", channel);
|
|
|
|
v8::Isolate* isolate = electron::JavascriptEnvironment::GetIsolate();
|
|
gin_helper::Dictionary dict(isolate, event.ToV8().As<v8::Object>());
|
|
dict.Set("_replyChannel", gin_helper::internal::ReplyChannel::Create(
|
|
isolate, std::move(callback)));
|
|
|
|
emitter()->EmitWithoutEvent("-ipc-invoke", event, channel,
|
|
std::move(arguments));
|
|
}
|
|
|
|
void ReceivePostMessage(gin::Handle<gin_helper::internal::Event>& event,
|
|
const std::string& channel,
|
|
blink::TransferableMessage message) {
|
|
v8::Isolate* isolate = JavascriptEnvironment::GetIsolate();
|
|
v8::HandleScope handle_scope(isolate);
|
|
auto wrapped_ports =
|
|
MessagePort::EntanglePorts(isolate, std::move(message.ports));
|
|
v8::Local<v8::Value> message_value =
|
|
electron::DeserializeV8Value(isolate, message);
|
|
emitter()->EmitWithoutEvent("-ipc-ports", event, channel, message_value,
|
|
std::move(wrapped_ports));
|
|
}
|
|
|
|
void MessageSync(
|
|
gin::Handle<gin_helper::internal::Event>& event,
|
|
const std::string& channel,
|
|
blink::CloneableMessage arguments,
|
|
electron::mojom::ElectronApiIPC::MessageSyncCallback callback) {
|
|
TRACE_EVENT1("electron", "IpcHelper::MessageSync", "channel", channel);
|
|
|
|
v8::Isolate* isolate = electron::JavascriptEnvironment::GetIsolate();
|
|
gin_helper::Dictionary dict(isolate, event.ToV8().As<v8::Object>());
|
|
dict.Set("_replyChannel", gin_helper::internal::ReplyChannel::Create(
|
|
isolate, std::move(callback)));
|
|
|
|
emitter()->EmitWithoutEvent("-ipc-message-sync", event, channel,
|
|
std::move(arguments));
|
|
}
|
|
|
|
private:
|
|
inline T* emitter() {
|
|
// T must inherit from gin_helper::EventEmitterMixin<T>
|
|
return static_cast<T*>(this);
|
|
}
|
|
};
|
|
|
|
} // namespace electron
|
|
|
|
#endif // ELECTRON_SHELL_BROWSER_API_IPC_DISPATCHER_H_
|