-
Notifications
You must be signed in to change notification settings - Fork 29
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add IPC documentation #97
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,6 +21,91 @@ and it does not have direct access to the underlying operating system’s [clipb | |
microphone, or video camera even though there are Web APIs that grant access to those features. | ||
Instead, UI process brokers such requests. | ||
|
||
FIXME: How is IPC setup | ||
## How is IPC Setup | ||
|
||
FIXME: How to add / modify an IPC message | ||
In WebKit, Inter-Process Communication (IPC) enables communication between different processes. The IPC setup in WebKit involves several key components: | ||
|
||
### Message Definitions | ||
|
||
Messages are defined in `*.messages.in` files (e.g., `WebPage.messages.in`). These files specify the structure and types of messages exchanged between processes. Each `*.messages.in` file must map to a header file with the same name (e.g., `WebPage.messages.in` maps to `WebPage.h`). These `*.messages.in` files are processed at build time to generate source code for receiving IPC messages. They support both synchronous and asynchronous messages. | ||
|
||
### Message Handlers | ||
|
||
Each process has message handlers that process incoming messages and perform the necessary actions. The message definitions in the `*.messages.in` file need to have corresponding implementations in the related class (e.g., `WebPage` implements handlers for the corresponding messages defined in `WebPage.messages.in`). The processing of the `*.messages.in` files during build time generates source code that maps a message definition to its corresponding handler implementation, which will automatically call it for you when that message is received. The message handlers must adhere to the correct function signatures specified in the `*.messages.in` files, otherwise you will get a build error. | ||
|
||
### IPC::MessageSender and IPC::MessageReceiver | ||
|
||
Classes that send or receive IPC messages typically inherit from `IPC::MessageSender` and `IPC::MessageReceiver`. These base classes automatically handle the serialization and deserialization of messages, as well as the setup of message dispatching. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. MessageSender should not be used in general, so it should not be documented. |
||
|
||
For a deeper dive, you can found WebKit's IPC code in the `Source/WebKit/Platform/IPC` directory. This directory contains the classes and utilities needed to manage IPC, including message sending and receiving, connection management, and the serialization and deserialization of messages. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This probably could be rewritten and moved to either to the beginning or to the end. |
||
|
||
## How to Add or Modify an IPC Message | ||
|
||
Adding or modifying an IPC message in WebKit involves several steps to ensure proper communication between classes in different processes. Here is a step-by-step guide: | ||
|
||
### 1. Define the Message | ||
|
||
Locate the appropriate `*.messages.in` file (e.g., `WebPage.messages.in`). If a new message file is needed, it should be placed in the same directory as the class you are implementing it for and it should also be added to the directory's `Sources.txt` file, as mentioned [here](../Build/AddingNewFile.html). | ||
Now, define the new message in this file. For example, let's say we want to send a message called `LoadURL` from the UI process' `WebPageProxy` class to the WebContent process' `WebPage` class. In `WebPage.messages.in`, you would add an entry like: | ||
|
||
``` | ||
LoadURL(String url) | ||
``` | ||
|
||
### 2. Implement the Message Handler | ||
|
||
In the class that will receive the message (e.g., `WebPage`), implement the handler method. This method will be called when the message is received. For example: | ||
|
||
``` | ||
void WebPage::loadURL(const String& url) { | ||
// Implementation code to load the URL | ||
} | ||
``` | ||
|
||
### 3. Send the Message | ||
|
||
To send the message from another process, use the `send` method of the `IPC::MessageSender` class. For example, to send the `LoadURL` message from the UI process' `WebPageProxy` class to the WebContent's `WebPage` class: | ||
|
||
``` | ||
send(Messages::WebPage::LoadURL(url)); | ||
``` | ||
|
||
Note, `WebPageProxy` inherits from `IPC::MessageSender`, which is what makes this possible. | ||
|
||
## Replying to Messages | ||
|
||
In addition to sending messages, WebKit's IPC mechanism supports replying to messages, which can be done synchronously or asynchronously. | ||
|
||
### 1. Define the Message Reply | ||
|
||
In the definition of the message in the `*.messages.in` file, specify that it expects a reply. For example, in `WebPage.messages.in`: | ||
|
||
``` | ||
GetTitle() -> (String title) | ||
``` | ||
|
||
By default, the reply is handled asynchronously. In order to make it synchronous, add `Synchronous` after the message definition, for example: | ||
|
||
``` | ||
GetTitle() -> (String title) Synchronous | ||
``` | ||
|
||
### 2. Implement the Message Handler with Reply | ||
|
||
Implement the handler method in the receiving class that will process the message and send a reply. For example, in the WebContent process' `WebPage.h`: | ||
|
||
``` | ||
void WebPage::getTitle(CompletionHandler<void(String)>&& completionHandler) { | ||
completionHandler(m_title); | ||
} | ||
``` | ||
|
||
### 3. Send the Asynchronous Message and Handle Reply | ||
|
||
To send the asynchronous message and handle the reply, use the `sendWithAsyncReply` method of the `IPC::MessageSender` class. For example, in the UI process' `WebPageProxy.cpp`: | ||
|
||
``` | ||
sendWithAsyncReply(Messages::WebPage::GetTitle(), [this, weakThis = WeakPtr { *this }](String title) { | ||
// do something with title... | ||
}); | ||
``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be better to pick some other interface than WebPage, WebPageProxy. They're the most complex of the classes, and also use the MessageSender, which is not advised.
There's no good examples, but IPCTester should be a simple one perhaps.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I liked WebPage and WebPageProxy because I could use simple message examples like
LoadURL
that represent how APIs in the UI process (like WKWebView) control and interact with actual web processes. However, I understand the issue with MessageSender. I dont know if IPCTester is the best example, because its not clear where it gets its IPC::Connection object from - also, I would like to use an example class that is actually used for IPC in WebKit.I dug around and found RemoteAudioSessionProxy - it inherits from MessageReceiver and owns an IPC::Connection object to send messages, is this the correct semantics? If so, Ill try to find another similar class that isnt so "niche" as RemoteAudioSessionProxy that uses the same semantics, but if not, ill just use it.
If this example still isnt good, and there is no other option, Ill use IPCTester as you mentioned, but ill need to figure out how to explain how its using IPC::Connection