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