• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..16-Feb-2021-

lib/H16-Feb-2021-12,8059,125

tests/H16-Feb-2021-19,22614,301

BUILD.gnH A D16-Feb-20218.2 KiB298276

DEPSH A D16-Feb-2021119 54

README.mdH A D16-Feb-202156.1 KiB1,7731,366

array_data_view.hH A D16-Feb-20216.4 KiB246165

array_traits.hH A D16-Feb-20213.3 KiB8012

array_traits_span.hH A D16-Feb-20211.2 KiB4427

array_traits_stl.hH A D16-Feb-20215.3 KiB178116

array_traits_web_vector.hH A D16-Feb-20211.6 KiB5735

array_traits_wtf_vector.hH A D16-Feb-20211.7 KiB5939

associated_binding.hH A D16-Feb-20217.2 KiB18197

associated_binding_set.hH A D16-Feb-20211.2 KiB3118

associated_group.hH A D16-Feb-20211.8 KiB5223

associated_group_controller.hH A D16-Feb-20214.1 KiB9842

associated_interface_ptr.hH A D16-Feb-202110.6 KiB267137

associated_interface_ptr_info.hH A D16-Feb-20212.7 KiB8651

associated_interface_request.hH A D16-Feb-20212.9 KiB8845

associated_receiver.hH A D16-Feb-202112.8 KiB275119

associated_receiver_set.hH A D16-Feb-20211 KiB2918

associated_remote.hH A D16-Feb-202112.5 KiB283142

async_flusher.ccH A D16-Feb-2021652 2814

async_flusher.hH A D16-Feb-20212 KiB5524

binder_map.hH A D16-Feb-20214.8 KiB12664

binding.hH A D16-Feb-202111.2 KiB26995

binding_set.hH A D16-Feb-202111.4 KiB331226

callback_helpers.hH A D16-Feb-20214.8 KiB12560

clone_traits.hH A D16-Feb-20212.1 KiB8765

connection_error_callback.hH A D16-Feb-2021969 2512

connection_group.ccH A D16-Feb-20212.9 KiB10778

connection_group.hH A D16-Feb-20214.2 KiB11956

connector.hH A D16-Feb-202113 KiB342149

deprecated_interface_types_forward.hH A D16-Feb-20211.1 KiB3625

disconnect_reason.hH A D16-Feb-2021658 2614

enum_traits.hH A D16-Feb-20211.1 KiB3412

enum_utils.hH A D16-Feb-20212.9 KiB6720

equals_traits.hH A D16-Feb-20212.6 KiB9972

features.ccH A D16-Feb-20211.5 KiB349

features.hH A D16-Feb-2021644 2413

generic_pending_receiver.ccH A D16-Feb-20211.3 KiB4530

generic_pending_receiver.hH A D16-Feb-20212.7 KiB7944

interface_data_view.hH A D16-Feb-2021713 2613

interface_endpoint_client.hH A D16-Feb-202111 KiB303163

interface_endpoint_controller.hH A D16-Feb-20211.3 KiB3813

interface_id.hH A D16-Feb-20211.3 KiB4019

interface_ptr.hH A D16-Feb-20219.4 KiB246116

interface_ptr_info.hH A D16-Feb-20212.1 KiB6535

interface_ptr_set.hH A D16-Feb-20214 KiB149101

interface_request.hH A D16-Feb-20217.1 KiB19389

map_data_view.hH A D16-Feb-20211.9 KiB6445

map_traits.hH A D16-Feb-20212.4 KiB6512

map_traits_flat_map.hH A D16-Feb-20211.9 KiB5740

map_traits_stl.hH A D16-Feb-20213.7 KiB11682

map_traits_wtf_hash_map.hH A D16-Feb-20212.1 KiB6544

message.hH A D16-Feb-202117.2 KiB453227

message_dispatcher.hH A D16-Feb-20211.6 KiB5531

message_dumper.hH A D16-Feb-20211.2 KiB4429

message_header_validator.hH A D16-Feb-2021973 3318

native_enum.hH A D16-Feb-2021757 2914

pending_associated_receiver.hH A D16-Feb-20213.9 KiB10765

pending_associated_remote.hH A D16-Feb-20214.1 KiB11375

pending_flush.ccH A D16-Feb-2021859 3117

pending_flush.hH A D16-Feb-20213 KiB7421

pending_receiver.hH A D16-Feb-20215.9 KiB15377

pending_remote.hH A D16-Feb-20216.3 KiB16178

pipe_control_message_handler.hH A D16-Feb-20211.7 KiB5627

pipe_control_message_handler_delegate.hH A D16-Feb-20211.2 KiB3417

pipe_control_message_proxy.hH A D16-Feb-20211.7 KiB5029

raw_ptr_impl_ref_traits.hH A D16-Feb-2021719 2311

receiver.hH A D16-Feb-202113.7 KiB299120

receiver_set.hH A D16-Feb-202115 KiB404237

remote.hH A D16-Feb-202117.1 KiB392153

remote_set.hH A D16-Feb-20215.3 KiB165113

scoped_interface_endpoint_handle.hH A D16-Feb-20214.5 KiB12354

scoped_message_error_crash_key.ccH A D16-Feb-20211,007 3117

scoped_message_error_crash_key.hH A D16-Feb-20211.1 KiB3419

self_owned_associated_receiver.hH A D16-Feb-20211.1 KiB3321

self_owned_receiver.hH A D16-Feb-20211.1 KiB3321

sequence_local_sync_event_watcher.hH A D16-Feb-20212.7 KiB7027

service_factory.ccH A D16-Feb-20213 KiB8557

service_factory.hH A D16-Feb-20215.8 KiB17282

shared_associated_remote.hH A D16-Feb-20212.8 KiB6535

shared_remote.hH A D16-Feb-202112.5 KiB310184

string_data_view.hH A D16-Feb-2021932 3519

string_traits.hH A D16-Feb-20211.5 KiB4112

string_traits_stl.hH A D16-Feb-2021712 2715

string_traits_string_piece.hH A D16-Feb-20211.3 KiB4021

string_traits_wtf.hH A D16-Feb-20211,011 2917

strong_associated_binding.hH A D16-Feb-20215.3 KiB14188

strong_binding.hH A D16-Feb-20215.3 KiB14789

strong_binding_set.hH A D16-Feb-20211.2 KiB3214

struct_forward.hH A D16-Feb-2021509 199

struct_ptr.hH A D16-Feb-20218.4 KiB332230

struct_traits.hH A D16-Feb-20217 KiB17012

sync_call_restrictions.hH A D16-Feb-20214.6 KiB13469

sync_event_watcher.hH A D16-Feb-20212.4 KiB7531

sync_handle_registry.hH A D16-Feb-20213.5 KiB10255

sync_handle_watcher.hH A D16-Feb-20212.7 KiB7632

thread_safe_forwarder_base.ccH A D16-Feb-20217 KiB191130

thread_safe_forwarder_base.hH A D16-Feb-20215.9 KiB15487

thread_safe_interface_ptr.hH A D16-Feb-20218.8 KiB220136

type_converter.hH A D16-Feb-20213.4 KiB11730

union_traits.hH A D16-Feb-20211.7 KiB4612

unique_associated_receiver_set.hH A D16-Feb-20211.5 KiB3415

unique_ptr_impl_ref_traits.hH A D16-Feb-2021822 2311

unique_receiver_set.hH A D16-Feb-20211.3 KiB3213

README.md

