Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(135)

Side by Side Diff: docs/mojo_in_chromium.md

Issue 1410053006: Move third_party/mojo/src/mojo/public to mojo/public (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: merge Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 # Mojo in Chromium 1 # Mojo in Chromium
2 2
3 **THIS DOCUIMENT IS A WORK IN PROGRESS.** As long as this notice exists, you 3 **THIS DOCUIMENT IS A WORK IN PROGRESS.** As long as this notice exists, you
4 should probably ignore everything below it. 4 should probably ignore everything below it.
5 5
6 This document is intended to serve as a Mojo primer for Chromium developers. No 6 This document is intended to serve as a Mojo primer for Chromium developers. No
7 prior knowledge of Mojo is assumed, but you should have a decent grasp of C++ 7 prior knowledge of Mojo is assumed, but you should have a decent grasp of C++
8 and be familiar with Chromium's multi-process architecture as well as common 8 and be familiar with Chromium's multi-process architecture as well as common
9 concepts used throughout Chromium such as smart pointers, message loops, 9 concepts used throughout Chromium such as smart pointers, message loops,
10 callback binding, and so on. 10 callback binding, and so on.
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
86 A message pipe is a lightweight primitive for reliable, bidirectional, queued 86 A message pipe is a lightweight primitive for reliable, bidirectional, queued
87 transfer of relatively small packets of data. Every pipe endpoint is identified 87 transfer of relatively small packets of data. Every pipe endpoint is identified
88 by a **handle** -- a unique process-wide integer identifying the endpoint to the 88 by a **handle** -- a unique process-wide integer identifying the endpoint to the
89 EDK. 89 EDK.
90 90
91 A single message across a pipe consists of a binary payload and an array of zero 91 A single message across a pipe consists of a binary payload and an array of zero
92 or more handles to be transferred. A pipe's endpoints may live in the same 92 or more handles to be transferred. A pipe's endpoints may live in the same
93 process or in two different processes. 93 process or in two different processes.
94 94
95 Pipes are easy to create. The `mojo::MessagePipe` type (see 95 Pipes are easy to create. The `mojo::MessagePipe` type (see
96 `/third_party/mojo/src/mojo/public/cpp/system/message_pipe.h`) provides a nice 96 `/mojo/public/cpp/system/message_pipe.h`) provides a nice
97 class wrapper with each endpoint represented as a scoped handle type (see 97 class wrapper with each endpoint represented as a scoped handle type (see
98 members `handle0` and `handle1` and the definition of 98 members `handle0` and `handle1` and the definition of
99 `mojo::ScopedMessagePipeHandle`). In the same header you can find 99 `mojo::ScopedMessagePipeHandle`). In the same header you can find
100 `WriteMessageRaw` and `ReadMessageRaw` definitions. These are in theory all one 100 `WriteMessageRaw` and `ReadMessageRaw` definitions. These are in theory all one
101 needs to begin pushing things from one endpoint to the other. 101 needs to begin pushing things from one endpoint to the other.
102 102
103 While it's worth being aware of `mojo::MessagePipe` and the associated raw I/O 103 While it's worth being aware of `mojo::MessagePipe` and the associated raw I/O
104 functions, you will rarely if ever have a use for them. Instead you'll typically 104 functions, you will rarely if ever have a use for them. Instead you'll typically
105 use bindings code generated from mojom interface definitions, along with the 105 use bindings code generated from mojom interface definitions, along with the
106 public bindings API which mostly hides the underlying pipes. 106 public bindings API which mostly hides the underlying pipes.
(...skipping 29 matching lines...) Expand all
136 Before we see an example implementation and usage of the Frobinator, there are a 136 Before we see an example implementation and usage of the Frobinator, there are a
137 handful of interesting bits in the public C++ bindings API you should be 137 handful of interesting bits in the public C++ bindings API you should be
138 familiar with. These complement generated bindings code and generally obviate 138 familiar with. These complement generated bindings code and generally obviate
139 any need to use a `mojo::MessagePipe` directly. 139 any need to use a `mojo::MessagePipe` directly.
140 140
141 In all of the cases below, `T` is the type of a generated bindings class 141 In all of the cases below, `T` is the type of a generated bindings class
142 interface, such as the `frob::Frobinator` discussed above. 142 interface, such as the `frob::Frobinator` discussed above.
143 143
144 #### `mojo::InterfacePtr<T>` 144 #### `mojo::InterfacePtr<T>`
145 145
146 Defined in `/third_party/mojo/src/mojo/public/cpp/bindings/interface_ptr.h`. 146 Defined in `/mojo/public/cpp/bindings/interface_ptr.h`.
147 147
148 `mojo::InterfacePtr<T>` is a typed proxy for a service of type `T`, which can be 148 `mojo::InterfacePtr<T>` is a typed proxy for a service of type `T`, which can be
149 bound to a message pipe endpoint. This class implements every interface method 149 bound to a message pipe endpoint. This class implements every interface method
150 on `T` by serializing a message (encoding the method call and its arguments) and 150 on `T` by serializing a message (encoding the method call and its arguments) and
151 writing it to the pipe (if bound.) This is the standard way for C++ code to talk 151 writing it to the pipe (if bound.) This is the standard way for C++ code to talk
152 to any Mojo service. 152 to any Mojo service.
153 153
154 For illustrative purposes only, we can create a message pipe and bind an 154 For illustrative purposes only, we can create a message pipe and bind an
155 `InterfacePtr` to one end as follows: 155 `InterfacePtr` to one end as follows:
156 156
157 ``` 157 ```
158 mojo::MessagePipe pipe; 158 mojo::MessagePipe pipe;
159 mojo::InterfacePtr<frob::Frobinator> frobinator; 159 mojo::InterfacePtr<frob::Frobinator> frobinator;
160 frobinator.Bind( 160 frobinator.Bind(
161 mojo::InterfacePtrInfo<frob::Frobinator>(pipe.handle0.Pass(), 0u)); 161 mojo::InterfacePtrInfo<frob::Frobinator>(pipe.handle0.Pass(), 0u));
162 ``` 162 ```
163 163
164 You could then call `frobinator->Frobinate()` and read the encoded `Frobinate` 164 You could then call `frobinator->Frobinate()` and read the encoded `Frobinate`
165 message from the other side of the pipe (`handle1`.) You most likely don't want 165 message from the other side of the pipe (`handle1`.) You most likely don't want
166 to do this though, because as you'll soon see there's a nicer way to establish 166 to do this though, because as you'll soon see there's a nicer way to establish
167 service pipes. 167 service pipes.
168 168
169 #### `mojo::InterfaceRequest<T>` 169 #### `mojo::InterfaceRequest<T>`
170 170
171 Defined in `/third_party/mojo/src/mojo/public/cpp/bindings/interface_request.h`. 171 Defined in `/mojo/public/cpp/bindings/interface_request.h`.
172 172
173 `mojo::InterfaceRequest<T>` is a typed container for a message pipe endpoint 173 `mojo::InterfaceRequest<T>` is a typed container for a message pipe endpoint
174 that should _eventually_ be bound to a service implementation. An 174 that should _eventually_ be bound to a service implementation. An
175 `InterfaceRequest` doesn't actually _do_ anything, it's just a way of holding 175 `InterfaceRequest` doesn't actually _do_ anything, it's just a way of holding
176 onto an endpoint without losing interface type information. 176 onto an endpoint without losing interface type information.
177 177
178 A common usage pattern is to create a pipe, bind one end to an 178 A common usage pattern is to create a pipe, bind one end to an
179 `InterfacePtr<T>`, and pass the other end off to someone else (say, over some 179 `InterfacePtr<T>`, and pass the other end off to someone else (say, over some
180 other message pipe) who is expected to eventually bind it to a concrete service 180 other message pipe) who is expected to eventually bind it to a concrete service
181 implementation. `InterfaceRequest<T>` is here for that purpose and is, as we'll 181 implementation. `InterfaceRequest<T>` is here for that purpose and is, as we'll
(...skipping 14 matching lines...) Expand all
196 ``` 196 ```
197 197
198 At this point we could start making calls to `frobinator->Frobinate()` as 198 At this point we could start making calls to `frobinator->Frobinate()` as
199 before, but they'll just sit in queue waiting for the request side to be bound. 199 before, but they'll just sit in queue waiting for the request side to be bound.
200 Note that the basic logic in the snippet above is such a common pattern that 200 Note that the basic logic in the snippet above is such a common pattern that
201 there's a convenient API function which does it for us. 201 there's a convenient API function which does it for us.
202 202
203 #### `mojo::GetProxy<T>` 203 #### `mojo::GetProxy<T>`
204 204
205 Defined in 205 Defined in
206 `/third_party/mojo/src/mojo/public/cpp/bindings/interface`_request.h`. 206 `/mojo/public/cpp/bindings/interface`_request.h`.
207 207
208 `mojo::GetProxy<T>` is the function you will most commonly use to create a new 208 `mojo::GetProxy<T>` is the function you will most commonly use to create a new
209 message pipe. Its signature is as follows: 209 message pipe. Its signature is as follows:
210 210
211 ``` 211 ```
212 template <typename T> 212 template <typename T>
213 mojo::InterfaceRequest<T> GetProxy(mojo::InterfacePtr<T>* ptr); 213 mojo::InterfaceRequest<T> GetProxy(mojo::InterfacePtr<T>* ptr);
214 ``` 214 ```
215 215
216 This function creates a new message pipe, binds one end to the given 216 This function creates a new message pipe, binds one end to the given
217 `InterfacePtr` argument, and binds the other end to a new `InterfaceRequest` 217 `InterfacePtr` argument, and binds the other end to a new `InterfaceRequest`
218 which it then returns. Equivalent to the sample code just above is the following 218 which it then returns. Equivalent to the sample code just above is the following
219 snippet: 219 snippet:
220 220
221 ``` 221 ```
222 mojo::InterfacePtr<frob::Frobinator> frobinator; 222 mojo::InterfacePtr<frob::Frobinator> frobinator;
223 mojo::InterfaceRequest<frob::Frobinator> frobinator_request = 223 mojo::InterfaceRequest<frob::Frobinator> frobinator_request =
224 mojo::GetProxy(&frobinator); 224 mojo::GetProxy(&frobinator);
225 ``` 225 ```
226 226
227 #### `mojo::Binding<T>` 227 #### `mojo::Binding<T>`
228 228
229 Defined in `/third_party/mojo/src/mojo/public/cpp/bindings/binding.h`. 229 Defined in `/mojo/public/cpp/bindings/binding.h`.
230 230
231 Binds one end of a message pipe to an implementation of service `T`. A message 231 Binds one end of a message pipe to an implementation of service `T`. A message
232 sent from the other end of the pipe will be read and, if successfully decoded as 232 sent from the other end of the pipe will be read and, if successfully decoded as
233 a `T` message, will invoke the corresponding call on the bound `T` 233 a `T` message, will invoke the corresponding call on the bound `T`
234 implementation. A `Binding<T>` must be constructed over an instance of `T` 234 implementation. A `Binding<T>` must be constructed over an instance of `T`
235 (which itself usually owns said `Binding` object), and its bound pipe is usually 235 (which itself usually owns said `Binding` object), and its bound pipe is usually
236 taken from a passed `InterfaceRequest<T>`. 236 taken from a passed `InterfaceRequest<T>`.
237 237
238 A common usage pattern looks something like this: 238 A common usage pattern looks something like this:
239 239
240 ``` 240 ```
241 #include "components/frob/public/interfaces/frobinator.mojom.h" 241 #include "components/frob/public/interfaces/frobinator.mojom.h"
242 #include "third_party/mojo/src/mojo/public/cpp/bindings/binding.h" 242 #include "mojo/public/cpp/bindings/binding.h"
243 #include "third_party/mojo/src/mojo/public/cpp/bindings/interface_request.h" 243 #include "mojo/public/cpp/bindings/interface_request.h"
244 244
245 class FrobinatorImpl : public frob::Frobinator { 245 class FrobinatorImpl : public frob::Frobinator {
246 public: 246 public:
247 FrobinatorImpl(mojo::InterfaceRequest<frob::Frobinator> request) 247 FrobinatorImpl(mojo::InterfaceRequest<frob::Frobinator> request)
248 : binding_(this, request.Pass()) {} 248 : binding_(this, request.Pass()) {}
249 ~FrobinatorImpl() override {} 249 ~FrobinatorImpl() override {}
250 250
251 private: 251 private:
252 // frob::Frobinator: 252 // frob::Frobinator:
253 void Frobinate() override { /* ... */ } 253 void Frobinate() override { /* ... */ }
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
289 1. The message is passed on to the receiver. In this case the receiver is 289 1. The message is passed on to the receiver. In this case the receiver is
290 generated bindings code, via `Binding<T>`. This code decodes and validates 290 generated bindings code, via `Binding<T>`. This code decodes and validates
291 the `Frobinate` message. 291 the `Frobinate` message.
292 1. `FrobinatorImpl::Frobinate()` is called on the bound implementation. 292 1. `FrobinatorImpl::Frobinate()` is called on the bound implementation.
293 293
294 So as you can see, the call to `Frobinate()` may result in up to two thread hops 294 So as you can see, the call to `Frobinate()` may result in up to two thread hops
295 and one process hop before the service implementation is invoked. 295 and one process hop before the service implementation is invoked.
296 296
297 #### `mojo::StrongBinding<T>` 297 #### `mojo::StrongBinding<T>`
298 298
299 Defined in `third_party/mojo/src/mojo/public/cpp/bindings/strong_binding.h`. 299 Defined in `mojo/public/cpp/bindings/strong_binding.h`.
300 300
301 `mojo::StrongBinding<T>` is just like `mojo::Binding<T>` with the exception that 301 `mojo::StrongBinding<T>` is just like `mojo::Binding<T>` with the exception that
302 a `StrongBinding` takes ownership of the bound `T` instance. The instance is 302 a `StrongBinding` takes ownership of the bound `T` instance. The instance is
303 destroyed whenever the bound message pipe is closed. This is convenient in cases 303 destroyed whenever the bound message pipe is closed. This is convenient in cases
304 where you want a service implementation to live as long as the pipe it's 304 where you want a service implementation to live as long as the pipe it's
305 servicing, but like all features with clever lifetime semantics, it should be 305 servicing, but like all features with clever lifetime semantics, it should be
306 used with caution. 306 used with caution.
307 307
308 ## The Mojo Shell 308 ## The Mojo Shell
309 309
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
420 you build should probably go there. Let's create some basic files to kick things 420 you build should probably go there. Let's create some basic files to kick things
421 off. You may want to start a new local Git branch to isolate any changes you 421 off. You may want to start a new local Git branch to isolate any changes you
422 make while working through this. 422 make while working through this.
423 423
424 First create a new `//components/hello` directory. Inside this directory we're 424 First create a new `//components/hello` directory. Inside this directory we're
425 going to add the following files: 425 going to add the following files:
426 426
427 **components/hello/main.cc** 427 **components/hello/main.cc**
428 ``` 428 ```
429 #include "base/logging.h" 429 #include "base/logging.h"
430 #include "third_party/mojo/src/mojo/public/c/system/main.h" 430 #include "mojo/public/c/system/main.h"
431 431
432 MojoResult MojoMain(MojoHandle shell_handle) { 432 MojoResult MojoMain(MojoHandle shell_handle) {
433 LOG(ERROR) << "Hello, world!"; 433 LOG(ERROR) << "Hello, world!";
434 return MOJO_RESULT_OK; 434 return MOJO_RESULT_OK;
435 }; 435 };
436 ``` 436 ```
437 437
438 **components/hello/BUILD.gn** 438 **components/hello/BUILD.gn**
439 ``` 439 ```
440 import("//mojo/public/mojo_application.gni") 440 import("//mojo/public/mojo_application.gni")
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
480 An app that prints `"Hello, world!"` isn't terribly interesting. At a bare 480 An app that prints `"Hello, world!"` isn't terribly interesting. At a bare
481 minimum your app should implement `mojo::ApplicationDelegate` and expose at 481 minimum your app should implement `mojo::ApplicationDelegate` and expose at
482 least one service to connecting applications. 482 least one service to connecting applications.
483 483
484 Let's update `main.cc` with the following contents: 484 Let's update `main.cc` with the following contents:
485 485
486 **components/hello/main.cc** 486 **components/hello/main.cc**
487 ``` 487 ```
488 #include "components/hello/hello_app.h" 488 #include "components/hello/hello_app.h"
489 #include "mojo/application/public/cpp/application_runner.h" 489 #include "mojo/application/public/cpp/application_runner.h"
490 #include "third_party/mojo/src/mojo/public/c/system/main.h" 490 #include "mojo/public/c/system/main.h"
491 491
492 MojoResult MojoMain(MojoHandle shell_handle) { 492 MojoResult MojoMain(MojoHandle shell_handle) {
493 mojo::ApplicationRunner runner(new hello::HelloApp); 493 mojo::ApplicationRunner runner(new hello::HelloApp);
494 return runner.Run(shell_handle); 494 return runner.Run(shell_handle);
495 }; 495 };
496 ``` 496 ```
497 497
498 This is a pretty typical looking `MojoMain`. Most of the time this is all you 498 This is a pretty typical looking `MojoMain`. Most of the time this is all you
499 want -- a `mojo::ApplicationRunner` constructed over a 499 want -- a `mojo::ApplicationRunner` constructed over a
500 `mojo::ApplicationDelegate` instance, `Run()` with the pipe handle received from 500 `mojo::ApplicationDelegate` instance, `Run()` with the pipe handle received from
501 the shell. We'll add some new files to the app as well: 501 the shell. We'll add some new files to the app as well:
502 502
503 **components/hello/public/interfaces/greeter.mojom** 503 **components/hello/public/interfaces/greeter.mojom**
504 ``` 504 ```
505 module hello; 505 module hello;
506 interface Greeter { 506 interface Greeter {
507 Greet(string name) => (string greeting); 507 Greet(string name) => (string greeting);
508 }; 508 };
509 ``` 509 ```
510 510
511 Note the new arrow syntax on the `Greet` method. This indicates that the caller 511 Note the new arrow syntax on the `Greet` method. This indicates that the caller
512 expects a response from the service. 512 expects a response from the service.
513 513
514 **components/hello/public/interfaces/BUILD.gn** 514 **components/hello/public/interfaces/BUILD.gn**
515 ``` 515 ```
516 import("//third_party/mojo/src/mojo/public/tools/bindings/mojom.gni") 516 import("//mojo/public/tools/bindings/mojom.gni")
517 517
518 mojom("interfaces") { 518 mojom("interfaces") {
519 sources = [ 519 sources = [
520 "greeter.mojom", 520 "greeter.mojom",
521 ] 521 ]
522 } 522 }
523 ``` 523 ```
524 524
525 **components/hello/hello_app.h** 525 **components/hello/hello_app.h**
526 ``` 526 ```
(...skipping 29 matching lines...) Expand all
556 556
557 #endif // COMPONENTS_HELLO_HELLO_APP_H_ 557 #endif // COMPONENTS_HELLO_HELLO_APP_H_
558 ``` 558 ```
559 559
560 560
561 **components/hello/hello_app.cc** 561 **components/hello/hello_app.cc**
562 ``` 562 ```
563 #include "base/macros.h" 563 #include "base/macros.h"
564 #include "components/hello/hello_app.h" 564 #include "components/hello/hello_app.h"
565 #include "mojo/application/public/cpp/application_connection.h" 565 #include "mojo/application/public/cpp/application_connection.h"
566 #include "third_party/mojo/src/mojo/public/cpp/bindings/interface_request.h" 566 #include "mojo/public/cpp/bindings/interface_request.h"
567 #include "third_party/mojo/src/mojo/public/cpp/bindings/strong_binding.h" 567 #include "mojo/public/cpp/bindings/strong_binding.h"
568 568
569 namespace hello { 569 namespace hello {
570 570
571 namespace { 571 namespace {
572 572
573 class GreeterImpl : public Greeter { 573 class GreeterImpl : public Greeter {
574 public: 574 public:
575 GreeterImpl(mojo::InterfaceRequest<Greeter> request) 575 GreeterImpl(mojo::InterfaceRequest<Greeter> request)
576 : binding_(this, request.Pass()) { 576 : binding_(this, request.Pass()) {
577 } 577 }
(...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after
964 964
965 This is still a work in progress and might not really take shape until the 965 This is still a work in progress and might not really take shape until the
966 Blink+Chromium merge. In the meantime there are some end-to-end WebUI examples 966 Blink+Chromium merge. In the meantime there are some end-to-end WebUI examples
967 in `/content/browser/webui/web_ui_mojo_browsertest.cc`. In particular, 967 in `/content/browser/webui/web_ui_mojo_browsertest.cc`. In particular,
968 `WebUIMojoTest.ConnectToApplication` connects from a WebUI frame to a test app 968 `WebUIMojoTest.ConnectToApplication` connects from a WebUI frame to a test app
969 running in a new utility process. 969 running in a new utility process.
970 970
971 ## FAQ 971 ## FAQ
972 972
973 Nothing here yet! 973 Nothing here yet!
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698