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