Movatterモバイル変換


[0]ホーム

URL:


Google Git
Sign in
chromium /chromium /src /refs/heads/main /. /docs /mojo_ipc_conversion.md
blob: 28a8438c2f750759a9afe744c8673c1773ebcd8c [file] [log] [blame] [view]
Ken Rockotab035122019-02-06 00:35:24[diff] [blame]1# Converting Legacy IPC to Mojo
2
3[TOC]
4
5## Overview
6
7A number of IPC messages sent (primarily between the browser and renderer
8processes) are still defined using Chrome's old IPC system in `//ipc`. This
9system uses
10[`base::Pickle`](https://cs.chromium.org/chromium/src/base/pickle.h?rcl=8b7842262ee1239b1f3ae20b9c851748ef0b9a8b&l=128)
11as the basis for message serialization and is supported by a number if `IPC_*`
12preprocessor macros defined in `//ipc` and used around the source tree.
13
14There is an ongoing, distributed effort to get these messages converted to Mojo
15interface messages. Messages that still need to be converted are tracked in two
16spreadsheets:
17
18- [Chrome IPC to Mojo migration](https://docs.google.com/spreadsheets/d/1pGWX_wxGdjAVtQOmlDDfhuIc3Pbwg9FtvFXAXYu7b7c/edit#gid=0) for non-web platform messages
19- [Mojoifying Platform Features](https://docs.google.com/spreadsheets/d/1VIINt17Dg2cJjPpoJ_HY3HI0uLpidql-1u8pBJtpbGk/edit#gid=1603373208) for web platform messages
20
21This document is concerned primarily with rote conversion of legacy IPC messages
22to Mojo interface messages. If you are considering more holistic refactoring and
23better isolation of an entire subsystem of the browser, you may consider
24[servicifying](servicification.md) the feature instead of merely converting its
25IPCs.
26
27See other [Mojo & Services](/docs/README.md#Mojo-Services) documentation
28for introductory guides, API references, and more.
29
30## Legacy IPC Concepts
31
32Each Content child process has a single **`IPC::Channel`** implementation going
33between it and the browser process, and this is used as the sole two-way FIFO
34to send legacy IPC messages between the processes.
35
36There are two fundamental types of legacy IPC messages: **control** messages,
37defined via `IPC_MESSAGE_CONTROLn` macros (where `n` is some small integer) and
38**routed** messages defined via `IPC_MESSAGE_ROUTEDn` macros.
39
40Control messages generally go between a browser-side process host (*e.g.*,
41`RenderProcessHost` or `GpuProcessHost`) and the child-side `ChildThreadImpl`
42subclass. All of these classes implement `IPC::Sender` and thus have a `Send`
43method for sending a control message to their remote counterpart, and they
44implement `IPC::Listener` to receive incoming control messages via
45`OnMessageReceived`.
46
47Routed messages are relegated to **routes** which have arbitrary meaning
48determined by their use within a given process. For example, renderers use
49routes to isolate messages scoped to individual render frames, and so such
50routed messages will travel between a `RenderFrameHostImpl` and its
51corresponding `RenderFrameImpl`, both of which also implement `IPC::Sender` and
52`IPC::Listener`.
53
54## Mojo Interfaces as Routes
55
56Routed messages in the old IPC system always carry a **routing ID** to identify
57to the receiving endpoint which routed object (*e.g.* which `RenderFrameImpl`
58or `RenderViewImpl` or whatever) the message is targeting. Each endpoint is thus
59required to do some additional book-keeping to track what each routing ID means.
60
61Mojo interfaces obviate the need for routing IDs, as new "routes" can be
62established by simply creating a new interface pipe and passing one endpoint to
63something which knows how to bind it.
64
65When thinking about an IPC message conversion to Mojo, it's important to
66consider whether the message is a control message or a routed message, as this
67determines where you might find an existing Mojo interface to carry your
68message, or where you will want to add a new end-to-end Mojo interface for that
69purpose. This can mean the difference between a single per-process interface
70going between each `RenderProcessHostImpl` and its corresponding
71`RenderThreadImpl`, vs a per-frame interface going between each
72`RenderFrameHostImpl` and its corresponding `RenderFrameImpl`.
73
74## Ordering Considerations
75
76One **very important** consideration when doing IPC conversions is the relative
77ordering of IPC-driven operations. With the old IPC system, because every
78message between two processes is globally ordered, it is quite easy for parts
79of the system to (intentionally or often unintentionally) rely on strict
80ordering guarantees.
81
82For example, imagine a `WebContentsObserver` in the browser processes observes
83a frame navigation and immediately sends an IPC message to the frame to
84configure some new behavior. The implementation may be inadvertently relying on
85this message arriving *before* some other tangentially related message sent to
86the same frame shortly after the same navigation event.
87
Hong Xua2be4a32023-04-19 19:18:28[diff] [blame]88While Mojo guarantees strict ordering within each message pipe, Mojo does not
89(and in fact cannot) make any strict ordering guarantees between separate
90message pipes, as message pipes may be freely moved across process boundaries
91and thus cannot necessarily share a common FIFO at all times.
Ken Rockotab035122019-02-06 00:35:24[diff] [blame]92
93If the two messages described above were moved to separate Mojo interfaces on
94separate message pipes, renderer behavior could break as the first message may
95arrive after the second message.
96
97The best solution to this problem is to rethink the IPC surface and/or
98implementation on either side to eliminate ordering dependencies between two
99interfaces that otherwise seem to be logically distinct. Failing that, Mojo's
100solution to this problem is to support
101[**associated interfaces**](/mojo/public/tools/bindings/README.md#Associated-Interfaces).
102In a nutshell, these allow multiple distinct interfaces to be multiplexed over
103a shared message pipe.
104
105## Channel-Associated Interfaces
106
107The previous section mentions **associated interfaces** as a general-purpose
108solution for establishing a mutual FIFO between multiple logical Mojo interfaces
109by having them share a single message pipe.
110
Egor Paskof833cde82025-06-10 17:25:07[diff] [blame]111In Chrome, the `IPC::Channel` which carries all legacy IPC messages between two
112processes is itself a Mojo message pipe (implicitly). We provide a mechanism for
Ken Rockotab035122019-02-06 00:35:24[diff] [blame]113associating arbitrary Mojo interfaces with this pipe, which means messages can
114be converted to Mojo while preserving strict FIFO with respect to other legacy
115IPC messages. Such interfaces are designated in Chrome parlance as
116**Channel-associated interfaces**.
117
Ken Rockotab035122019-02-06 00:35:24[diff] [blame]118Usage of Channel-associated interfaces should be rare but is considered a
119reasonable intermediate solution for incremental IPC conversions where it would
120be too risky or noisy to convert a large IPC surface all at once, but it would
121also be impossible to split the IPC surface between legacy IPC and a dedicated
122Mojo interface pipe without introducing timing bugs.
123
124At this point in Chrome's development, practical usage of Channel-associated
125interfaces is restricted to the `IPC::Channel` between the browser process and
126a renderer process, as this is the most complex IPC surface with the most
127implicit ordering dependencies. A few simple APIs exist to support this.
128
Egor Paskof833cde82025-06-10 17:25:07[diff] [blame]129`RenderProcessHostImpl` owns an `IPC::Channel` (through `IPC::ChannelProxy`)
130to its corresponding `RenderFrameImpl` in the render process. This object has a
Ken Rockotab035122019-02-06 00:35:24[diff] [blame]131`GetRemoteAssociatedInterfaces` method which can be used to pass arbitrary
132associated interface requests:
133
134``` cpp
Oksana Zhuravlova9f3b8ef2019-08-26 20:27:40[diff] [blame]135mojo::PendingAssociatedRemote<magic::mojom::GoatTeleporter> teleporter;
Egor Paskof833cde82025-06-10 17:25:07[diff] [blame]136render_frame->GetRemoteAssociatedInterfaces()->GetInterface(&teleporter);
Ken Rockotab035122019-02-06 00:35:24[diff] [blame]137
138// These messages are all guaranteed to arrive in the same order they were sent.
139channel_->Send(new FooMsg_SomeLegacyIPC);
140teleporter->TeleportAllGoats();
141channel_->Send(new FooMsg_AnotherLegacyIPC);
142```
143
Egor Paskof833cde82025-06-10 17:25:07[diff] [blame]144Likewise, `RenderFrameHostImpl` defines a `GetRemoteAssociatedInterfaces`
145method.
Ken Rockotab035122019-02-06 00:35:24[diff] [blame]146
147To receive and bind incoming Channel-associated interface requests, the above
148objects also implement `IPC::Listener::OnAssociatedInterfaceRequest`.
149
Ken Rockotab035122019-02-06 00:35:24[diff] [blame]150There are some example conversion CLs which use Channel-associated interfaces
151[here](https://codereview.chromium.org/2381493003) and
152[here](https://codereview.chromium.org/2400313002).
153
154## Deciding How to Approach a Conversion
155
156There are a few questions you should ask before embarking upon any IPC message
157conversion journey, and there are many potential approaches to consider. The
158right one depends on context.
159
160Note that this section assumes the message is traveling between the browser
161process and a renderer process. Other cases are rare and developers may wish to
162consult
163[chromium-mojo@chromium.org](https://groups.google.com/a/chromium.org/forum/#!forum/chromium-mojo)
164before proceeding with them. Otherwise, apply the following basic algorithm to
165decide how to proceed:
166
167- General note: If the message is a reply to some other message (typically these
168 take a "request ID" argument), see the note about message replies at the
169 bottom of this section.
170- Consider whether or not the message makes sense as part of the IPC surface of
171 a new or existing service somewhere in `//services` or `//chrome/services`,
172 *etc.* This is less and less likely to be the case as time goes on, as many
173 remaining IPC conversions are quite narrowly dealing with specific
174 browser/renderer details rather than the browser's supporting subsystems. If
175 defining a new service, you may wish to consult some of the other
176 [Mojo &amp; Services documentation](/docs/README.md#Mojo-Services) first.
177- If the message is an `IPC_MESSAGE_CONTROL` message:
178 - If there are likely to be strict ordering requirements between this
179 message and other legacy IPC or Channel-associated interface messages,
180 consider using a new or existing
181 [Channel-associated interface](#Channel-Associated-Interfaces) between
182 `RenderProcessHostImpl` and `RenderThreadImpl`.
183 - If the message is sent from a renderer to the browser:
184 - If an existing interface is bound by `RenderProcessHostImpl` and
185 requested through `RenderThread`'s Connector and seems to be a good
186 fit for the message, add the equivalent Mojo message to that
187 interface.
188 - If no such interface exists, consider adding one for this message and
189 any related messages.
190 - If the message is sent from the browser to a renderer:
191 - If an existing interface is bound by `RenderThreadImpl` and requested
192 through a `BrowserContext` Connector referencing a specific
193 `RenderProcessHost` [identity](https://cs.chromium.org/chromium/src/content/public/browser/render_process_host.h?rcl=1497b88b7d6400a2a5cced258df03d53800d7848&l=327),
194 and the interface seems to be a good fit for the message, add the
195 equivalent Mojo message to that interface.
196 - If no such interface exists, consider adding one for this message and
197 any related messages.
198- If the message is an `IPC_MESSAGE_ROUTED` message:
199 - Determine what the routing endpoints are. If they are
200 `RenderFrameHostImpl` and `RenderFrameImpl`:
201 - If there are likely to be strict ordering requirements between this
202 message and other legacy IPC or Channel-associated interface messages,
203 consider using a new or existing
204 [Channel-associated interface](#Channel-Associated-Interfaces) between
205 `RenderFrameHostImpl` and `RenderFrameImpl`.
206 - If the message is sent from a renderer to the browser:
207 - If an existing interface is bound by `RenderFrameHostImpl` and
Oksana Zhuravlovab685db62020-02-21 20:14:01[diff] [blame]208 acquired via `RenderFrame::GetBrowserInterfaceBroker` and the interface seems
Ken Rockotab035122019-02-06 00:35:24[diff] [blame]209 to be a good fit for this message, add the equivalent Mojo message
210 to that interface.
Oksana Zhuravlovacf170052019-09-23 19:56:27[diff] [blame]211 - If no such interface exists, consider adding one and registering it
212 with `RenderFrameHostImpl`'s `BrowserInterfaceBroker`. See the
Ken Rockotab035122019-02-06 00:35:24[diff] [blame]213 [simple example](/docs/mojo_and_services.md#Example_Defining-a-New-Frame-Interface)
Oksana Zhuravlovacf170052019-09-23 19:56:27[diff] [blame]214 in the "Intro to Mojo & Services" document.
Ken Rockotab035122019-02-06 00:35:24[diff] [blame]215 - If the message is sent from the browser to a renderer, consider
216 adding a Mojo equivalent to the `content.mojom.Frame` interface
217 defined
218 [here](https://cs.chromium.org/chromium/src/content/common/frame.mojom?rcl=138b66744ee9ee853cbb0ae8437b71eaa1fafaa9&l=42).
219 - If the routing endpoints are **not** frame objects (for example, they may
220 be `RenderView`/`RenderViewHost` objects), this is a special case which
221 does not yet have an easy conversion approach readily available. Contact
222 [chromium-mojo@chromium.org](https://groups.google.com/a/chromium.org/forum#!forum/chromium-mojo)
223 to propose or discuss options.
224
Oksana Zhuravlova355fa642019-02-15 22:21:04[diff] [blame]225*** aside
226**NOTE**: If you are converting a sync IPC, see the section on
227[Synchronous Calls](/mojo/public/cpp/bindings/README.md#Synchronous-Calls)
228in the Mojo documentation.
229***
230
Ken Rockotab035122019-02-06 00:35:24[diff] [blame]231### Dealing With Replies
232
233If the message is a **reply**, meaning it has a "request ID" which correlates it
234to a prior message in the opposite direction, consider converting the
235**request** message following the algorithm above. Unlike with legacy IPC, Mojo
236messages support replies as a first-class concept. So for example if you have:
237
238``` cpp
239IPC_CONTROL_MESSAGE2(FooHostMsg_DoTheThing,
240 int /* request_id */,
241 std::string /* name */);
242IPC_CONTROL_MESSAGE2(FooMsg_DidTheThing,
243 int /* request_id */,
244 bool /* success */);
245```
246
247You should consider defining an interface `Foo` which is bound in
248`RenderProcessHostImpl` and acquired from `RenderThreadImpl`, with the following
249mojom definition:
250
251``` cpp
252interface Foo {
253 DoTheThing(string name) => (bool success);
254};
255```
Oksana Zhuravlova87b225a2019-03-07 01:08:03[diff] [blame]256See [Receiving responses](/mojo/public/cpp/bindings/README.md#receiving-responses)
257for more information.
Ken Rockotab035122019-02-06 00:35:24[diff] [blame]258
259## Repurposing `IPC::ParamTraits` and `IPC_STRUCT*` Invocations
260
261Occasionally it is useful to do partial IPC conversions, where you want to
262convert a message to a Mojo interface method but you don't want to necessarily
263convert every structure passed by the message. In this case, you can leverage
264Mojo's
Oksana Zhuravlovaa77a9a12021-05-07 18:02:10[diff] [blame]265[type-mapping](https://chromium.googlesource.com/chromium/src/+/main/mojo/public/cpp/bindings/README.md#Type-Mapping)
Ken Rockotab035122019-02-06 00:35:24[diff] [blame]266system to repurpose existing `IPC::ParamTraits`.
267
268*** aside
269**NOTE**: Although in some cases `IPC::ParamTraits<T>` specializations are
270defined manually in library code, the `IPC_STRUCT*` macro helpers also define
271`IPC::ParamTraits<T>` specializations under the hood. All advice in this section
272pertains to both kinds of definitions.
273***
274
275If a mojom struct is declared without a struct body and is tagged with
276`[Native]`, and a corresponding typemap is provided for the struct, the emitted
277C++ bindings will -- as if by magic -- replace the mojom type with the
278typemapped C++ type and will internally use the existing `IPC::ParamTraits<T>`
279specialization for that type in order to serialize and deserialize the struct.
280
281For example, given the
282[`resource_messages.h`](https://cs.chromium.org/chromium/src/content/common/resource_messages.h?rcl=2e7a430d8d88222c04ab3ffb0a143fa85b3cec5b&l=215) header
283which defines an IPC mapping for `content::ResourceRequest`:
284
285``` cpp
286IPC_STRUCT_TRAITS_BEGIN(content::ResourceRequest)
287 IPC_STRUCT_TRAITS_MEMBER(method)
288 IPC_STRUCT_TRAITS_MEMBER(url)
289 // ...
290IPC_STRUCT_TRAITS_END()
291```
292
293and the
294[`resource_request.h`](https://cs.chromium.org/chromium/src/content/common/resource_request.h?rcl=dce9e476a525e4ff0304787935dc1a8c38392ac8&l=32) header
295which actually defines the `content::ResourceRequest` type:
296
297``` cpp
298namespace content {
299
300struct CONTENT_EXPORT ResourceRequest {
301 // ...
302};
303
304} // namespace content
305```
306
307we can declare a corresponding "native" mojom struct:
308
309``` cpp
310module content.mojom;
311
312[Native]
313struct URLRequest;
314```
315
316and add a typemap like
317[`url_request.typemap`](https://cs.chromium.org/chromium/src/content/common/url_request.typemap?rcl=4b5963fa744a706398f8f06a4cbbf70d7fa3213d)
318to define how to map between them:
319
320``` python
321mojom = "//content/public/common/url_loader.mojom"
322public_headers = [ "//content/common/resource_request.h" ]
323traits_headers = [ "//content/common/resource_messages.h" ]
324...
325type_mappings = [ "content.mojom.URLRequest=content::ResourceRequest" ]
326```
327
328Note specifically that public_headers includes the definition of the native C++
329type, and traits_headers includes the definition of the legacy IPC traits.
330
331As a result of all this, other mojom files can now reference
332`content.mojom.URLRequest` as a type for method parameters and other struct
333fields, and the generated C++ bindings will represent those values exclusively
334as `content::ResourceRequest` objects.
335
336This same basic approach can be used to leverage existing `IPC_ENUM_TRAITS` for
337invocations for `[Native]` mojom enum aliases.
338
339*** aside
340**NOTE:** Use of `[Native]` mojom definitions is strictly limited to C++
341bindings. If a mojom message depends on such definitions, it cannot be sent or
342received by other language bindings. This feature also depends on continued
343support for legacy IPC serialization and all uses of it should therefore be
344treated as technical debt.
345***
346
Oksana Zhuravlova4f3692b2019-02-08 21:00:58[diff] [blame]347## Blink-Specific Advice
348
349### Variants
350Let's assume we have a mojom file such as this:
351
352``` cpp
353module example.mojom;
354
355interface Foo {
356 SendData(string param1, array<int32> param2);
357};
358```
359
360The following GN snippet will generate two concrete targets: `example` and
361`example_blink`:
362
363```
364mojom("example") {
365 sources = [ "example.mojom" ]
366}
367```
368
369The target `example` will generate Chromium-style C++ bindings using STL types:
370
371``` cpp
372// example.mojom.h
373namespace example {
374namespace mojom {
375
376class Example {
377 virtual void SendArray(const std::string& param1, const std::vector<int32_t>& param2) = 0;
378}
379
380} // namespace mojom
381} // namespace example
382```
383
384The target `example_blink` will generate Blink-style C++ bindings using WTF types:
385
386``` cpp
387// example.mojom-blink.h
388namespace example {
389namespace mojom {
390namespace blink {
391
392class Example {
393 virtual void SendArray(const WTF::String& param1, const WTF::Vector<int32_t>& param2) = 0;
394}
395
396} // namespace blink
397} // namespace mojom
398} // namespace example
399```
400
401Thanks to these separate sets of bindings no work is necessary to convert types
402between Blink-style code and Chromium-style code. It is handled automatically
403during message serialization and deserialization.
404
405For more information about variants, see
406[this section](/mojo/public/cpp/bindings/README.md#Variants) of the C++ bindings
407documentation.
408
409### Binding callbacks
410
411Mojo methods that return a value take an instance of `base::OnceCallback`.
Dave Tapuska28700f92022-09-16 14:02:31[diff] [blame]412Use `WTF::BindOnce()` and an appropriate wrapper function depending on the type of
Oksana Zhuravlova4f3692b2019-02-08 21:00:58[diff] [blame]413object and the callback.
414
Oksana Zhuravlova9f3b8ef2019-08-26 20:27:40[diff] [blame]415For garbage-collected (Oilpan) classes owning the `mojo::Remote`, it is recommended
Oksana Zhuravlova6fac3d132019-02-19 23:58:33[diff] [blame]416to use `WrapWeakPersistent(this)` for connection error handlers since they
417are not guaranteed to get called in a finite time period (wrapping the object
418with `WrapPersistent` in this case would cause memory leaks).
419
420If the response can be discarded in case the object is not alive by the time
421the response is received, use `WrapWeakPersistent(this)` for binding the response callback:
Oksana Zhuravlova4f3692b2019-02-08 21:00:58[diff] [blame]422
423``` cpp
Oksana Zhuravlova6fac3d132019-02-19 23:58:33[diff] [blame]424// src/third_party/blink/renderer/modules/device_orientation/device_sensor_entry.cc
Dave Tapuska28700f92022-09-16 14:02:31[diff] [blame]425sensor_.set_connection_error_handler(WTF::BindOnce(
Oksana Zhuravlova6fac3d132019-02-19 23:58:33[diff] [blame]426 &DeviceSensorEntry::HandleSensorError, WrapWeakPersistent(this)));
427sensor_->ConfigureReadingChangeNotifications(/*enabled=*/false);
428sensor_->AddConfiguration(
Dave Tapuska28700f92022-09-16 14:02:31[diff] [blame]429 std::move(config), WTF::BindOnce(&DeviceSensorEntry::OnSensorAddConfiguration,
Oksana Zhuravlova6fac3d132019-02-19 23:58:33[diff] [blame]430 WrapWeakPersistent(this)));
431```
432
433Otherwise (for example, if the response callback is used to resolve a Promise),
434use `WrapPersistent(this)` to keep the object alive:
435
436``` cpp
437// src/third_party/blink/renderer/modules/nfc/nfc.cc
438ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
439...
Dave Tapuska28700f92022-09-16 14:02:31[diff] [blame]440nfc_->CancelAllWatches(WTF::BindOnce(&NFC::OnRequestCompleted,
Oksana Zhuravlova6fac3d132019-02-19 23:58:33[diff] [blame]441 WrapPersistent(this),
442 WrapPersistent(resolver)));
Oksana Zhuravlova4f3692b2019-02-08 21:00:58[diff] [blame]443```
444
445Non-garbage-collected objects can use `WTF::Unretained(this)` for both response
Oksana Zhuravlova9f3b8ef2019-08-26 20:27:40[diff] [blame]446and error handler callbacks when the `mojo::Remote` is owned by the object bound
Oksana Zhuravlova4f3692b2019-02-08 21:00:58[diff] [blame]447to the callback or the object is guaranteed to outlive the Mojo connection for
448another reason. Otherwise a weak pointer should be used. However, it is not a
449common pattern since using Oilpan is recommended for all Blink code.
450
451### Implementing Mojo interfaces in Blink
452
Oksana Zhuravlova9f3b8ef2019-08-26 20:27:40[diff] [blame]453Only a `mojo::Receiver` or `mojo::ReceiverSet` should be used when implementing a
Oksana Zhuravlova4f3692b2019-02-08 21:00:58[diff] [blame]454Mojo interface in an Oilpan-managed object. The object must then have a pre-finalizer
455to close any open pipes when the object is about to be swept as lazy sweeping
456means that it may be invalid long before the destructor is called. This requires
457setup in both the object header and implementation.
458
459``` cpp
460// MyObject.h
461class MyObject : public GarbageCollected,
462 public example::mojom::blink::Example {
463 USING_PRE_FINALIZER(MyObject, Dispose);
464
465 public:
466 MyObject();
467 void Dispose();
468
469 // Implementation of example::mojom::blink::Example.
470
471 private:
Oksana Zhuravlova9f3b8ef2019-08-26 20:27:40[diff] [blame]472 mojo::Receiver<example::mojom::blink::Example> m_receiver{this};
Oksana Zhuravlova4f3692b2019-02-08 21:00:58[diff] [blame]473};
474
475// MyObject.cpp
476void MyObject::Dispose() {
Oksana Zhuravlova9f3b8ef2019-08-26 20:27:40[diff] [blame]477 m_receiver.Close();
Oksana Zhuravlova4f3692b2019-02-08 21:00:58[diff] [blame]478}
479```
480
481For more information about Blink's Garbage Collector, see
482[Blink GC API Reference](/third_party/blink/renderer/platform/heap/BlinkGCAPIReference.md).
483
484### Typemaps For Content and Blink Types
Ken Rockotab035122019-02-06 00:35:24[diff] [blame]485
486Using typemapping for messages that go between Blink and content browser code
487can sometimes be tricky due to things like dependency cycles or confusion over
488the correct place for some definition
489to live. There are some example CLs provided here, but feel free to also contact
490[chromium-mojo@chromium.org](https://groups.google.com/a/chromium.org/forum/#!forum/chromium-mojo)
491with specific details if you encounter trouble.
492
493[This CL](https://codereview.chromium.org/2363533002) introduces a Mojom
494definition and typemap for `ui::WindowOpenDisposition` as a precursor to the
495IPC conversion below.
496
497The [follow-up CL](https://codereview.chromium.org/2363573002) uses that
498definition along with several other new typemaps (including native typemaps as
499described above) to convert the relatively large `ViewHostMsg_CreateWindow`
500message to Mojo.
501
502## Additional Support
503
504If this document was not helpful in some way, please post a message to your
505friendly
506[chromium-mojo@chromium.org](https://groups.google.com/a/chromium.org/forum/#!forum/chromium-mojo)
507mailing list.

[8]ページ先頭

©2009-2025 Movatter.jp