【chromium】chromium IPC:mojo、mojom 实例;form:Intro to Mojo & Services

文章目录

过程

来自:Intro to Mojo & Services

  • 实现:将消息从render 发送到browser 进程的RenderFrameHostImpl 实例处,这个实例和render frame 相关联。
  1. 定义接口。
  • 创建一个 mojom
    • Ping() 返回值会对应到C++中的回调方法 :返回值对应回调方法的 参数。
// src/example/public/mojom/ping_responder.mojom
module example.mojom;

interface PingResponder {
  // Receives a "Ping" and responds with a random integer.
  Ping() => (int32 random);
};
  • 加上相应构建规则,以实现对上述定义的 C++绑定
# src/example/public/mojom/BUILD.gn
import("//mojo/public/tools/bindings/mojom.gni")
mojom("mojom") {
  sources = [ "ping_responder.mojom" ]
}
  1. 添加一个pipe 、Remote
  • 添加一个 message pipe 以使用这个接口。
    • 通常 Remote 端 为创建管道一方,因为其通常先发送消息。
  • 将下面代码放在renderer 中
    • 创建一个RemotePendingReceiver ,后者只是为了编译期强类型,表明端点希望被Receiver 端同接口类型 绑定。
// src/third_party/blink/example/public/ping_responder.h
mojo::Remote<example::mojom::PingResponder> ping_responder;
mojo::PendingReceiver<example::mojom::PingResponder> receiver =   ping_responder.BindNewPipeAndPassReceiver();
  • 这里的Remote 通过BindNewPipeAndPassReceiver 实现了创建pipe、绑定端口。
    • Remote 可以在构造的时候传入PendingRemote 以实现绑定, 或者后续使用 Bind 绑定PendingRemote 。(PendingRemote 包含了message pipe 的端点)
  1. Remote端通过调用Ping 来发送消息。
  • 实现回调、发送消息。
    • 回调通过 mojom接口 -> 底层通道 -> mojom 接口实例 -> browser 侧。
// src/third_party/blink/example/public/ping_responder.h

void OnPong(int32_t num) {} 
ping_responder->Ping(base::BindOnce(&OnPong));
  1. PendingReceiver 发送到 browser 进程。
  • 可以使用 invitation 传递,原文采用了BrowserInterfaceBroker 传递。
  1. 在 browser 侧实现 PingResponder 接口 的实现。
  • 其中Receiver 作为私有成员,在构造时传入了 this 和PendingReceiver (PendingReceiver 存储了message pipe 的另一个端点)。
// render_frame_host_impl.h
#include "example/public/mojom/ping_responder.mojom.h"

class PingResponderImpl : example::mojom::PingResponder {
 public:
  explicit PingResponderImpl(mojo::PendingReceiver<example::mojom::PingResponder> receiver)
      : receiver_(this, std::move(receiver)) {}
  PingResponderImpl(const PingResponderImpl&) = delete;
  PingResponderImpl& operator=(const PingResponderImpl&) = delete;

  // example::mojom::PingResponder:
  void Ping(PingCallback callback) override {
    // Respond with a random 4, chosen by fair dice roll.
    std::move(callback).Run(4);
  }

 private:
  mojo::Receiver<example::mojom::PingResponder> receiver_;
};
  • browser 侧实现
// render_frame_host_impl.h
class RenderFrameHostImpl
  ...
  void GetPingResponder(mojo::PendingReceiver<example::mojom::PingResponder> receiver);
  ...
 private:
  ...
  std::unique_ptr<PingResponderImpl> ping_responder_;
  ...
};

// render_frame_host_impl.cc
void RenderFrameHostImpl::GetPingResponder(
    mojo::PendingReceiver<example::mojom::PingResponder> receiver) {
  ping_responder_ = std::make_unique<PingResponderImpl>(std::move(receiver));
}

// browser_interface_binders.cc
void PopulateFrameBinders(RenderFrameHostImpl* host,
                          mojo::BinderMap* map) {
...
  // Register the handler for PingResponder.
  map->Add<example::mojom::PingResponder>(base::BindRepeating(
    &RenderFrameHostImpl::GetPingResponder, base::Unretained(host)));
}
  • 只要 ping_responder 对象在render 端存在的够久,OnPong 回调会被正确调用。

理解

  • 过程: (A、B 进程需要通信)
    • A进程:创建mojom 文件、修改构建规则 BUILD.gn、创建message pipe、创建Remote(绑定message pipe 的一个端点)、将另一个端点发送给进程B。
      • 随后A进程就可以使用 mojom 接口的方法, 用于传递消息。最终B进程实现的实例中的方法会被调用。
    • B进程:实现mojom 接口的实例类 并创建其对象、根据传递来的message pipe 端点和 实例对象 创建Receiver 。即形成了通路。
    • render 端的 Remote 通过 mojom 接口 发送消息。
      • mojo::Remote<example::mojom::PingResponder> ping_responder; 将其绑定到message pipe 的一端,再调用PingResponder接口即可。
    • browser端 对mojom 接口实现类: PingResponderImpl,其实例和message pipe端点一起绑定到Receiver上。
    • mojo::Receiver<example::mojom::PingResponder> receiver_; 将其绑定到底层message pipe的另一个 端点上。
    • 消息最终传递到实现类对应的方法中。

在这里插入图片描述
图来自:Chromium-Mojo&IPC

  • 需要保证 RemoteReceiver 的生命周期,否则消息无法传递或收取。

参考

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值