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

Side by Side Diff: docs/mojo_in_chromium.md

Issue 1483943004: Fix code blocks in mojo_in_chromium.md. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 ```cpp
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 `/third_party/mojo/src/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
182 see later, a first-class concept in Mojom interface definitions. 182 see later, a first-class concept in Mojom interface definitions.
183 183
184 As with `InterfacePtr<T>`, we can manually bind an `InterfaceRequest<T>` to a 184 As with `InterfacePtr<T>`, we can manually bind an `InterfaceRequest<T>` to a
185 pipe endpoint: 185 pipe endpoint:
186 186
187 ``` 187 ```cpp
188 mojo::MessagePipe pipe; 188 mojo::MessagePipe pipe;
189 189
190 mojo::InterfacePtr<frob::Frobinator> frobinator; 190 mojo::InterfacePtr<frob::Frobinator> frobinator;
191 frobinator.Bind( 191 frobinator.Bind(
192 mojo::InterfacePtrInfo<frob::Frobinator>(pipe.handle0.Pass(), 0u)); 192 mojo::InterfacePtrInfo<frob::Frobinator>(pipe.handle0.Pass(), 0u));
193 193
194 mojo::InterfaceRequest<frob::Frobinator> frobinator_request; 194 mojo::InterfaceRequest<frob::Frobinator> frobinator_request;
195 frobinator_request.Bind(pipe.handle1.Pass()); 195 frobinator_request.Bind(pipe.handle1.Pass());
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 `/third_party/mojo/src/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 ```cpp
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 ```cpp
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 `/third_party/mojo/src/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 ```cpp
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 "third_party/mojo/src/mojo/public/cpp/bindings/binding.h"
243 #include "third_party/mojo/src/mojo/public/cpp/bindings/interface_request.h" 243 #include "third_party/mojo/src/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 { /* ... */ }
254 254
255 mojo::Binding<frob::Frobinator> binding_; 255 mojo::Binding<frob::Frobinator> binding_;
256 }; 256 };
257 ``` 257 ```
258 258
259 And then we could write some code to test this: 259 And then we could write some code to test this:
260 260
261 ``` 261 ```cpp
262 // Fun fact: The bindings generator emits a type alias like this for every 262 // Fun fact: The bindings generator emits a type alias like this for every
263 // interface type. frob::FrobinatorPtr is an InterfacePtr<frob::Frobinator>. 263 // interface type. frob::FrobinatorPtr is an InterfacePtr<frob::Frobinator>.
264 frob::FrobinatorPtr frobinator; 264 frob::FrobinatorPtr frobinator;
265 scoped_ptr<FrobinatorImpl> impl( 265 scoped_ptr<FrobinatorImpl> impl(
266 new FrobinatorImpl(mojo::GetProxy(&frobinator))); 266 new FrobinatorImpl(mojo::GetProxy(&frobinator)));
267 frobinator->Frobinate(); 267 frobinator->Frobinate();
268 ``` 268 ```
269 269
270 This will _eventually_ call `FrobinatorImpl::Frobinate()`. "Eventually," because 270 This will _eventually_ call `FrobinatorImpl::Frobinate()`. "Eventually," because
271 the sequence of events when `frobinator->Frobinate()` is called is roughly as 271 the sequence of events when `frobinator->Frobinate()` is called is roughly as
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
418 foreseeable future we'll likely be treating `//components` as a sort of 418 foreseeable future we'll likely be treating `//components` as a sort of
419 top-level home for new Mojo apps in the Chromium tree. Any component application 419 top-level home for new Mojo apps in the Chromium tree. Any component application
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 ```cpp
429 #include "base/logging.h" 430 #include "base/logging.h"
430 #include "third_party/mojo/src/mojo/public/c/system/main.h" 431 #include "third_party/mojo/src/mojo/public/c/system/main.h"
431 432
432 MojoResult MojoMain(MojoHandle shell_handle) { 433 MojoResult MojoMain(MojoHandle shell_handle) {
433 LOG(ERROR) << "Hello, world!"; 434 LOG(ERROR) << "Hello, world!";
434 return MOJO_RESULT_OK; 435 return MOJO_RESULT_OK;
435 }; 436 };
436 ``` 437 ```
437 438
438 **components/hello/BUILD.gn** 439 **components/hello/BUILD.gn**
440
439 ``` 441 ```
440 import("//mojo/public/mojo_application.gni") 442 import("//mojo/public/mojo_application.gni")
441 443
442 mojo_native_application("hello") { 444 mojo_native_application("hello") {
443 sources = [ 445 sources = [
444 "main.cc", 446 "main.cc",
445 ] 447 ]
446 deps = [ 448 deps = [
447 "//base", 449 "//base",
448 "//mojo/environment:chromium", 450 "//mojo/environment:chromium",
(...skipping 28 matching lines...) Expand all
477 479
478 ### Exposing Services 480 ### Exposing Services
479 481
480 An app that prints `"Hello, world!"` isn't terribly interesting. At a bare 482 An app that prints `"Hello, world!"` isn't terribly interesting. At a bare
481 minimum your app should implement `mojo::ApplicationDelegate` and expose at 483 minimum your app should implement `mojo::ApplicationDelegate` and expose at
482 least one service to connecting applications. 484 least one service to connecting applications.
483 485
484 Let's update `main.cc` with the following contents: 486 Let's update `main.cc` with the following contents:
485 487
486 **components/hello/main.cc** 488 **components/hello/main.cc**
487 ``` 489
490 ```cpp
488 #include "components/hello/hello_app.h" 491 #include "components/hello/hello_app.h"
489 #include "mojo/application/public/cpp/application_runner.h" 492 #include "mojo/application/public/cpp/application_runner.h"
490 #include "third_party/mojo/src/mojo/public/c/system/main.h" 493 #include "third_party/mojo/src/mojo/public/c/system/main.h"
491 494
492 MojoResult MojoMain(MojoHandle shell_handle) { 495 MojoResult MojoMain(MojoHandle shell_handle) {
493 mojo::ApplicationRunner runner(new hello::HelloApp); 496 mojo::ApplicationRunner runner(new hello::HelloApp);
494 return runner.Run(shell_handle); 497 return runner.Run(shell_handle);
495 }; 498 };
496 ``` 499 ```
497 500
498 This is a pretty typical looking `MojoMain`. Most of the time this is all you 501 This is a pretty typical looking `MojoMain`. Most of the time this is all you
499 want -- a `mojo::ApplicationRunner` constructed over a 502 want -- a `mojo::ApplicationRunner` constructed over a
500 `mojo::ApplicationDelegate` instance, `Run()` with the pipe handle received from 503 `mojo::ApplicationDelegate` instance, `Run()` with the pipe handle received from
501 the shell. We'll add some new files to the app as well: 504 the shell. We'll add some new files to the app as well:
502 505
503 **components/hello/public/interfaces/greeter.mojom** 506 **components/hello/public/interfaces/greeter.mojom**
507
504 ``` 508 ```
505 module hello; 509 module hello;
506 interface Greeter { 510 interface Greeter {
507 Greet(string name) => (string greeting); 511 Greet(string name) => (string greeting);
508 }; 512 };
509 ``` 513 ```
510 514
511 Note the new arrow syntax on the `Greet` method. This indicates that the caller 515 Note the new arrow syntax on the `Greet` method. This indicates that the caller
512 expects a response from the service. 516 expects a response from the service.
513 517
514 **components/hello/public/interfaces/BUILD.gn** 518 **components/hello/public/interfaces/BUILD.gn**
519
515 ``` 520 ```
516 import("//third_party/mojo/src/mojo/public/tools/bindings/mojom.gni") 521 import("//third_party/mojo/src/mojo/public/tools/bindings/mojom.gni")
517 522
518 mojom("interfaces") { 523 mojom("interfaces") {
519 sources = [ 524 sources = [
520 "greeter.mojom", 525 "greeter.mojom",
521 ] 526 ]
522 } 527 }
523 ``` 528 ```
524 529
525 **components/hello/hello_app.h** 530 **components/hello/hello_app.h**
526 ``` 531
532 ```cpp
527 #ifndef COMPONENTS_HELLO_HELLO_APP_H_ 533 #ifndef COMPONENTS_HELLO_HELLO_APP_H_
528 #define COMPONENTS_HELLO_HELLO_APP_H_ 534 #define COMPONENTS_HELLO_HELLO_APP_H_
529 535
530 #include "base/macros.h" 536 #include "base/macros.h"
531 #include "components/hello/public/interfaces/greeter.mojom.h" 537 #include "components/hello/public/interfaces/greeter.mojom.h"
532 #include "mojo/application/public/cpp/application_delegate.h" 538 #include "mojo/application/public/cpp/application_delegate.h"
533 #include "mojo/application/public/cpp/interface_factory.h" 539 #include "mojo/application/public/cpp/interface_factory.h"
534 540
535 namespace hello { 541 namespace hello {
536 542
(...skipping 15 matching lines...) Expand all
552 DISALLOW_COPY_AND_ASSIGN(HelloApp); 558 DISALLOW_COPY_AND_ASSIGN(HelloApp);
553 }; 559 };
554 560
555 } // namespace hello 561 } // namespace hello
556 562
557 #endif // COMPONENTS_HELLO_HELLO_APP_H_ 563 #endif // COMPONENTS_HELLO_HELLO_APP_H_
558 ``` 564 ```
559 565
560 566
561 **components/hello/hello_app.cc** 567 **components/hello/hello_app.cc**
562 ``` 568
569 ```cpp
563 #include "base/macros.h" 570 #include "base/macros.h"
564 #include "components/hello/hello_app.h" 571 #include "components/hello/hello_app.h"
565 #include "mojo/application/public/cpp/application_connection.h" 572 #include "mojo/application/public/cpp/application_connection.h"
566 #include "third_party/mojo/src/mojo/public/cpp/bindings/interface_request.h" 573 #include "third_party/mojo/src/mojo/public/cpp/bindings/interface_request.h"
567 #include "third_party/mojo/src/mojo/public/cpp/bindings/strong_binding.h" 574 #include "third_party/mojo/src/mojo/public/cpp/bindings/strong_binding.h"
568 575
569 namespace hello { 576 namespace hello {
570 577
571 namespace { 578 namespace {
572 579
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
609 new GreeterImpl(request.Pass()); 616 new GreeterImpl(request.Pass());
610 } 617 }
611 618
612 } // namespace hello 619 } // namespace hello
613 ``` 620 ```
614 621
615 And finally we need to update our app's `BUILD.gn` to add some new sources and 622 And finally we need to update our app's `BUILD.gn` to add some new sources and
616 dependencies: 623 dependencies:
617 624
618 **components/hello/BUILD.gn** 625 **components/hello/BUILD.gn**
626
619 ``` 627 ```
620 import("//mojo/public/mojo_application.gni") 628 import("//mojo/public/mojo_application.gni")
621 629
622 source_set("lib") { 630 source_set("lib") {
623 sources = [ 631 sources = [
624 "hello_app.cc", 632 "hello_app.cc",
625 "hello_app.h", 633 "hello_app.h",
626 ] 634 ]
627 deps = [ 635 deps = [
628 "//base", 636 "//base",
(...skipping 28 matching lines...) Expand all
657 test! 665 test!
658 666
659 ### App Tests 667 ### App Tests
660 668
661 App tests run inside a test application, giving test code access to a shell 669 App tests run inside a test application, giving test code access to a shell
662 which can connect to one or more applications-under-test. 670 which can connect to one or more applications-under-test.
663 671
664 First let's introduce some test code: 672 First let's introduce some test code:
665 673
666 **components/hello/hello_apptest.cc** 674 **components/hello/hello_apptest.cc**
667 ``` 675
676 ```cpp
668 #include "base/bind.h" 677 #include "base/bind.h"
669 #include "base/callback.h" 678 #include "base/callback.h"
670 #include "base/logging.h" 679 #include "base/logging.h"
671 #include "base/macros.h" 680 #include "base/macros.h"
672 #include "base/run_loop.h" 681 #include "base/run_loop.h"
673 #include "components/hello/public/interfaces/greeter.mojom.h" 682 #include "components/hello/public/interfaces/greeter.mojom.h"
674 #include "mojo/application/public/cpp/application_impl.h" 683 #include "mojo/application/public/cpp/application_impl.h"
675 #include "mojo/application/public/cpp/application_test_base.h" 684 #include "mojo/application/public/cpp/application_test_base.h"
676 685
677 namespace hello { 686 namespace hello {
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
773 782
774 This is exploited by the definition of 783 This is exploited by the definition of
775 `mojo::ApplicationConnection::ConnectToService<T>`, which uses `T::Name_` as the 784 `mojo::ApplicationConnection::ConnectToService<T>`, which uses `T::Name_` as the
776 name of the service to connect to. The type `T` in this context is inferred from 785 name of the service to connect to. The type `T` in this context is inferred from
777 the `InterfacePtr<T>*` argument. You can inspect the definition of 786 the `InterfacePtr<T>*` argument. You can inspect the definition of
778 `ConnectToService` in `/mojo/application/public/cpp/application_connection.h` 787 `ConnectToService` in `/mojo/application/public/cpp/application_connection.h`
779 for additional clarity. 788 for additional clarity.
780 789
781 We could have instead written this code as: 790 We could have instead written this code as:
782 791
783 ``` 792 ```cpp
784 mojo::URLRequestPtr app_url = mojo::URLRequest::New(); 793 mojo::URLRequestPtr app_url = mojo::URLRequest::New();
785 app_url->url = "mojo::hello"; 794 app_url->url = "mojo::hello";
786 795
787 mojo::ServiceProviderPtr services; 796 mojo::ServiceProviderPtr services;
788 application_impl()->shell()->ConnectToApplication( 797 application_impl()->shell()->ConnectToApplication(
789 app_url.Pass(), mojo::GetProxy(&services), 798 app_url.Pass(), mojo::GetProxy(&services),
790 // We pass a null provider since we aren't exposing any of our own 799 // We pass a null provider since we aren't exposing any of our own
791 // services to the target app. 800 // services to the target app.
792 mojo::ServiceProviderPtr()); 801 mojo::ServiceProviderPtr());
793 802
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
828 Applications can be set up to run within the browser process via 837 Applications can be set up to run within the browser process via
829 `ContentBrowserClient::RegisterInProcessMojoApplications`. This method populates 838 `ContentBrowserClient::RegisterInProcessMojoApplications`. This method populates
830 a mapping from URL to `base::Callback<scoped_ptr<mojo::ApplicationDelegate>()>` 839 a mapping from URL to `base::Callback<scoped_ptr<mojo::ApplicationDelegate>()>`
831 (_i.e._, a factory function which creates a new `mojo::ApplicationDelegate` 840 (_i.e._, a factory function which creates a new `mojo::ApplicationDelegate`
832 instance), so registering a new app means adding an entry to this map. 841 instance), so registering a new app means adding an entry to this map.
833 842
834 Let's modify `ChromeContentBrowserClient::RegisterInProcessMojoApplications` 843 Let's modify `ChromeContentBrowserClient::RegisterInProcessMojoApplications`
835 (in `//chrome/browser/chrome_content_browser_client.cc`) by adding the following 844 (in `//chrome/browser/chrome_content_browser_client.cc`) by adding the following
836 code: 845 code:
837 846
838 apps->insert(std::make_pair(GURL("mojo:hello"), 847 ```cpp
839 base::Bind(&HelloApp::CreateApp))); 848 apps->insert(std::make_pair(GURL("mojo:hello"),
849 base::Bind(&HelloApp::CreateApp)));
850 ```
840 851
841 you'll also want to add the following convenience method to your `HelloApp` 852 you'll also want to add the following convenience method to your `HelloApp`
842 definition in `//components/hello/hello_app.h`: 853 definition in `//components/hello/hello_app.h`:
843 854
844 static scoped_ptr<mojo::ApplicationDelegate> HelloApp::CreateApp() { 855 ```cpp
845 return scoped_ptr<mojo::ApplicationDelegate>(new HelloApp); 856 static scoped_ptr<mojo::ApplicationDelegate> HelloApp::CreateApp() {
846 } 857 return scoped_ptr<mojo::ApplicationDelegate>(new HelloApp);
858 }
859 ```
847 860
848 This introduces a dependency from `//chrome/browser` on to 861 This introduces a dependency from `//chrome/browser` on to
849 `//components/hello:lib`, which you can add to the `"browser"` target's deps in 862 `//components/hello:lib`, which you can add to the `"browser"` target's deps in
850 `//chrome/browser/BUILD.gn`. You'll of course also need to include 863 `//chrome/browser/BUILD.gn`. You'll of course also need to include
851 `"components/hello/hello_app.h"` in `chrome_content_browser_client.cc`. 864 `"components/hello/hello_app.h"` in `chrome_content_browser_client.cc`.
852 865
853 That's it! Now if an app comes to the shell asking to connect to `"mojo:hello"` 866 That's it! Now if an app comes to the shell asking to connect to `"mojo:hello"`
854 and app is already running, it'll get connected to our `HelloApp` and have 867 and app is already running, it'll get connected to our `HelloApp` and have
855 access to the `Greeter` service. If the app wasn't already running, it will 868 access to the `Greeter` service. If the app wasn't already running, it will
856 first be launched on a new thread. 869 first be launched on a new thread.
857 870
858 ### Connecting From the Browser 871 ### Connecting From the Browser
859 872
860 We've already seen how apps can connect to each other using their own private 873 We've already seen how apps can connect to each other using their own private
861 shell proxy, but the vast majority of Chromium code doesn't yet belong to a Mojo 874 shell proxy, but the vast majority of Chromium code doesn't yet belong to a Mojo
862 application. So how do we use an app's services from arbitrary browser code? We 875 application. So how do we use an app's services from arbitrary browser code? We
863 use `content::MojoAppConnection`, like this: 876 use `content::MojoAppConnection`, like this:
864 877
865 ``` 878 ```cpp
866 #include "base/bind.h" 879 #include "base/bind.h"
867 #include "base/logging.h" 880 #include "base/logging.h"
868 #include "components/hello/public/interfaces/greeter.mojom.h" 881 #include "components/hello/public/interfaces/greeter.mojom.h"
869 #include "content/public/browser/mojo_app_connection.h" 882 #include "content/public/browser/mojo_app_connection.h"
870 883
871 void LogGreeting(const mojo::String& greeting) { 884 void LogGreeting(const mojo::String& greeting) {
872 LOG(INFO) << greeting; 885 LOG(INFO) << greeting;
873 } 886 }
874 887
875 void GreetTheWorld() { 888 void GreetTheWorld() {
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
923 run out-of-process and unsandboxed (which you **probably do not**), you can 936 run out-of-process and unsandboxed (which you **probably do not**), you can
924 register its URL via 937 register its URL via
925 `ContentBrowserClient::RegisterUnsandboxedOutOfProcessMojoApplications`. 938 `ContentBrowserClient::RegisterUnsandboxedOutOfProcessMojoApplications`.
926 939
927 ## Connecting From `RenderFrame` 940 ## Connecting From `RenderFrame`
928 941
929 We can also connect to Mojo apps from a `RenderFrame`. This is made possible by 942 We can also connect to Mojo apps from a `RenderFrame`. This is made possible by
930 `RenderFrame`'s `GetServiceRegistry()` interface. The `ServiceRegistry` can be 943 `RenderFrame`'s `GetServiceRegistry()` interface. The `ServiceRegistry` can be
931 used to acquire a shell proxy and in turn connect to an app like so: 944 used to acquire a shell proxy and in turn connect to an app like so:
932 945
933 ``` 946 ```cpp
934 void GreetWorld(content::RenderFrame* frame) { 947 void GreetWorld(content::RenderFrame* frame) {
935 mojo::ShellPtr shell; 948 mojo::ShellPtr shell;
936 frame->GetServiceRegistry()->ConnectToRemoteService( 949 frame->GetServiceRegistry()->ConnectToRemoteService(
937 mojo::GetProxy(&shell)); 950 mojo::GetProxy(&shell));
938 951
939 mojo::URLRequestPtr request = mojo::URLRequest::New(); 952 mojo::URLRequestPtr request = mojo::URLRequest::New();
940 request->url = "mojo:hello"; 953 request->url = "mojo:hello";
941 954
942 mojo::ServiceProviderPtr hello_services; 955 mojo::ServiceProviderPtr hello_services;
943 shell->ConnectToApplication( 956 shell->ConnectToApplication(
(...skipping 20 matching lines...) Expand all
964 977
965 This is still a work in progress and might not really take shape until the 978 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 979 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, 980 in `/content/browser/webui/web_ui_mojo_browsertest.cc`. In particular,
968 `WebUIMojoTest.ConnectToApplication` connects from a WebUI frame to a test app 981 `WebUIMojoTest.ConnectToApplication` connects from a WebUI frame to a test app
969 running in a new utility process. 982 running in a new utility process.
970 983
971 ## FAQ 984 ## FAQ
972 985
973 Nothing here yet! 986 Nothing here yet!
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698