[chromium] chromium IPC: mojo and mojom instances; form: Intro to Mojo & Services

process

come from: Intro to Mojo & Services

  • Implementation: send the message from render to the RenderFrameHostImpl instance of the browser process, which is associated with render frame.
  1. Define the interface.
  • Create a mojom
    • The return value of Ping() corresponds to the callback method in C + +: the return value corresponds to the parameters of the callback method.
// src/example/public/mojom/ping_responder.mojom
module example.mojom;

interface PingResponder {
  // Receives a "Ping" and responds with a random integer.
  Ping() => (int32 random);
};
  • Add the corresponding construction rules to realize the C + + binding defined above
# src/example/public/mojom/BUILD.gn
import("//mojo/public/tools/bindings/mojom.gni")
mojom("mojom") {
  sources = [ "ping_responder.mojom" ]
}
  1. Add a pipe
  • Add a message pipe to use this interface.
    • Usually, the Remote side is the party that creates the pipeline, because it usually sends messages first.
  • Put the following code in renderer
    • Create a Remote and PendingReceiver. The latter is only for strong typing at compile time, indicating that the endpoint wants to be bound with the interface type by the Receiver end.
// 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();
  1. The Remote end sends messages by calling Ping.
  • Implement callback and send message.
    • Callback through mojom interface - > underlying channel - > mojom interface instance - > browser side.
// src/third_party/blink/example/public/ping_responder.h

void OnPong(int32_t num) {} 
ping_responder->Ping(base::BindOnce(&OnPong));
  1. Send PendingReceiver to the browser process.
  • You can use invitation transmission. The original text adopts browser interface broker transmission.
  1. Implement the PingResponder interface on the browser side.
  • As a private member, the Receiver passes in this and PendingReceiver during construction (PendingReceiver stores another endpoint of 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 side implementation
// 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)));
}
  • Just Ping_ If the responder object exists on the render side long enough, the OnPong callback will be called correctly.

understand

  • Process: (A and B processes need communication)
    • Process A: create mojom file and modify build rule build GN, create message pipe, create Remote (bind one endpoint of message pipe), and send another endpoint to process B.
      • Then A process can use the method of mojom interface to deliver messages. Finally, the method in the instance implemented by the B process will be called.
    • B process: implement the instance class of mojom interface and create its object, and create a Receiver according to the message pipe endpoint and instance object passed. That is, a pathway is formed.
    • The Remote on the render side sends messages through the mojom interface.
      • mojo::Remote<example::mojom::PingResponder> ping_ responder; Bind it to one end of the message pipe, and then call the pingresponder interface.
    • The browser side to mojom interface implementation class: PingResponderImpl, whose instance is bound to the Receiver together with the message pipe endpoint.
    • mojo::Receiver<example::mojom::PingResponder> receiver_; Bind it to another endpoint of the underlying message pipe.
    • The message is finally passed to the method corresponding to the implementation class.


Figure from: Chromium-Mojo&IPC

  • The life cycle of Remote and Receiver needs to be guaranteed, otherwise the message cannot be delivered or received.

reference resources

Keywords: ipc Chromium

Added by LeZeNkO on Wed, 02 Mar 2022 12:59:34 +0200