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