1# Mojo C++ Bindings API
2This document is a subset of the [Mojo documentation](/mojo/README.md).
3
4[TOC]
5
6## Overview
7The Mojo C++ Bindings API leverages the
8[C++ System API](/mojo/public/cpp/system/README.md) to provide a more natural
9set of primitives for communicating over Mojo message pipes. Combined with
10generated code from the
11[Mojom IDL and bindings generator](/mojo/public/tools/bindings/README.md), users
12can easily connect interface clients and implementations across arbitrary intra-
13and inter-process boundaries.
14
15This document provides a detailed guide to bindings API usage with example code
16snippets. For a detailed API references please consult the headers in
17[//mojo/public/cpp/bindings](https://cs.chromium.org/chromium/src/mojo/public/cpp/bindings/README.md).
18
19For a simplified guide targeted at Chromium developers, see [this
20link](/docs/mojo_and_services.md).
21
22## Getting Started
23
24When a Mojom IDL file is processed by the bindings generator, C++ code is
25emitted in a series of `.h` and `.cc` files with names based on the input
26`.mojom` file. Suppose we create the following Mojom file at
27`//services/db/public/mojom/db.mojom`:
28
29```
30module db.mojom;
31
32interface Table {
33  AddRow(int32 key, string data);
34};
35
36interface Database {
37  CreateTable(Table& table);
38};
39```
40
41And a GN target to generate the bindings in
42`//services/db/public/mojom/BUILD.gn`:
43
44```
45import("//mojo/public/tools/bindings/mojom.gni")
46
47mojom("mojom") {
48  sources = [
49    "db.mojom",
50  ]
51}
52```
53
54Ensure that any target that needs this interface depends on it, e.g. with a line like:
55
56```
57   deps += [ '//services/db/public/mojom' ]
58```
59
60If we then build this target:
61
62```
63ninja -C out/r services/db/public/mojom
64```
65
66This will produce several generated source files, some of which are relevant to
67C++ bindings. Two of these files are:
68
69```
70out/gen/services/db/public/mojom/db.mojom.cc
71out/gen/services/db/public/mojom/db.mojom.h
72```
73
74You can include the above generated header in your sources in order to use the
75definitions therein:
76
77``` cpp
78#include "services/business/public/mojom/factory.mojom.h"
79
80class TableImpl : public db::mojom::Table {
81  // ...
82};
83```
84
85This document covers the different kinds of definitions generated by Mojom IDL
86for C++ consumers and how they can effectively be used to communicate across
87message pipes.
88
89*** note
90**NOTE:** Using C++ bindings from within Blink code is typically subject to
91special constraints which require the use of a different generated header.
92For details, see [Blink Type Mapping](#Blink-Type-Mapping).
93***
94
95## Interfaces
96
97Mojom IDL interfaces are translated to corresponding C++ (pure virtual) class
98interface definitions in the generated header, consisting of a single generated
99method signature for each request message on the interface. Internally there is
100also generated code for serialization and deserialization of messages, but this
101detail is hidden from bindings consumers.
102
103### Basic Usage
104
105Let's consider a new `//sample/logger.mojom` to define a simple logging
106interface which clients can use to log simple string messages:
107
108``` cpp
109module sample.mojom;
110
111interface Logger {
112  Log(string message);
113};
114```
115
116Running this through the bindings generator will produce a `logger.mojom.h`
117with the following definitions (modulo unimportant details):
118
119``` cpp
120namespace sample {
121namespace mojom {
122
123class Logger {
124  virtual ~Logger() {}
125
126  virtual void Log(const std::string& message) = 0;
127};
128
129}  // namespace mojom
130}  // namespace sample
131```
132
133### Remote and PendingReceiver
134
135In the world of Mojo bindings libraries these are effectively strongly-typed
136message pipe endpoints. If a `Remote<T>` is bound to a message pipe
137endpoint, it can be dereferenced to make calls on an opaque `T` interface. These
138calls immediately serialize their arguments (using generated code) and write a
139corresponding message to the pipe.
140
141A `PendingReceiver<T>` is essentially just a typed container to hold the other
142end of a `Remote<T>`'s pipe -- the receiving end -- until it can be
143routed to some implementation which will **bind** it. The `PendingReceiver<T>`
144doesn't actually *do* anything other than hold onto a pipe endpoint and carry
145useful compile-time type information.
146
147![Diagram illustrating Remote and PendingReceiver on either end of a message pipe](/docs/images/mojo_pipe.png)
148
149So how do we create a strongly-typed message pipe?
150
151### Creating Interface Pipes
152
153One way to do this is by manually creating a pipe and wrapping each end with a
154strongly-typed object:
155
156``` cpp
157#include "sample/logger.mojom.h"
158
159mojo::MessagePipe pipe;
160mojo::Remote<sample::mojom::Logger> logger(
161    mojo::PendingRemote<sample::mojom::Logger>(std::move(pipe.handle0), 0));
162mojo::PendingReceiver<sample::mojom::Logger> receiver(std::move(pipe.handle1));
163```
164
165That's pretty verbose, but the C++ Bindings library provides a more convenient
166way to accomplish the same thing. [remote.h](https://cs.chromium.org/chromium/src/mojo/public/cpp/bindings/remote.h)
167defines a `BindNewPipeAndPassReceiver` method:
168
169``` cpp
170mojo::Remote<sample::mojom::Logger> logger;
171auto receiver = logger.BindNewPipeAndPassReceiver();
172```
173
174This second snippet is equivalent to the first one.
175
176*** note
177**NOTE:** In the first example above you may notice usage of the
178`mojo::PendingRemote<Logger>`. This is similar to a `PendingReceiver<T>`
179in that it merely holds onto a pipe handle and cannot actually read or
180write messages on the pipe. Both this type and `PendingReceiver<T>` are safe
181to move freely from sequence to sequence, whereas a bound `Remote<T>` is bound
182to a single sequence.
183
184A `Remote<T>` may be unbound by calling its `Unbind()` method,
185which returns a new `PendingRemote<T>`. Conversely, an `Remote<T>` may
186bind (and thus take ownership of) an `PendingRemote<T>` so that interface
187calls can be made on the pipe.
188
189The sequence-bound nature of `Remote<T>` is necessary to support safe
190dispatch of its [message responses](#Receiving-Responses) and
191[connection error notifications](#Connection-Errors).
192***
193
194Once the `PendingRemote<Logger>` is bound we can immediately begin calling `Logger`
195interface methods on it, which will immediately write messages into the pipe.
196These messages will stay queued on the receiving end of the pipe until someone
197binds to it and starts reading them.
198
199``` cpp
200logger->Log("Hello!");
201```
202
203This actually writes a `Log` message to the pipe.
204
205![Diagram illustrating a message traveling on a pipe from Remote<Logger> to PendingReceiver<Logger>](/docs/images/mojo_message.png)
206
207But as mentioned above, `PendingReceiver` *doesn't actually do anything*, so
208that message will just sit on the pipe forever. We need a way to read messages
209off the other end of the pipe and dispatch them. We have to
210**bind the pending receiver**.
211
212### Binding a Pending Receiver
213
214There are many different helper classes in the bindings library for binding the
215receiving end of a message pipe. The most primitive among them is `mojo::Receiver<T>`.
216A `mojo::Receiver<T>` bridges an implementation of `T`
217with a single bound message pipe endpoint (via a `mojo::PendingReceiver<T>`),
218which it continuously watches for readability.
219
220Any time the bound pipe becomes readable, the `Receiver` will schedule a task to
221read, deserialize (using generated code), and dispatch all available messages to
222the bound `T` implementation. Below is a sample implementation of the `Logger`
223interface. Notice that the implementation itself owns a `mojo::Receiver`. This is
224a common pattern, since a bound implementation must outlive any `mojo::Receiver`
225which binds it.
226
227``` cpp
228#include "base/logging.h"
229#include "base/macros.h"
230#include "sample/logger.mojom.h"
231
232class LoggerImpl : public sample::mojom::Logger {
233 public:
234  // NOTE: A common pattern for interface implementations which have one
235  // instance per client is to take a PendingReceiver in the constructor.
236
237  explicit LoggerImpl(mojo::PendingReceiver<sample::mojom::Logger> receiver)
238      : receiver_(this, std::move(receiver)) {}
239  ~Logger() override {}
240  Logger(const Logger&) = delete;
241  Logger& operator=(const Logger&) = delete;
242
243  // sample::mojom::Logger:
244  void Log(const std::string& message) override {
245    LOG(ERROR) << "[Logger] " << message;
246  }
247
248 private:
249  mojo::Receiver<sample::mojom::Logger> receiver_;
250};
251```
252
253Now we can construct a `LoggerImpl` over our `PendingReceiver<Logger>`, and the
254previously queued `Log` message will be dispatched ASAP on the `LoggerImpl`'s
255sequence:
256
257``` cpp
258LoggerImpl impl(std::move(receiver));
259```
260
261The diagram below illustrates the following sequence of events, all set in
262motion by the above line of code:
263
2641. The `LoggerImpl` constructor is called, passing the `PendingReceiver<Logger>` along
265   to the `Receiver`.
2662. The `Receiver` takes ownership of the `PendingReceiver<Logger>`'s pipe endpoint and
267   begins watching it for readability. The pipe is readable immediately, so a
268   task is scheduled to read the pending `Log` message from the pipe ASAP.
2693. The `Log` message is read and deserialized, causing the `Receiver` to invoke
270   the `Logger::Log` implementation on its bound `LoggerImpl`.
271
272![Diagram illustrating the progression of binding a pending receiver, reading a pending message, and dispatching it](/docs/images/mojo_receiver_and_dispatch.png)
273
274As a result, our implementation will eventually log the client's `"Hello!"`
275message via `LOG(ERROR)`.
276
277*** note
278**NOTE:** Messages will only be read and dispatched from a pipe as long as the
279object which binds it (*i.e.* the `mojo::Receiver` in the above example) remains
280alive.
281***
282
283### Receiving Responses
284
285Some Mojom interface methods expect a response. Suppose we modify our `Logger`
286interface so that the last logged line can be queried like so:
287
288``` cpp
289module sample.mojom;
290
291interface Logger {
292  Log(string message);
293  GetTail() => (string message);
294};
295```
296
297The generated C++ interface will now look like:
298
299``` cpp
300namespace sample {
301namespace mojom {
302
303class Logger {
304 public:
305  virtual ~Logger() {}
306
307  virtual void Log(const std::string& message) = 0;
308
309  using GetTailCallback = base::OnceCallback<void(const std::string& message)>;
310
311  virtual void GetTail(GetTailCallback callback) = 0;
312}
313
314}  // namespace mojom
315}  // namespace sample
316```
317
318As before, both clients and implementations of this interface use the same
319signature for the `GetTail` method: implementations use the `callback` argument
320to *respond* to the request, while clients pass a `callback` argument to
321asynchronously `receive` the response. The parameter `GetTailCallback` passed to
322the implementation of `GetTail` is sequence-affine. It must be invoked on the
323same sequence that `GetTail` is called on. A client's `callback` runs on the
324same sequence on which they invoked `GetTail` (the sequence to which their
325`logger` is bound). Here's an updated implementation:
326
327```cpp
328class LoggerImpl : public sample::mojom::Logger {
329 public:
330  // NOTE: A common pattern for interface implementations which have one
331  // instance per client is to take a PendingReceiver in the constructor.
332
333  explicit LoggerImpl(mojo::PendingReceiver<sample::mojom::Logger> receiver)
334      : receiver_(this, std::move(receiver)) {}
335  ~Logger() override {}
336  Logger(const Logger&) = delete;
337  Logger& operator=(const Logger&) = delete;
338
339  // sample::mojom::Logger:
340  void Log(const std::string& message) override {
341    LOG(ERROR) << "[Logger] " << message;
342    lines_.push_back(message);
343  }
344
345  void GetTail(GetTailCallback callback) override {
346    std::move(callback).Run(lines_.back());
347  }
348
349 private:
350  mojo::Receiver<sample::mojom::Logger> receiver_;
351  std::vector<std::string> lines_;
352};
353```
354
355And an updated client call:
356
357``` cpp
358void OnGetTail(const std::string& message) {
359  LOG(ERROR) << "Tail was: " << message;
360}
361
362logger->GetTail(base::BindOnce(&OnGetTail));
363```
364
365Behind the scenes, the implementation-side callback is actually serializing the
366response arguments and writing them onto the pipe for delivery back to the
367client. Meanwhile the client-side callback is invoked by some internal logic
368which watches the pipe for an incoming response message, reads and deserializes
369it once it arrives, and then invokes the callback with the deserialized
370parameters.
371
372### Connection Errors
373
374If a pipe is disconnected, both endpoints will be able to observe the connection
375error (unless the disconnection is caused by closing/destroying an endpoint, in
376which case that endpoint won't get such a notification). If there are remaining
377incoming messages for an endpoint on disconnection, the connection error won't
378be triggered until the messages are drained.
379
380Pipe disconnection may be caused by:
381* Mojo system-level causes: process terminated, resource exhausted, etc.
382* The bindings close the pipe due to a validation error when processing a
383  received message.
384* The peer endpoint is closed. For example, the remote side is a bound
385  `mojo::Remote<T>` and it is destroyed.
386
387Regardless of the underlying cause, when a connection error is encountered on
388a receiver endpoint, that endpoint's **disconnect handler** (if set) is
389invoked. This handler is a simple `base::OnceClosure` and may only be invoked
390*once* as long as the endpoint is bound to the same pipe. Typically clients and
391implementations use this handler to do some kind of cleanup or -- particuarly if
392the error was unexpected -- create a new pipe and attempt to establish a new
393connection with it.
394
395All message pipe-binding C++ objects (*e.g.*, `mojo::Receiver<T>`,
396`mojo::Remote<T>`, *etc.*) support setting their disconnect handler
397via a `set_disconnect_handler` method.
398
399We can set up another end-to-end `Logger` example to demonstrate disconnect handler
400invocation. Suppose that `LoggerImpl` had set up the following disconnect
401handler within its constructor:
402
403``` cpp
404LoggerImpl::LoggerImpl(mojo::PendingReceiver<sample::mojom::Logger> receiver)
405    : receiver_(this, std::move(receiver)) {
406  receiver_.set_disconnect_handler(
407      base::BindOnce(&LoggerImpl::OnError, base::Unretained(this)));
408}
409
410void LoggerImpl::OnError() {
411  LOG(ERROR) << "Client disconnected! Purging log lines.";
412  lines_.clear();
413}
414
415mojo::Remote<sample::mojom::Logger> logger;
416LoggerImpl impl(logger.BindNewPipeAndPassReceiver());
417logger->Log("OK cool");
418logger.reset();  // Closes the client end.
419
420```
421
422As long as `impl` stays alive here, it will eventually receive the `Log` message
423followed immediately by an invocation of the bound callback which outputs
424`"Client disconnected! Purging log lines."`. Like all other receiver callbacks, a disconnect handler will
425**never** be invoked once its corresponding receiver object has been destroyed.
426
427The use of `base::Unretained` is *safe* because the error handler will never be
428invoked beyond the lifetime of `receiver_`, and `this` owns `receiver_`.
429
430### A Note About Endpoint Lifetime and Callbacks
431Once a `mojo::Remote<T>` is destroyed, it is guaranteed that pending
432callbacks as well as the connection error handler (if registered) won't be
433called.
434
435Once a `mojo::Receiver<T>` is destroyed, it is guaranteed that no more method
436calls are dispatched to the implementation and the connection error handler (if
437registered) won't be called.
438
439### Best practices for dealing with process crashes and callbacks
440A common situation when calling mojo interface methods that take a callback is
441that the caller wants to know if the other endpoint is torn down (e.g. because
442of a crash). In that case, the consumer usually wants to know if the response
443callback won't be run. There are different solutions for this problem, depending
444on how the `Remote<T>` is held:
4451. The consumer owns the `Remote<T>`: `set_disconnect_handler`
446   should be used.
4472. The consumer doesn't own the `Remote<T>`: there are two helpers
448   depending on the behavior that the caller wants. If the caller wants to
449   ensure that an error handler is run, then
450   [**`mojo::WrapCallbackWithDropHandler`**](https://cs.chromium.org/chromium/src/mojo/public/cpp/bindings/callback_helpers.h?l=46)
451   should be used. If the caller wants the callback to always be run, then
452   [**`mojo::WrapCallbackWithDefaultInvokeIfNotRun`**](https://cs.chromium.org/chromium/src/mojo/public/cpp/bindings/callback_helpers.h?l=40)
453   helper should be used. With both of these helpers, usual callback care should
454   be followed to ensure that the callbacks don't run after the consumer is
455   destructed (e.g. because the owner of the `Remote<T>` outlives the
456   consumer). This includes using
457   [**`base::WeakPtr`**](https://cs.chromium.org/chromium/src/base/memory/weak_ptr.h?l=5)
458   or
459   [**`base::RefCounted`**](https://cs.chromium.org/chromium/src/base/memory/ref_counted.h?l=246).
460   It should also be noted that with these helpers, the callbacks could be run
461   synchronously while the Remote<T> is reset or destroyed.
462
463### A Note About Ordering
464
465As mentioned in the previous section, closing one end of a pipe will eventually
466trigger a connection error on the other end. However it's important to note that
467this event is itself ordered with respect to any other event (*e.g.* writing a
468message) on the pipe.
469
470This means that it's safe to write something contrived like:
471
472``` cpp
473LoggerImpl::LoggerImpl(mojo::PendingReceiver<sample::mojom::Logger> receiver,
474      base::OnceClosure disconnect_handler)
475    : receiver_(this, std::move(receiver)) {
476  receiver_.set_disconnect_handler(std::move(disconnect_handler));
477}
478
479void GoBindALogger(mojo::PendingReceiver<sample::mojom::Logger> receiver) {
480  base::RunLoop loop;
481  LoggerImpl impl(std::move(receiver), loop.QuitClosure());
482  loop.Run();
483}
484
485void LogSomething() {
486  mojo::Remote<sample::mojom::Logger> logger;
487  bg_thread->task_runner()->PostTask(
488      FROM_HERE, base::BindOnce(&GoBindALogger, logger.BindNewPipeAndPassReceiver()));
489  logger->Log("OK Computer");
490}
491```
492
493When `logger` goes out of scope it immediately closes its end of the message
494pipe, but the impl-side won't notice this until it receives the sent `Log`
495message. Thus the `impl` above will first log our message and *then* see a
496connection error and break out of the run loop.
497
498## Types
499
500### Enums
501
502[Mojom enums](/mojo/public/tools/bindings/README.md#Enumeration-Types) translate
503directly to equivalent strongly-typed C++11 enum classes with `int32_t` as the
504underlying type. The typename and value names are identical between Mojom and
505C++. Mojo also always defines a special enumerator `kMaxValue` that shares the
506value of the highest enumerator: this makes it easy to record Mojo enums in
507histograms and interoperate with legacy IPC.
508
509For example, consider the following Mojom definition:
510
511```cpp
512module business.mojom;
513
514enum Department {
515  kEngineering,
516  kMarketing,
517  kSales,
518};
519```
520
521This translates to the following C++ definition:
522
523```cpp
524namespace business {
525namespace mojom {
526
527enum class Department : int32_t {
528  kEngineering,
529  kMarketing,
530  kSales,
531  kMaxValue = kSales,
532};
533
534}  // namespace mojom
535}  // namespace business
536```
537
538### Structs
539
540[Mojom structs](mojo/public/tools/bindings/README.md#Structs) can be used to
541define logical groupings of fields into a new composite type. Every Mojom struct
542elicits the generation of an identically named, representative C++ class, with
543identically named public fields of corresponding C++ types, and several helpful
544public methods.
545
546For example, consider the following Mojom struct:
547
548```cpp
549module business.mojom;
550
551struct Employee {
552  int64 id;
553  string username;
554  Department department;
555};
556```
557
558This would generate a C++ class like so:
559
560```cpp
561namespace business {
562namespace mojom {
563
564class Employee;
565
566using EmployeePtr = mojo::StructPtr<Employee>;
567
568class Employee {
569 public:
570  // Default constructor - applies default values, potentially ones specified
571  // explicitly within the Mojom.
572  Employee();
573
574  // Value constructor - an explicit argument for every field in the struct, in
575  // lexical Mojom definition order.
576  Employee(int64_t id, const std::string& username, Department department);
577
578  // Creates a new copy of this struct value
579  EmployeePtr Clone();
580
581  // Tests for equality with another struct value of the same type.
582  bool Equals(const Employee& other);
583
584  // Equivalent public fields with names identical to the Mojom.
585  int64_t id;
586  std::string username;
587  Department department;
588};
589
590}  // namespace mojom
591}  // namespace business
592```
593
594Note when used as a message parameter or as a field within another Mojom struct,
595a `struct` type is wrapped by the move-only `mojo::StructPtr` helper, which is
596roughly equivalent to a `std::unique_ptr` with some additional utility methods.
597This allows struct values to be nullable and struct types to be potentially
598self-referential.
599
600Every generated struct class has a static `New()` method which returns a new
601`mojo::StructPtr<T>` wrapping a new instance of the class constructed by
602forwarding the arguments from `New`. For example:
603
604```cpp
605mojom::EmployeePtr e1 = mojom::Employee::New();
606e1->id = 42;
607e1->username = "mojo";
608e1->department = mojom::Department::kEngineering;
609```
610
611is equivalent to
612
613```cpp
614auto e1 = mojom::Employee::New(42, "mojo", mojom::Department::kEngineering);
615```
616
617Now if we define an interface like:
618
619```cpp
620interface EmployeeManager {
621  AddEmployee(Employee e);
622};
623```
624
625We'll get this C++ interface to implement:
626
627```cpp
628class EmployeeManager {
629 public:
630  virtual ~EmployeManager() {}
631
632  virtual void AddEmployee(EmployeePtr e) = 0;
633};
634```
635
636And we can send this message from C++ code as follows:
637
638```cpp
639mojom::EmployeManagerPtr manager = ...;
640manager->AddEmployee(
641    Employee::New(42, "mojo", mojom::Department::kEngineering));
642
643// or
644auto e = Employee::New(42, "mojo", mojom::Department::kEngineering);
645manager->AddEmployee(std::move(e));
646```
647
648### Unions
649
650Similarly to [structs](#Structs), tagged unions generate an identically named,
651representative C++ class which is typically wrapped in a `mojo::StructPtr<T>`.
652
653Unlike structs, all generated union fields are private and must be retrieved and
654manipulated using accessors. A field `foo` is accessible by `get_foo()` and
655settable by `set_foo()`. There is also a boolean `is_foo()` for each field which
656indicates whether the union is currently taking on the value of field `foo` in
657exclusion to all other union fields.
658
659Finally, every generated union class also has a nested `Tag` enum class which
660enumerates all of the named union fields. A Mojom union value's current type can
661be determined by calling the `which()` method which returns a `Tag`.
662
663For example, consider the following Mojom definitions:
664
665```cpp
666union Value {
667  int64 int_value;
668  float float_value;
669  string string_value;
670};
671
672interface Dictionary {
673  AddValue(string key, Value value);
674};
675```
676
677This generates the following C++ interface:
678
679```cpp
680class Value {
681 public:
682  ~Value() {}
683};
684
685class Dictionary {
686 public:
687  virtual ~Dictionary() {}
688
689  virtual void AddValue(const std::string& key, ValuePtr value) = 0;
690};
691```
692
693And we can use it like so:
694
695```cpp
696ValuePtr value = Value::New();
697value->set_int_value(42);
698CHECK(value->is_int_value());
699CHECK_EQ(value->which(), Value::Tag::INT_VALUE);
700
701value->set_float_value(42);
702CHECK(value->is_float_value());
703CHECK_EQ(value->which(), Value::Tag::FLOAT_VALUE);
704
705value->set_string_value("bananas");
706CHECK(value->is_string_value());
707CHECK_EQ(value->which(), Value::Tag::STRING_VALUE);
708```
709
710Finally, note that if a union value is not currently occupied by a given field,
711attempts to access that field will DCHECK:
712
713```cpp
714ValuePtr value = Value::New();
715value->set_int_value(42);
716LOG(INFO) << "Value is " << value->string_value();  // DCHECK!
717```
718
719### Sending Interfaces Over Interfaces
720
721We know how to create interface pipes and use their Remote and PendingReceiver endpoints
722in some interesting ways. This still doesn't add up to interesting IPC! The
723bread and butter of Mojo IPC is the ability to transfer interface endpoints
724across other interfaces, so let's take a look at how to accomplish that.
725
726#### Sending Pending Receivers
727
728Consider a new example Mojom in `//sample/db.mojom`:
729
730``` cpp
731module db.mojom;
732
733interface Table {
734  void AddRow(int32 key, string data);
735};
736
737interface Database {
738  AddTable(pending_receiver<Table> table);
739};
740```
741
742As noted in the
743[Mojom IDL documentation](/mojo/public/tools/bindings/README.md#Primitive-Types),
744the `pending_receiver<Table>` syntax corresponds
745precisely to the `PendingReceiver<T>` type discussed in the sections above, and
746in fact the generated code for these interfaces is approximately:
747
748``` cpp
749namespace db {
750namespace mojom {
751
752class Table {
753 public:
754  virtual ~Table() {}
755
756  virtual void AddRow(int32_t key, const std::string& data) = 0;
757}
758
759class Database {
760 public:
761  virtual ~Database() {}
762
763  virtual void AddTable(mojo::PendingReceiver<Table> table);
764};
765
766}  // namespace mojom
767}  // namespace db
768```
769
770We can put this all together now with an implementation of `Table` and
771`Database`:
772
773``` cpp
774#include "sample/db.mojom.h"
775
776class TableImpl : public db::mojom:Table {
777 public:
778  explicit TableImpl(mojo::PendingReceiver<db::mojom::Table> receiver)
779      : receiver_(this, std::move(receiver)) {}
780  ~TableImpl() override {}
781
782  // db::mojom::Table:
783  void AddRow(int32_t key, const std::string& data) override {
784    rows_.insert({key, data});
785  }
786
787 private:
788  mojo::Receiver<db::mojom::Table> receiver_;
789  std::map<int32_t, std::string> rows_;
790};
791
792class DatabaseImpl : public db::mojom::Database {
793 public:
794  explicit DatabaseImpl(mojo::PendingReceiver<db::mojom::Database> receiver)
795      : receiver_(this, std::move(receiver)) {}
796  ~DatabaseImpl() override {}
797
798  // db::mojom::Database:
799  void AddTable(mojo::PendingReceiver<db::mojom::Table> table) {
800    tables_.emplace_back(std::make_unique<TableImpl>(std::move(table)));
801  }
802
803 private:
804  mojo::Receiver<db::mojom::Database> receiver_;
805  std::vector<std::unique_ptr<TableImpl>> tables_;
806};
807```
808
809Pretty straightforward. The `pending_receiver<Table>` Mojom parameter to `AddTable` translates to
810a C++ `mojo::PendingReceiver<db::mojom::Table>`, which we know is just a
811strongly-typed message pipe handle. When `DatabaseImpl` gets an `AddTable` call,
812it constructs a new `TableImpl` and binds it to the received `mojo::PendingReceiver<db::mojom::Table>`.
813
814Let's see how this can be used.
815
816``` cpp
817mojo::Remote<db::mojom::Database> database;
818DatabaseImpl db_impl(database.BindNewPipeAndPassReceiver());
819
820mojo::Remote<db::mojom::Table> table1, table2;
821database->AddTable(table1.BindNewPipeAndPassReceiver());
822database->AddTable(table2.BindNewPipeAndPassReceiver());
823
824table1->AddRow(1, "hiiiiiiii");
825table2->AddRow(2, "heyyyyyy");
826```
827
828Notice that we can again start using the new `Table` pipes immediately, even
829while their `mojo::PendingReceiver<db::mojom::Table>` endpoints are still in transit.
830
831#### Sending Remotes
832
833Of course we can also send `Remote`s:
834
835``` cpp
836interface TableListener {
837  OnRowAdded(int32 key, string data);
838};
839
840interface Table {
841  AddRow(int32 key, string data);
842
843  AddListener(pending_remote<TableListener> listener);
844};
845```
846
847This would generate a `Table::AddListener` signature like so:
848
849``` cpp
850  virtual void AddListener(mojo::PendingRemote<TableListener> listener) = 0;
851```
852
853and this could be used like so:
854
855``` cpp
856mojo::PendingRemote<db::mojom::TableListener> listener;
857TableListenerImpl impl(listener.InitWithNewPipeAndPassReceiver());
858table->AddListener(std::move(listener));
859```
860
861## Other Interface Binding Types
862
863The [Interfaces](#Interfaces) section above covers basic usage of the most
864common bindings object types: `Remote`, `PendingReceiver`, and `Receiver`.
865While these types are probably the most commonly used in practice, there are
866several other ways of binding both client- and implementation-side interface
867pipes.
868
869### Self-owned Receivers
870
871A **self-owned receiver** exists as a standalone object which owns its interface
872implementation and automatically cleans itself up when its bound interface
873endpoint detects an error. The
874[**`MakeSelfOwnedReceiver`**](https://cs.chromium.org/chromium/src/mojo/public/cpp/bindings/self_owned_receiver.h)
875function is used to create such a receiver.
876.
877
878``` cpp
879class LoggerImpl : public sample::mojom::Logger {
880 public:
881  LoggerImpl() {}
882  ~LoggerImpl() override {}
883
884  // sample::mojom::Logger:
885  void Log(const std::string& message) override {
886    LOG(ERROR) << "[Logger] " << message;
887  }
888
889 private:
890  // NOTE: This doesn't own any Receiver object!
891};
892
893mojo::Remote<db::mojom::Logger> logger;
894mojo::MakeSelfOwnedReceiver(std::make_unique<LoggerImpl>(),
895                        logger.BindNewPipeAndPassReceiver());
896
897logger->Log("NOM NOM NOM MESSAGES");
898```
899
900Now as long as `logger` remains open somewhere in the system, the bound
901`LoggerImpl` on the other end will remain alive.
902
903### Receiver Sets
904
905Sometimes it's useful to share a single implementation instance with multiple
906clients. [**`ReceiverSet`**](https://cs.chromium.org/chromium/src/mojo/public/cpp/bindings/receiver_set.h)
907makes this easy. Consider the Mojom:
908
909``` cpp
910module system.mojom;
911
912interface Logger {
913  Log(string message);
914};
915
916interface LoggerProvider {
917  GetLogger(Logger& logger);
918};
919```
920
921We can use `ReceiverSet` to bind multiple `Logger` pending receivers to a single
922implementation instance:
923
924``` cpp
925class LogManager : public system::mojom::LoggerProvider,
926                   public system::mojom::Logger {
927 public:
928  explicit LogManager(mojo::PendingReceiver<system::mojom::LoggerProvider> receiver)
929      : provider_receiver_(this, std::move(receiver)) {}
930  ~LogManager() {}
931
932  // system::mojom::LoggerProvider:
933  void GetLogger(mojo::PendingReceiver<Logger> receiver) override {
934    logger_receivers_.Add(this, std::move(receiver));
935  }
936
937  // system::mojom::Logger:
938  void Log(const std::string& message) override {
939    LOG(ERROR) << "[Logger] " << message;
940  }
941
942 private:
943  mojo::Receiver<system::mojom::LoggerProvider> provider_receiver_;
944  mojo::ReceiverSet<system::mojom::Logger> logger_receivers_;
945};
946
947```
948
949
950### Remote Sets
951
952Similar to the `ReceiverSet` above, sometimes it's useful to maintain a set of
953`Remote`s for *e.g.* a set of clients observing some event.
954[**`RemoteSet`**](https://cs.chromium.org/chromium/src/mojo/public/cpp/bindings/remote_set.h)
955is here to help. Take the Mojom:
956
957``` cpp
958module db.mojom;
959
960interface TableListener {
961  OnRowAdded(int32 key, string data);
962};
963
964interface Table {
965  AddRow(int32 key, string data);
966  AddListener(pending_remote<TableListener> listener);
967};
968```
969
970An implementation of `Table` might look something like like this:
971
972``` cpp
973class TableImpl : public db::mojom::Table {
974 public:
975  TableImpl() {}
976  ~TableImpl() override {}
977
978  // db::mojom::Table:
979  void AddRow(int32_t key, const std::string& data) override {
980    rows_.insert({key, data});
981    listeners_.ForEach([key, &data](db::mojom::TableListener* listener) {
982      listener->OnRowAdded(key, data);
983    });
984  }
985
986  void AddListener(mojo::PendingRemote<db::mojom::TableListener> listener) {
987    listeners_.Add(std::move(listener));
988  }
989
990 private:
991  mojo::RemoteSet<db::mojom::Table> listeners_;
992  std::map<int32_t, std::string> rows_;
993};
994```
995
996## Associated Interfaces
997
998Associated interfaces are interfaces which:
999
1000* enable running multiple interfaces over a single message pipe while
1001  preserving message ordering.
1002* make it possible for the receiver to access a single message pipe from
1003  multiple sequences.
1004
1005### Mojom
1006
1007New types `pending_associated_remote` and `pending_associated_receiver` are
1008introduced for remote/receiver fields. For example:
1009
1010``` cpp
1011interface Bar {};
1012
1013struct Qux {
1014  pending_associated_remote<Bar> bar;
1015};
1016
1017interface Foo {
1018  // Uses associated remote.
1019  PassBarRemote(pending_associated_remote<Bar> bar);
1020  // Uses associated receiver.
1021  PassBarReceiver(pending_associated_receiver<Bar> bar);
1022  // Passes a struct with associated interface pointer.
1023  PassQux(Qux qux);
1024  // Uses associated interface pointer in callback.
1025  AsyncGetBar() => (pending_associated_remote<Bar> bar);
1026};
1027```
1028
1029In each case the interface impl/client will communicate using the same message
1030pipe over which the associated remote/receiver is passed.
1031
1032### Using associated interfaces in C++
1033
1034When generating C++ bindings, the pending_associated_remote of `Bar` is
1035mapped to `mojo::PendingAssociatedRemote<Bar>`; pending_associated_receiver to
1036`mojo::PendingAssociatedReceiver<Bar>`.
1037
1038``` cpp
1039// In mojom:
1040interface Foo {
1041  ...
1042  PassBarRemote(pending_associated_remote<Bar> bar);
1043  PassBarReceiver(pending_associated_receiver<Bar> bar);
1044  ...
1045};
1046
1047// In C++:
1048class Foo {
1049  ...
1050  virtual void PassBarRemote(mojo::PendingAssociatedRemote<Bar> bar) = 0;
1051  virtual void PassBarReceiver(mojo::PendingAssociatedReceiver<Bar> bar) = 0;
1052  ...
1053};
1054```
1055
1056#### Passing pending associated receivers
1057
1058Assume you already have a `Remote<Foo> foo`, and you would like to call
1059`PassBarReceiver()` on it. You can do:
1060
1061``` cpp
1062mojo::PendingAssociatedRemote<Bar> pending_bar;
1063mojo::PendingAssociatedReceiver<Bar> bar_receiver = pending_bar.InitWithNewEndpointAndPassReceiver();
1064foo->PassBarReceiver(std::move(bar_receiver));
1065
1066mojo::AssociatedRemote<Bar> bar;
1067bar.Bind(std::move(pending_bar));
1068bar->DoSomething();
1069```
1070
1071First, the code creates an associated interface of type `Bar`. It looks very
1072similar to what you would do to setup a non-associated interface. An
1073important difference is that one of the two associated endpoints (either
1074`bar_receiver` or `pending_bar`) must be sent over another interface. That is
1075how the interface is associated with an existing message pipe.
1076
1077It should be noted that you cannot call `bar->DoSomething()` before passing
1078`bar_receiver`. This is required by the FIFO-ness guarantee: at the receiver
1079side, when the message of `DoSomething` call arrives, we want to dispatch it to
1080the corresponding `AssociatedReceiver<Bar>` before processing any subsequent
1081messages. If `bar_receiver` is in a subsequent message, message dispatching gets
1082into a deadlock. On the other hand, as soon as `bar_receiver` is sent, `bar`
1083is usable. There is no need to wait until `bar_receiver` is bound to an
1084implementation at the remote side.
1085
1086`AssociatedRemote` provides a `BindNewEndpointAndPassReceiver` method
1087to make the code a little shorter. The following code achieves the same purpose:
1088
1089``` cpp
1090mojo::AssociatedRemote<Bar> bar;
1091foo->PassBarReceiver(bar.BindNewEndpointAndPassReceiver());
1092bar->DoSomething();
1093```
1094
1095The implementation of `Foo` looks like this:
1096
1097``` cpp
1098class FooImpl : public Foo {
1099  ...
1100  void PassBarReceiver(mojo::AssociatedReceiver<Bar> bar) override {
1101    bar_receiver_.Bind(std::move(bar));
1102    ...
1103  }
1104  ...
1105
1106  Receiver<Foo> foo_receiver_;
1107  AssociatedReceiver<Bar> bar_receiver_;
1108};
1109```
1110
1111In this example, `bar_receiver_`'s lifespan is tied to that of `FooImpl`. But you
1112don't have to do that. You can, for example, pass `bar2` to another sequence to
1113bind to an `AssociatedReceiver<Bar>` there.
1114
1115When the underlying message pipe is disconnected (e.g., `foo` or
1116`foo_receiver_` is destroyed), all associated interface endpoints (e.g.,
1117`bar` and `bar_receiver_`) will receive a disconnect error.
1118
1119#### Passing associated remotes
1120
1121Similarly, assume you have already got an `Remote<Foo> foo`, and you
1122would like to call `PassBarRemote()` on it. You can do:
1123
1124``` cpp
1125mojo::AssociatedReceiver<Bar> bar_receiver(some_bar_impl);
1126mojo::PendingAssociatedRemote<Bar> bar;
1127mojo::PendingAssociatedReceiver<Bar> bar_pending_receiver = bar.InitWithNewEndpointAndPassReceiver();
1128foo->PassBarRemote(std::move(bar));
1129bar_receiver.Bind(std::move(bar_pending_receiver));
1130```
1131
1132The following code achieves the same purpose:
1133
1134``` cpp
1135mojo::AssociatedReceiver<Bar> bar_receiver(some_bar_impl);
1136mojo::PendingAssociatedRemote<Bar> bar;
1137bar_receiver.Bind(bar.InitWithNewPipeAndPassReceiver());
1138foo->PassBarRemote(std::move(bar));
1139```
1140
1141### Performance considerations
1142
1143When using associated interfaces on different sequences than the primary
1144sequence (where the primary interface lives):
1145
1146* Sending messages: send happens directly on the calling sequence. So there
1147  isn't sequence hopping.
1148* Receiving messages: associated interfaces bound on a different sequence from
1149  the primary interface incur an extra sequence hop during dispatch.
1150
1151Therefore, performance-wise associated interfaces are better suited for
1152scenarios where message receiving happens on the primary sequence.
1153
1154### Testing
1155
1156Associated interfaces need to be associated with a primary interface before
1157they can be used. This means one end of the associated interface must be sent
1158over one end of the primary interface, or over one end of another associated
1159interface which itself already has a primary interface.
1160
1161If you want to test an associated interface endpoint without first
1162associating it, you can use `AssociatedRemote::BindNewEndpointAndPassDedicatedReceiver`.
1163This will create working associated interface endpoints which are not actually
1164associated with anything else.
1165
1166### Read more
1167
1168* [Design: Mojo Associated Interfaces](https://docs.google.com/document/d/1nq3J_HbS-gvVfIoEhcVyxm1uY-9G_7lhD-4Kyxb1WIY/edit)
1169
1170## Synchronous Calls
1171
1172### Think carefully before you decide to use sync calls
1173
1174Although sync calls are convenient, you should avoid them whenever they
1175are not absolutely necessary:
1176
1177* Sync calls hurt parallelism and therefore hurt performance.
1178* Re-entrancy changes message order and produces call stacks that you
1179probably never think about while you are coding. It has always been a
1180huge pain.
1181* Sync calls may lead to deadlocks.
1182
1183### Mojom changes
1184
1185A new attribute `[Sync]` (or `[Sync=true]`) is introduced for methods.
1186For example:
1187
1188``` cpp
1189interface Foo {
1190  [Sync]
1191  SomeSyncCall() => (Bar result);
1192};
1193```
1194
1195It indicates that when `SomeSyncCall()` is called, the control flow of
1196the calling thread is blocked until the response is received.
1197
1198It is not allowed to use this attribute with functions that don’t have
1199responses. If you just need to wait until the service side finishes
1200processing the call, you can use an empty response parameter list:
1201
1202``` cpp
1203[Sync]
1204SomeSyncCallWithNoResult() => ();
1205```
1206
1207### Generated bindings (C++)
1208
1209The generated C++ interface of the Foo interface above is:
1210
1211``` cpp
1212class Foo {
1213 public:
1214  // The service side implements this signature. The client side can
1215  // also use this signature if it wants to call the method asynchronously.
1216  virtual void SomeSyncCall(SomeSyncCallCallback callback) = 0;
1217
1218  // The client side uses this signature to call the method synchronously.
1219  virtual bool SomeSyncCall(BarPtr* result);
1220};
1221```
1222
1223As you can see, the client side and the service side use different
1224signatures. At the client side, response is mapped to output parameters
1225and the boolean return value indicates whether the operation is
1226successful. (Returning false usually means a connection error has
1227occurred.)
1228
1229At the service side, a signature with callback is used. The reason is
1230that in some cases the implementation may need to do some asynchronous
1231work which the sync method’s result depends on.
1232
1233*** note
1234**NOTE:** you can also use the signature with callback at the client side to
1235call the method asynchronously.
1236***
1237
1238### Re-entrancy
1239
1240What happens on the calling thread while waiting for the response of a
1241sync method call? It continues to process incoming sync request messages
1242(i.e., sync method calls); block other messages, including async
1243messages and sync response messages that don’t match the ongoing sync
1244call.
1245
1246![Diagram illustrating sync call flow](/docs/images/mojo_sync_call_flow.png)
1247
1248Please note that sync response messages that don’t match the ongoing
1249sync call cannot re-enter. That is because they correspond to sync calls
1250down in the call stack. Therefore, they need to be queued and processed
1251while the stack unwinds.
1252
1253### Avoid deadlocks
1254
1255Please note that the re-entrancy behavior doesn’t prevent deadlocks
1256involving async calls. You need to avoid call sequences such as:
1257
1258![Diagram illustrating a sync call deadlock](/docs/images/mojo_sync_call_deadlock.png)
1259
1260### Read more
1261
1262* [Design Proposal: Mojo Sync Methods](
1263https://docs.google.com/document/d/1dixzFzZQW8e3ldjdM8Adbo8klXDDE4pVekwo5aLgUsE)
1264
1265## Type Mapping
1266
1267In many instances you might prefer that your generated C++ bindings use a more
1268natural type to represent certain Mojom types in your interface methods. For one
1269example consider a Mojom struct such as the `Rect` below:
1270
1271``` cpp
1272module gfx.mojom;
1273
1274struct Rect {
1275  int32 x;
1276  int32 y;
1277  int32 width;
1278  int32 height;
1279};
1280
1281interface Canvas {
1282  void FillRect(Rect rect);
1283};
1284```
1285
1286The `Canvas` Mojom interface would normally generate a C++ interface like:
1287
1288``` cpp
1289class Canvas {
1290 public:
1291  virtual void FillRect(RectPtr rect) = 0;
1292};
1293```
1294
1295However, the Chromium tree already defines a native
1296[`gfx::Rect`](https://cs.chromium.org/chromium/src/ui/gfx/geometry/rect.h) which
1297is equivalent in meaning but which also has useful helper methods. Instead of
1298manually converting between a `gfx::Rect` and the Mojom-generated `RectPtr` at
1299every message boundary, wouldn't it be nice if the Mojom bindings generator
1300could instead generate:
1301
1302``` cpp
1303class Canvas {
1304 public:
1305  virtual void FillRect(const gfx::Rect& rect) = 0;
1306}
1307```
1308
1309The correct answer is, "Yes! That would be nice!" And fortunately, it can!
1310
1311### Defining `StructTraits`
1312
1313In order to teach generated bindings code how to serialize an arbitrary native
1314type `T` as an arbitrary Mojom type `mojom::U`, we need to define an appropriate
1315specialization of the
1316[`mojo::StructTraits`](https://cs.chromium.org/chromium/src/mojo/public/cpp/bindings/struct_traits.h)
1317template.
1318
1319A valid specialization of `StructTraits` MUST define the following static
1320methods:
1321
1322* A single static accessor for every field of the Mojom struct, with the exact
1323  same name as the struct field. These accessors must all take a (preferably
1324  const) ref to an object of the native type, and must return a value compatible
1325  with the Mojom struct field's type. This is used to safely and consistently
1326  extract data from the native type during message serialization without
1327  incurring extra copying costs.
1328
1329* A single static `Read` method which initializes an instance of the the native
1330  type given a serialized representation of the Mojom struct. The `Read` method
1331  must return a `bool` to indicate whether the incoming data is accepted
1332  (`true`) or rejected (`false`).
1333
1334In order to define the mapping for `gfx::Rect`, we want the following
1335`StructTraits` specialization, which we'll define in
1336`//ui/gfx/geometry/mojo/geometry_mojom_traits.h`:
1337
1338``` cpp
1339#include "mojo/public/cpp/bindings/mojom_traits.h"
1340#include "ui/gfx/geometry/rect.h"
1341#include "ui/gfx/geometry/mojo/geometry.mojom.h"
1342
1343namespace mojo {
1344
1345template <>
1346class StructTraits<gfx::mojom::RectDataView, gfx::Rect> {
1347 public:
1348  static int32_t x(const gfx::Rect& r) { return r.x(); }
1349  static int32_t y(const gfx::Rect& r) { return r.y(); }
1350  static int32_t width(const gfx::Rect& r) { return r.width(); }
1351  static int32_t height(const gfx::Rect& r) { return r.height(); }
1352
1353  static bool Read(gfx::mojom::RectDataView data, gfx::Rect* out_rect);
1354};
1355
1356}  // namespace mojo
1357```
1358
1359And in `//ui/gfx/geometry/mojo/geometry_mojom_traits.cc`:
1360
1361``` cpp
1362#include "ui/gfx/geometry/mojo/geometry_mojom_traits.h"
1363
1364namespace mojo {
1365
1366// static
1367bool StructTraits<gfx::mojom::RectDataView, gfx::Rect>::Read(
1368    gfx::mojom::RectDataView data,
1369  gfx::Rect* out_rect) {
1370  if (data.width() < 0 || data.height() < 0)
1371    return false;
1372
1373  out_rect->SetRect(data.x(), data.y(), data.width(), data.height());
1374  return true;
1375};
1376
1377}  // namespace mojo
1378```
1379
1380Note that the `Read()` method returns `false` if either the incoming `width` or
1381`height` fields are negative. This acts as a validation step during
1382deserialization: if a client sends a `gfx::Rect` with a negative width or
1383height, its message will be rejected and the pipe will be closed. In this way,
1384type mapping can serve to enable custom validation logic in addition to making
1385callsites and interface implemention more convenient.
1386
1387When the struct fields have non-primitive types, e.g. string or array,
1388returning a read-only view of the data in the accessor is recommended to
1389avoid copying. It is safe because the input object is guaranteed to
1390outlive the usage of the result returned by the accessor method.
1391
1392The following example uses `StringPiece` to return a view of the GURL's
1393data (`//url/mojom/url_gurl_mojom_traits.h`):
1394
1395``` cpp
1396#include "base/strings/string_piece.h"
1397#include "url/gurl.h"
1398#include "url/mojom/url.mojom.h"
1399#include "url/url_constants.h"
1400
1401namespace mojo {
1402
1403template <>
1404struct StructTraits<url::mojom::UrlDataView, GURL> {
1405  static base::StringPiece url(const GURL& r) {
1406    if (r.possibly_invalid_spec().length() > url::kMaxURLChars ||
1407        !r.is_valid()) {
1408      return base::StringPiece();
1409    }
1410    return base::StringPiece(r.possibly_invalid_spec().c_str(),
1411                             r.possibly_invalid_spec().length());
1412  }
1413}  // namespace mojo
1414```
1415
1416### Enabling a New Type Mapping
1417
1418We've defined the `StructTraits` necessary, but we still need to teach the
1419bindings generator (and hence the build system) about the mapping. To do this we
1420must add some more information to our `mojom` target in GN:
1421
1422```
1423# Without a typemap
1424mojom("mojom") {
1425  sources = [
1426    "rect.mojom",
1427  ]
1428}
1429
1430# With a typemap.
1431mojom("mojom") {
1432  sources = [
1433    "rect.mojom",
1434  ]
1435
1436  cpp_typemaps = [
1437    {
1438      # NOTE: A single typemap entry can list multiple individual type mappings.
1439      # Each mapping assumes the same values for |traits_headers| etc below.
1440      #
1441      # To typemap a type with separate |traits_headers| etc, add a separate
1442      # entry to |cpp_typemaps|.
1443      types = [
1444        {
1445          mojom = "gfx.mojom.Rect"
1446          cpp = "::gfx::Rect"
1447        },
1448      ]
1449      traits_headers = [ "//ui/gfx/geometry/mojo/geometry_mojom_traits.h" ]
1450      traits_sources = [ "//ui/gfx/geometry/mojo/geometry_mojom_traits.cc" ]
1451      traits_public_deps = [ "//ui/gfx/geometry" ]
1452    },
1453  ]
1454}
1455```
1456
1457See typemap documentation in
1458[mojom.gni](https://cs.chromium.org/chromium/src/mojo/public/tools/bindings/mojom.gni)
1459for details on the above definition and other supported parameters.
1460
1461With this extra configuration present, any mojom references to `gfx.mojom.Rect`
1462(e.g. for method parameters or struct fields) will be `gfx::Rect` references in
1463generated C++ code.
1464
1465For the Blink variant of bindings, add to the `blink_cpp_typemaps` list instead.
1466
1467### Type Mapping Without `traits_sources`
1468
1469Using `traits_sources` in a typemap configuration means that the listed sources
1470will be baked directly into the corresponding `mojom` target's own sources. This
1471can be problematic if you want to use the same typemap for both Blink and
1472non-Blink bindings.
1473
1474For such cases, it is recommended that you define a separate `component` target
1475for your typemap traits, and reference this in the `traits_public_deps` of the
1476typemap:
1477
1478```
1479mojom("mojom") {
1480  sources = [
1481    "rect.mojom",
1482  ]
1483
1484  cpp_typemaps = [
1485    {
1486      types = [
1487        {
1488          mojom = "gfx.mojom.Rect"
1489          cpp = "::gfx::Rect"
1490        },
1491      ]
1492      traits_headers = [ "//ui/gfx/geometry/mojo/geometry_mojom_traits.h" ]
1493      traits_public_deps = [ ":geometry_mojom_traits" ]
1494    },
1495  ]
1496}
1497
1498component("geometry_mojom_traits") {
1499  sources = [
1500    "//ui/gfx/geometry/mojo/geometry_mojom_traits.cc",
1501    "//ui/gfx/geometry/mojo/geometry_mojom_traits.h",
1502  ]
1503
1504  # The header of course needs corresponding COMPONENT_EXPORT() tags.
1505  defines = [ "IS_GEOMETRY_MOJOM_TRAITS_IMPL" ]
1506}
1507```
1508
1509### StructTraits Reference
1510
1511Each of a `StructTraits` specialization's static getter methods -- one per
1512struct field -- must return a type which can be used as a data source for the
1513field during serialization. This is a quick reference mapping Mojom field type
1514to valid getter return types:
1515
1516| Mojom Field Type             | C++ Getter Return Type |
1517|------------------------------|------------------------|
1518| `bool`                       | `bool`
1519| `int8`                       | `int8_t`
1520| `uint8`                      | `uint8_t`
1521| `int16`                      | `int16_t`
1522| `uint16`                     | `uint16_t`
1523| `int32`                      | `int32_t`
1524| `uint32`                     | `uint32_t`
1525| `int64`                      | `int64_t`
1526| `uint64`                     | `uint64_t`
1527| `float`                      | `float`
1528| `double`                     | `double`
1529| `handle`                     | `mojo::ScopedHandle`
1530| `handle<message_pipe>`       | `mojo::ScopedMessagePipeHandle`
1531| `handle<data_pipe_consumer>` | `mojo::ScopedDataPipeConsumerHandle`
1532| `handle<data_pipe_producer>` | `mojo::ScopedDataPipeProducerHandle`
1533| `handle<shared_buffer>`      | `mojo::ScopedSharedBufferHandle`
1534| `pending_remote<Foo>`        | `mojo::PendingRemote<Foo>`
1535| `pending_receiver<Foo>`      | `mojo::PendingReceiver<Foo>`
1536| `pending_associated_remote<Foo>`    | `mojo::PendingAssociatedRemote<Foo>`
1537| `pending_associated_receiver<Foo>`    | `mojo::PendingAssociatedReceiver<Foo>`
1538| `string`                     | Value or reference to any type `T` that has a `mojo::StringTraits` specialization defined. By default this includes `std::string`, `base::StringPiece`, and `WTF::String` (Blink).
1539| `array<T>`                   | Value or reference to any type `T` that has a `mojo::ArrayTraits` specialization defined. By default this includes `std::vector<T>`, `mojo::CArray<T>`, and `WTF::Vector<T>` (Blink).
1540| `map<K, V>`                  | Value or reference to any type `T` that has a `mojo::MapTraits` specialization defined. By default this includes `std::map<T>`, `mojo::unordered_map<T>`, and `WTF::HashMap<T>` (Blink).
1541| `FooEnum`                    | Value of any type that has an appropriate `EnumTraits` specialization defined. By default this inlcudes only the generated `FooEnum` type.
1542| `FooStruct`                  | Value or reference to any type that has an appropriate `StructTraits` specialization defined. By default this includes only the generated `FooStructPtr` type.
1543| `FooUnion`                   | Value of reference to any type that has an appropriate `UnionTraits` specialization defined. By default this includes only the generated `FooUnionPtr` type.
1544| `Foo?`                       | `base::Optional<CppType>`, where `CppType` is the value type defined by the appropriate traits class specialization (e.g. `StructTraits`, `mojo::MapTraits`, etc.). This may be customized by the [typemapping](#Enabling-a-New-Type-Mapping).
1545
1546### Using Generated DataView Types
1547
1548Static `Read` methods on `StructTraits` specializations get a generated
1549`FooDataView` argument (such as the `RectDataView` in the example above) which
1550exposes a direct view of the serialized Mojom structure within an incoming
1551message's contents. In order to make this as easy to work with as possible, the
1552generated `FooDataView` types have a generated method corresponding to every
1553struct field:
1554
1555* For POD field types (*e.g.* bools, floats, integers) these are simple accessor
1556  methods with names identical to the field name. Hence in the `Rect` example we
1557  can access things like `data.x()` and `data.width()`. The return types
1558  correspond exactly to the mappings listed in the table above, under
1559  [StructTraits Reference](#StructTraits-Reference).
1560
1561* For handle and interface types (*e.g* `handle` or `pending_remote<Foo>`) these
1562  are named `TakeFieldName` (for a field named `field_name`) and they return an
1563  appropriate move-only handle type by value. The return types correspond
1564  exactly to the mappings listed in the table above, under
1565  [StructTraits Reference](#StructTraits-Reference).
1566
1567* For all other field types (*e.g.*, enums, strings, arrays, maps, structs)
1568  these are named `ReadFieldName` (for a field named `field_name`) and they
1569  return a `bool` (to indicate success or failure in reading). On success they
1570  fill their output argument with the deserialized field value. The output
1571  argument may be a pointer to any type with an appropriate `StructTraits`
1572  specialization defined, as mentioned in the table above, under
1573  [StructTraits Reference](#StructTraits-Reference).
1574
1575An example would be useful here. Suppose we introduced a new Mojom struct:
1576
1577``` cpp
1578struct RectPair {
1579  Rect left;
1580  Rect right;
1581};
1582```
1583
1584and a corresponding C++ type:
1585
1586``` cpp
1587class RectPair {
1588 public:
1589  RectPair() {}
1590
1591  const gfx::Rect& left() const { return left_; }
1592  const gfx::Rect& right() const { return right_; }
1593
1594  void Set(const gfx::Rect& left, const gfx::Rect& right) {
1595    left_ = left;
1596    right_ = right;
1597  }
1598
1599  // ... some other stuff
1600
1601 private:
1602  gfx::Rect left_;
1603  gfx::Rect right_;
1604};
1605```
1606
1607Our traits to map `gfx::mojom::RectPair` to `gfx::RectPair` might look like
1608this:
1609
1610``` cpp
1611namespace mojo {
1612
1613template <>
1614class StructTraits
1615 public:
1616  static const gfx::Rect& left(const gfx::RectPair& pair) {
1617    return pair.left();
1618  }
1619
1620  static const gfx::Rect& right(const gfx::RectPair& pair) {
1621    return pair.right();
1622  }
1623
1624  static bool Read(gfx::mojom::RectPairDataView data, gfx::RectPair* out_pair) {
1625    gfx::Rect left, right;
1626    if (!data.ReadLeft(&left) || !data.ReadRight(&right))
1627      return false;
1628    out_pair->Set(left, right);
1629    return true;
1630  }
1631}  // namespace mojo
1632```
1633
1634Generated `ReadFoo` methods always convert `multi_word_field_name` fields to
1635`ReadMultiWordFieldName` methods.
1636
1637<a name="Blink-Type-Mapping"></a>
1638### Variants
1639
1640By now you may have noticed that additional C++ sources are generated when a
1641Mojom is processed. These exist due to type mapping, and the source files we
1642refer to throughout this docuemnt (namely `foo.mojom.cc` and `foo.mojom.h`) are
1643really only one **variant** (the *default* or *chromium* variant) of the C++
1644bindings for a given Mojom file.
1645
1646The only other variant currently defined in the tree is the *blink* variant,
1647which produces a few additional files:
1648
1649```
1650out/gen/sample/db.mojom-blink.cc
1651out/gen/sample/db.mojom-blink.h
1652```
1653
1654These files mirror the definitions in the default variant but with different
1655C++ types in place of certain builtin field and parameter types. For example,
1656Mojom strings are represented by `WTF::String` instead of `std::string`. To
1657avoid symbol collisions, the variant's symbols are nested in an extra inner
1658namespace, so Blink consumer of the interface might write something like:
1659
1660```
1661#include "sample/db.mojom-blink.h"
1662
1663class TableImpl : public db::mojom::blink::Table {
1664 public:
1665  void AddRow(int32_t key, const WTF::String& data) override {
1666    // ...
1667  }
1668};
1669```
1670
1671In addition to using different C++ types for builtin strings, arrays, and maps,
1672the custom typemaps applied to Blink bindings are managed separately from
1673regular bindings.
1674
1675`mojom` targets support a `blink_cpp_typemaps` parameter in addition to the
1676regular `cpp_typemaps`. This lists the typemaps to apply to Blink bindings.
1677
1678To depend specifically on generated Blink bindings, reference
1679`${target_name}_blink`. So for example, with the definition:
1680
1681```
1682# In //foo/mojom
1683mojom("mojom") {
1684  sources = [
1685    "db.mojom",
1686  ]
1687}
1688```
1689
1690C++ sources can depend on the Blink bindings by depending on
1691`"//foo/mojom:mojom_blink"`.
1692
1693Finally note that both bindings variants share some common definitions which are
1694unaffected by differences in the type-mapping configuration (like enums, and
1695structures describing serialized object formats). These definitions are
1696generated in *shared* sources:
1697
1698```
1699out/gen/sample/db.mojom-shared.cc
1700out/gen/sample/db.mojom-shared.h
1701out/gen/sample/db.mojom-shared-internal.h
1702```
1703
1704Including either variant's header (`db.mojom.h` or `db.mojom-blink.h`)
1705implicitly includes the shared header, but may wish to include *only* the shared
1706header in some instances.
1707
1708C++ sources can depend on shared sources only, by referencing the
1709`"${target_name}_shared"` target, e.g. `"//foo/mojom:mojom_shared"` in the
1710example above.
1711
1712## Versioning Considerations
1713
1714For general documentation of versioning in the Mojom IDL see
1715[Versioning](/mojo/public/tools/bindings/README.md#Versioning).
1716
1717This section briefly discusses some C++-specific considerations relevant to
1718versioned Mojom types.
1719
1720### Querying Interface Versions
1721
1722`Remote` defines the following methods to query or assert remote interface
1723version:
1724
1725```cpp
1726void QueryVersion(base::OnceCallback<void(uint32_t)> callback);
1727```
1728
1729This queries the remote endpoint for the version number of its binding. When a
1730response is received `callback` is invoked with the remote version number. Note
1731that this value is cached by the `Remote` instance to avoid redundant
1732queries.
1733
1734```cpp
1735void RequireVersion(uint32_t version);
1736```
1737
1738Informs the remote endpoint that a minimum version of `version` is required by
1739the client. If the remote endpoint cannot support that version, it will close
1740its end of the pipe immediately, preventing any other requests from being
1741received.
1742
1743### Versioned Enums
1744
1745For convenience, every extensible enum has a generated helper function to
1746determine whether a received enum value is known by the implementation's current
1747version of the enum definition. For example:
1748
1749```cpp
1750[Extensible]
1751enum Department {
1752  SALES,
1753  DEV,
1754  RESEARCH,
1755};
1756```
1757
1758generates the function in the same namespace as the generated C++ enum type:
1759
1760```cpp
1761inline bool IsKnownEnumValue(Department value);
1762```
1763
1764### Using Mojo Bindings in Chrome
1765
1766See [Converting Legacy Chrome IPC To Mojo](/docs/mojo_ipc_conversion.md).
1767
1768### Additional Documentation
1769
1770[Calling Mojo From Blink](/docs/mojo_ipc_conversion.md#Blink_Specific-Advice):
1771A brief overview of what it looks like to use Mojom C++ bindings from
1772within Blink code.
1773