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.
- 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" ] }
- 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();
- 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));
- Send PendingReceiver to the browser process.
- You can use invitation transmission. The original text adopts browser interface broker transmission.
- 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.
- 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.
-
- 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 Remote on the render side sends messages through the mojom 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.