 So yeah, we're going to talk about Chrome IPC. I assume many people here took the anatomy of a browser talk earlier today. So you're familiar with the multiprocess architecture in general, kind of how we send box processes and why we do it. So IPC is obviously inter-process communication. That's how the processes talk to each other. That system that we have in Chrome is called Mojo. We're going to talk about that. We do have slides at a go link up there. Go slash Chrome IPC 101 slides with hyphens. If you want to follow along or save it for later, it might be just a nice read to put you to sleep later tonight or something like that. Oh, right, I have a clicker. And so this is a basic practical, really simple example of using IPC. Funny enough, after we put this together, I discovered that the battery API is deprecated, but whatever. There isn't a simpler API to talk about, so we're going to talk about that. And so the basic flow of events here is the renderer. It calls navigator.getBattery. Oh wait, next slide, right. It makes a web API call, sends a request to the browser. Browser does some privileged work, sends a response back, render shows you your battery status. That's a real website. It's really cool. OK, so the render code looks like this. It's just some JavaScript navigator.getBattery as a promise, so it's asynchronous work. We want to talk about kind of how the renderer implements this API using IPC, how it gets the response back, and we're just going to dive into that. So this is the very high level look at things. The message format, we use a slightly different. That's a slight simplification, but the basic idea is it's not much more complicated than this, right? There's some message which describes this request. The renderer sends it to the browser over some channel which is dedicated to this feature. The browser sends a response back eventually, or maybe never, and then the renderer can continue on with its work. And so Mojo, this is where Mojo comes in. Mojo has an interface definition language which we use to describe messages and data structures. This is similar to Protobuf, if anyone's familiar with Protobuf. It is different for various reasons. But this is the basic format. So we can describe interfaces which are just collections of related messages, kind of like a class interface that has a collection of related methods. Messages can have responses. That's what we're showing here with the query status message. Renderer sends query status. Browser responds with a battery status structure. The structure is described by the Mojom file format. This file format is used at build time in Chrome to generate C++ code, JavaScript code, Java code. In the future, it's likely we'll probably have rust bindings, maybe other languages, not promising anything, but the main reason we have this idea though is so that we can generate bindings for different languages because we wanna talk from JavaScript to Java or to C++ or whatever. And so Mojo C++ code has these two very important primary types that you use with Mojo called a remote and a receiver. The remote sends messages to a receiver. The receiver receives messages and invokes corresponding methods on an implementation of the interface. So a remote is a way of talking to a remote implementation of an interface. And the Mojo message pipe is the primitive that kind of joins these things together and allows the remotes to send messages to the receiver. The receiver to send replies back to the remote. Conveniently, there was just a talk on the task scheduler. And so people are probably familiar with binding callbacks and doing asynchronous work. The way this works with Mojo is the render has this remote object. It calls query status and we didn't show it here because we weren't really sure whether or not anyone would know what a callback was. The query status call passes the callback and when the reply comes back, the callback is executed. So just like any asynchronous work in Chrome like post task and reply kind of thing. And so at this point, the native code, once it gets reply, it would then resolve the promise in JavaScript and you'd have your battery status information in the browser. Yay. And just for a detailed look at what this looks like, this is the flow kind of end to end from the remote back to the callback, back to the promise resolution. And so we have the call on the remote which results in the message being serialized. This gets written to a message pipe to the browser where it's read out, deserialized, pass to a receiver, which calls the method on the implementation. It goes to the operating system, gets the battery status information, whatever, however long that takes, it eventually invokes the callback to respond. And then we have the same flow back in the opposite direction to where the render results the promise. From a user's perspective, you really just have a remote on one side and an implementation with a receiver on the other side and you can just kind of call methods in it, magically works. And with that, Oksana is gonna talk more about the code that we generate from Mojom and how this is implemented in the browser and along with that some security concepts. Thank you Ken. So as Ken just mentioned, we get C++ code generated from the IDL files at build time. And this, among other things, this generated class has query status method. It's pure virtual, which means all implementations must override it. And the Mojom file has the return value and the way we handle it in C++ is that we pass this value to the callback and the callback runs in the renderer. So the browser code can implement the interface by inheriting a class from the generated battery monitor. And here is what it has and what it does. It overrides the query status method and we'll look at the implementation in just a second. Then it also has a receiver object which handles the communication with the renderer and translates incoming messages into method calls. And finally it knows how to connect this receiver to the pipe. We will not get into details here, but a common pattern is to do it in a constructor. So here is a possible implementation of the query status method. We create an instance of the battery status structure. We set the charging and level fields and then we pass it to the callback. At this point we're done, that's it. We have all the pieces in place that we need to get the battery status from the OS to the webpage. It's not exact chromium code and since it's deprecated, it might disappear soon. But it's pretty similar, it's pretty close. So working code is great, but how do we make sure the communication is secure? So let's switch to a different example where a renderer sends data to the browser. How about creating an interface to add bookmarks? It can have just a single method at bookmark. If this method takes a string as a URL, it's possible for the renderer to potentially pass some data that triggers vulnerabilities in the browser. So in such cases, it's safer to use provided modem URL type because it has built-in validation. The message is only considered deserialized if it's valid and only then module will involve the implementation. Otherwise it signals an error and closes the pipe. You can also, so the browser implementation can be sure it always is called with a valid URL. It's easy to plug in your own validation as well or your own types. So message validation is one way to make IPC more secure. We use some other approaches as well. So only the browser process is trusted by default. And if one part of Chrome wants to communicate with another part of Chrome, the browser handles this. Also any changes to the modem files need to pass a security review, which means someone from security team needs to approve them and pre-submit checks and commit queue, make sure it happens. Okay, so we have looked at some very simple examples and just covered the basics. So I'd like to leave you with some resources you can use to learn more and be productive. So go slash modem-docs and go slash modem-basics point to pages in the modem source directory. Modem services section in the top level docs has some related links. If you have any questions, please don't hesitate to reach out. Follow go slash modem-slack to join our dedicated Slack channel in the Chromium workspace or email chromium-modem at chromium.org. And finally, did you know that cs.... Sorry, code search, which is located at cs.chromium.org also indexes modem files? Well, now you do. Special thanks to Daniel Murphy for helping the talk and thank you so much for your attention.