{"id":625,"date":"2020-05-11T16:46:05","date_gmt":"2020-05-11T07:46:05","guid":{"rendered":"http:\/\/blogs.igalia.com\/gyuyoung\/?p=625"},"modified":"2022-10-13T09:19:06","modified_gmt":"2022-10-13T00:19:06","slug":"how-chromium-got-its-mojo","status":"publish","type":"post","link":"https:\/\/blogs.igalia.com\/gyuyoung\/2020\/05\/11\/how-chromium-got-its-mojo\/","title":{"rendered":"How Chromium Got its Mojo?"},"content":{"rendered":"<h1>Chromium IPC<\/h1>\n<p>Chromium has a multi-process architecture to become more secure and robust like modern operating systems, and it means that Chromium has a lot of processes communicating with each other. For example, renderer process, browser process, GPU process, utility process, and so on. Those processes have been communicating using IPC [1].<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-716\" src=\"http:\/\/blogs.igalia.com\/gyuyoung\/files\/2020\/05\/chromium-arch.png\" alt=\"\" width=\"700\" height=\"649\" srcset=\"https:\/\/blogs.igalia.com\/gyuyoung\/files\/2020\/05\/chromium-arch.png 700w, https:\/\/blogs.igalia.com\/gyuyoung\/files\/2020\/05\/chromium-arch-300x278.png 300w\" sizes=\"auto, (max-width: 700px) 100vw, 700px\" \/><\/p>\n<h1>Why is Mojo needed?<\/h1>\n<p>As a long-term intent, the Chromium team wanted to refactor Chromium into a large set of smaller services. To achieve that, they had considered below questions [3]<\/p>\n<ul>\n<li><strong>Which services we bring up?<\/strong><\/li>\n<li><strong>How can we isolate these services to improve security and stability?<\/strong><\/li>\n<li><strong>Which binary features can we ship?<\/strong><\/li>\n<\/ul>\n<p>They learned much from using the legacy Chromium IPC and maintaining Chromium dependencies over the past years. They felt a more robust messaging layer could allow them to integrate a large number of components without link-time interdependencies as well as help to build more and better features, faster, and with much less cost to users. So, that&#8217;s why Chromium team begins to make the <a href=\"https:\/\/chromium.googlesource.com\/chromium\/src.git\/+\/master\/mojo\/README.md\">Mojo<\/a> communication framework.<\/p>\n<p>From the performance perspective, Mojo is 3 times faster than IPC, and \u2153 less context switching compared to the old IPC in Chrome [3]. Also, we can remove unnecessary layers like content\/renderer layer to communicate between different processes. Because combined with generated code from the Mojom IDL, we can easily connect interface clients and implementations across arbitrary inter-process boundaries. Lastly, Mojo is a collection of runtime libraries providing a platform-agnostic abstraction of common IPC primitives. So, we can build higher-level bindings APIs to simplify messaging for developers writing C++, Java, Javascript.<\/p>\n<h2>Status of migrating legacy IPC to Mojo<\/h2>\n<p>Igalia has been working on the migration since this year in earnest. But, hundreds of IPCs still remain in Chromium. The below chart shows the progress of migrating legacy IPC to Mojo [4].<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-715\" src=\"http:\/\/blogs.igalia.com\/gyuyoung\/files\/2020\/05\/mojo-conversion-status.jpg\" alt=\"\" width=\"662\" height=\"458\" srcset=\"https:\/\/blogs.igalia.com\/gyuyoung\/files\/2020\/05\/mojo-conversion-status.jpg 662w, https:\/\/blogs.igalia.com\/gyuyoung\/files\/2020\/05\/mojo-conversion-status-300x208.jpg 300w\" sizes=\"auto, (max-width: 662px) 100vw, 662px\" \/><\/p>\n<h1>Mojo Terminology<\/h1>\n<p>Let&#8217;s take a look at the key terminology before starting the migration briefly.<\/p>\n<ul>\n<li><strong>Message Pipe<\/strong>: A pair of endpoints and either endpoint may be transferred over another message pipe. Because we bootstrap a primordial message pipe between the browser process and each child process, eventually this means that a new pipe we create ultimately sends either end to any process, and the two ends will still be able to talk to each other seamlessly and exclusively. We don&#8217;t need to use routing ID anymore. Each point has a queue of incoming messages.<\/li>\n<li><strong>Mojom file<\/strong>: Define interfaces, which are strongly-typed collections of messages. Each interface message is roughly analogous to a single prototype message<\/li>\n<li><strong>Remote<\/strong>: Used to send messages described by the interface.<\/li>\n<li><strong>Receiver<\/strong>: Used to receive the interface messages sent by Remote.<\/li>\n<li><strong>PendingRemote<\/strong>: Typed container to hold the other end of a Receiver\u2019s pipe.<\/li>\n<li><strong>PendingReceiver<\/strong>: Typed container to hold the other end of a Remote\u2019s pipe.<\/li>\n<li><strong>AssociatedRemote\/Receiver<\/strong>: Similar to a Remote and a Receiver. But, they run on multiple interfaces over a single message pipe while preserving message order, because the AssociatedRemote\/Receiver was implemented by using the IPC::Channel used by legacy IPC messages.<\/li>\n<\/ul>\n<h1>Example of migrating a legacy IPC to Mojo<\/h1>\n<p>In the following example, we migrate <strong>WebTestHostMsg_SimulateWebNotificationClose<\/strong> to illustrate the conversion from legacy IPC to Mojo.<\/p>\n<h2>The existing WebTestHostMsg_SimulateWebNotificationClose IPC<\/h2>\n<ol>\n<li>Message definition<strong><strong><br \/>\n<em>File: content\/shell\/common\/web_test\/web_test_messages.h<\/em><br \/>\n<\/strong><\/strong><\/p>\n<pre><span style=\"font-weight: 400\">IPC_MESSAGE_ROUTED2(<\/span><b>WebTestHostMsg_SimulateWebNotificationClose<\/b><span style=\"font-weight: 400\">,<\/span>\n<span style=\"font-weight: 400\">                    std::string \/*title*\/,<\/span><span style=\"font-weight: 400\"> \u00a0bool \/*by_user*\/)<\/span><\/pre>\n<\/li>\n<li>Send the message in the renderer<strong><strong><strong><br \/>\n<em>File: content\/shell\/renderer\/web_test\/blink_test_runner.cc<\/em><\/strong><\/strong><\/strong><\/p>\n<pre><span style=\"font-weight: 400\">void BlinkTestRunner::<\/span><b>SimulateWebNotificationClose<\/b><span style=\"font-weight: 400\">(\n    const std::string&amp; title,<\/span><span style=\"font-weight: 400\">\u00a0bool by_user) {<\/span>\n<span style=\"font-weight: 400\"> \u00a0Send(new WebTestHostMsg_SimulateWebNotificationClose(\n    routing_id(), title,<\/span><span style=\"font-weight: 400\">\u00a0by_user));<\/span>\n<span style=\"font-weight: 400\">}<\/span><\/pre>\n<\/li>\n<li>Receive the message in the browser<strong><strong><br \/>\n<em>File: content\/shell\/browser\/web_test\/web_test_message_filter.cc<\/em><br \/>\n<\/strong><\/strong><\/p>\n<pre><span style=\"font-weight: 400\">bool WebTestMessageFilter::OnMessageReceived(\n    const IPC::Message&amp; message) {<\/span>\n<span style=\"font-weight: 400\"> \u00a0bool handled = true;<\/span>\n<span style=\"font-weight: 400\"> \u00a0IPC_BEGIN_MESSAGE_MAP(WebTestMessageFilter, message)<\/span>\n<span style=\"font-weight: 400\"> \u00a0\u00a0\u00a0IPC_MESSAGE_HANDLER(\n<\/span><b>        WebTestHostMsg_SimulateWebNotificationClose<\/b><span style=\"font-weight: 400\">,<\/span>\n<span style=\"font-weight: 400\">        OnSimulateWebNotificationClose)<\/span><\/pre>\n<\/li>\n<li>Call the handler in the browser<strong><br \/>\n<em><strong>File: content\/shell\/browser\/web_test\/web_test_message_filter.cc<\/strong><\/em><br \/>\n<\/strong><\/li>\n<\/ol>\n<pre><span style=\"font-weight: 400\">void WebTestMessageFilter::<\/span><b>OnSimulateWebNotificationClose<\/b><span style=\"font-weight: 400\">(\n    const std::string&amp; title, bool by_user) {<\/span>\n<span style=\"font-weight: 400\"> \u00a0DCHECK_CURRENTLY_ON(BrowserThread::UI);<\/span>\n<span style=\"font-weight: 400\"> \u00a0GetMockPlatformNotificationService()-&gt;\n      SimulateClose(title, by_user);<\/span>\n<span style=\"font-weight: 400\">}<\/span><\/pre>\n<h2>Call flow after migrating the legacy IPC to Mojo<\/h2>\n<p>We begin to migrate <b>WebTestHostMsg_SimulateWebNotificationClose <\/b>to<b> WebTestClient <\/b>interface from here<span style=\"color: #000000\">. First, let&#8217;s see an overall call flow through simple diagrams. [5]<\/span><\/p>\n<ol>\n<li>The WebTestClientImpl factory method is called with passing the WebTestClientImpl PendingReceiver along to the Receiver.<br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-749\" src=\"http:\/\/blogs.igalia.com\/gyuyoung\/files\/2020\/05\/call-flow-1.jpg\" alt=\"\" width=\"1363\" height=\"338\" srcset=\"https:\/\/blogs.igalia.com\/gyuyoung\/files\/2020\/05\/call-flow-1.jpg 1363w, https:\/\/blogs.igalia.com\/gyuyoung\/files\/2020\/05\/call-flow-1-300x74.jpg 300w, https:\/\/blogs.igalia.com\/gyuyoung\/files\/2020\/05\/call-flow-1-768x190.jpg 768w, https:\/\/blogs.igalia.com\/gyuyoung\/files\/2020\/05\/call-flow-1-1024x254.jpg 1024w\" sizes=\"auto, (max-width: 1363px) 100vw, 1363px\" \/><\/li>\n<li>The receiver takes ownership of the WebTestClientImpl PendingReceiver\u2019s pipe endpoint and begins to watch it for incoming messages. The pipe is readable immediately, so a task is scheduled to read the pending SimulateWebNotificationClose message from the pipe as soon as possible.<br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-748\" src=\"http:\/\/blogs.igalia.com\/gyuyoung\/files\/2020\/05\/call-flow-2.jpg\" alt=\"\" width=\"1352\" height=\"216\" srcset=\"https:\/\/blogs.igalia.com\/gyuyoung\/files\/2020\/05\/call-flow-2.jpg 1352w, https:\/\/blogs.igalia.com\/gyuyoung\/files\/2020\/05\/call-flow-2-300x48.jpg 300w, https:\/\/blogs.igalia.com\/gyuyoung\/files\/2020\/05\/call-flow-2-768x123.jpg 768w, https:\/\/blogs.igalia.com\/gyuyoung\/files\/2020\/05\/call-flow-2-1024x164.jpg 1024w\" sizes=\"auto, (max-width: 1352px) 100vw, 1352px\" \/><\/li>\n<li>The WebTestClientImpl message is read and deserialized, then, it will make the Receiver to invoke the WebTestClientImpl::SimulateWebNotificationClose() implementation on its bound WebTestClientImpl.<br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-747\" src=\"http:\/\/blogs.igalia.com\/gyuyoung\/files\/2020\/05\/call-flow-3.jpg\" alt=\"\" width=\"1371\" height=\"275\" srcset=\"https:\/\/blogs.igalia.com\/gyuyoung\/files\/2020\/05\/call-flow-3.jpg 1371w, https:\/\/blogs.igalia.com\/gyuyoung\/files\/2020\/05\/call-flow-3-300x60.jpg 300w, https:\/\/blogs.igalia.com\/gyuyoung\/files\/2020\/05\/call-flow-3-768x154.jpg 768w, https:\/\/blogs.igalia.com\/gyuyoung\/files\/2020\/05\/call-flow-3-1024x205.jpg 1024w\" sizes=\"auto, (max-width: 1371px) 100vw, 1371px\" \/><\/li>\n<\/ol>\n<h2>Migrate the legacy IPC to Mojo<\/h2>\n<ol>\n<li>Write a mojom file<br \/>\n<strong><strong><em>File: <a href=\"https:\/\/source.chromium.org\/chromium\/chromium\/src\/+\/master:content\/shell\/common\/web_test\/web_test.mojom;l=214?q=web_test.mojom&amp;ss=chromium&amp;originalUrl=https:%2F%2Fcs.chromium.org%2F\">content\/shell\/common\/web_test\/web_test.mojom<\/a><\/em><br \/>\n<\/strong><\/strong><\/p>\n<pre><span style=\"font-weight: 400\">module content.mojom;<\/span>\n\n<span style=\"font-weight: 400\">\/\/ Web test messages sent from the renderer process to the\n<\/span><span style=\"font-weight: 400\"><span style=\"color: #222222;font-family: Courier 10 Pitch, Courier, monospace\">\/\/<\/span> browser.<\/span> \n<span style=\"font-weight: 400\">interface <\/span><b>WebTestClient<\/b><span style=\"font-weight: 400\"> {<\/span>\n<span style=\"font-weight: 400\"> \u00a0\/\/ Simulates closing a titled web notification depending on the user<\/span>\n<span style=\"font-weight: 400\"> \u00a0\/\/ click.<\/span>\n<span style=\"font-weight: 400\"> \u00a0\/\/ \u00a0 - |title|: the title of the notification.<\/span>\n<span style=\"font-weight: 400\"> \u00a0\/\/ \u00a0 - |by_user|: whether the user clicks the notification.<\/span>\n<b> \u00a0SimulateWebNotificationClose(string title, bool by_user);<\/b>\n<span style=\"font-weight: 400\">};<\/span><\/pre>\n<\/li>\n<li>Add the mojom file to a proper GN target.<br \/>\n<em><strong>File: <a href=\"https:\/\/source.chromium.org\/chromium\/chromium\/src\/+\/master:content\/shell\/BUILD.gn;l=53?q=content%2Fshell%2FBUILD.gn&amp;ss=chromium&amp;originalUrl=https:%2F%2Fcs.chromium.org%2F\">content\/shell\/BUILD.gn<\/a><\/strong><\/em><\/p>\n<pre><span style=\"font-weight: 400\">mojom(\"web_test_common_mojom\") {<\/span>\n<span style=\"font-weight: 400\"> \u00a0sources = [\n<\/span><span style=\"font-weight: 400\">  \u00a0\u00a0\"common\/web_test\/fake_bluetooth_chooser.mojom\",\n<b> \u00a0\u00a0\u00a0\"common\/web_test\/web_test.mojom\",<\/b><\/span>\n<span style=\"font-weight: 400\"> \u00a0\u00a0\u00a0\"common\/web_test\/web_test_bluetooth_fake_adapter_setter.mojom\",<\/span>\n<span style=\"font-weight: 400\">  ]<\/span><\/pre>\n<\/li>\n<li>Implement the interface files<br \/>\n<strong><strong><em>File: <a href=\"https:\/\/source.chromium.org\/chromium\/chromium\/src\/+\/master:content\/shell\/browser\/web_test\/web_test_client_impl.h;l=57?q=web_test_client_impl.h&amp;ss=chromium&amp;originalUrl=https:%2F%2Fcs.chromium.org%2F\">content\/shell\/browser\/web_test\/web_test_client_impl.h<\/a><\/em><br \/>\n<\/strong><\/strong><\/p>\n<pre><span style=\"font-weight: 400\">#include \"content\/shell\/common\/web_test.mojom.h\"<\/span>\n\n<b>class WebTestClientImpl : public mojom::WebTestClient {<\/b>\n<span style=\"font-weight: 400\"> public:<\/span>\n<span style=\"font-weight: 400\"> \u00a0WebTestClientImpl() = default;<\/span>\n<span style=\"font-weight: 400\"> \u00a0~WebTestClientImpl() override = default;<\/span>\n\n<span style=\"font-weight: 400\">\u00a0\u00a0WebTestClientImpl(const WebTestClientImpl&amp;) = delete;<\/span>\n<span style=\"font-weight: 400\"> \u00a0WebTestClientImpl&amp; operator=(const WebTestClientImpl&amp;) = delete;<\/span>\n\n<span style=\"font-weight: 400\">\u00a0\u00a0static void Create(\n      mojo::PendingReceiver&lt;mojom::WebTestClient&gt; receiver);<\/span>\n<span style=\"font-weight: 400\"> private:<\/span>\n<span style=\"font-weight: 400\"> \u00a0\/\/ WebTestClient implementation.<\/span>\n<b> void SimulateWebNotificationClose(const std::string&amp; title,<\/b>\n<b> \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0bool by_user) override;<\/b>\n};<\/pre>\n<\/li>\n<li>Implement the interface files<br \/>\n<em><strong>File: <a href=\"https:\/\/source.chromium.org\/chromium\/chromium\/src\/+\/master:content\/shell\/browser\/web_test\/web_test_client_impl.cc;l=125?originalUrl=https:%2F%2Fcs.chromium.org%2F\">content\/shell\/browser\/web_test\/web_test_client_impl.cc<\/a><\/strong><\/em><\/p>\n<pre><span style=\"font-weight: 400\">void WebTestClientImpl::<\/span><b>SimulateWebNotificationClose<\/b><span style=\"font-weight: 400\">(\n    const std::string&amp; title,<\/span><span style=\"font-weight: 400\">\u00a0bool by_user) {\n<\/span> <span style=\"font-weight: 400\"> \u00a0DCHECK_CURRENTLY_ON(BrowserThread::UI);\n<\/span> <span style=\"font-weight: 400\"> \u00a0GetMockPlatformNotificationService()-&gt;\n        SimulateClose(title, by_user);\n<\/span><span style=\"font-weight: 400\">}<\/span><\/pre>\n<\/li>\n<li>Creating an interface pipe<br \/>\n<em><strong>File: <a href=\"https:\/\/source.chromium.org\/chromium\/chromium\/src\/+\/master:content\/shell\/renderer\/web_test\/blink_test_runner.h;l=219?q=blink_test_runner.h&amp;ss=chromium%2Fchromium%2Fsrc&amp;originalUrl=https:%2F%2Fcs.chromium.org%2F\">content\/shell\/renderer\/web_test\/blink_test_runner.h<\/a><\/strong><\/em><\/p>\n<pre>mojo::AssociatedRemote&lt;mojom::WebTestClient&gt;&amp;\n    <span style=\"font-weight: 400\"><strong>GetWebTestClientRemote()<\/strong>;\n<\/span>mojo::AssociatedRemote&lt;mojom::WebTestClient&gt;\n    <span style=\"font-weight: 400\"><strong>web_test_client_remote_<\/strong>;<\/span><\/pre>\n<p><strong><em>File: <a href=\"https:\/\/source.chromium.org\/chromium\/chromium\/src\/+\/master:content\/shell\/renderer\/web_test\/blink_test_runner.cc;l=497?originalUrl=https:%2F%2Fcs.chromium.org%2F\">content\/shell\/renderer\/web_test\/blink_test_runner.cc<\/a><\/em><br \/>\n<\/strong><\/p>\n<pre><span style=\"font-weight: 400\">mojo::AssociatedRemote&lt;mojom::WebTestClient&gt;&amp;\n<\/span><span style=\"font-weight: 400\">BlinkTestRunner::<\/span><b>GetWebTestClientRemote<\/b><span style=\"font-weight: 400\">() {\n<\/span> <span style=\"font-weight: 400\"> if (!web_test_client_remote_) {\n<\/span> <span style=\"font-weight: 400\"> \u00a0\u00a0\u00a0RenderThread::Get()-&gt;GetChannel()-&gt;\n<\/span><b>        GetRemoteAssociatedInterface<\/b><span style=\"font-weight: 400\">(<\/span><span style=\"font-weight: 400\">&amp;web_test_client_remote_);\n<\/span> <span style=\"font-weight: 400\"> \u00a0\u00a0\u00a0web_test_client_remote_.set_disconnect_handler(\n<\/span> <span style=\"font-weight: 400\"> \u00a0\u00a0\u00a0\u00a0\u00a0 base::BindOnce( \n           &amp;BlinkTestRunner::HandleWebTestClientDisconnected,\n<\/span> <span style=\"font-weight: 400\"> \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0base::Unretained(this)));\n<\/span> <span style=\"font-weight: 400\"> \u00a0}\n<\/span> <span style=\"font-weight: 400\"> \u00a0return web_test_client_remote_;\n<\/span><span style=\"font-weight: 400\">}<\/span><\/pre>\n<\/li>\n<li>Register the WebTest interface<br \/>\n<em><strong> File: <a href=\"https:\/\/source.chromium.org\/chromium\/chromium\/src\/+\/master:content\/shell\/browser\/web_test\/web_test_content_browser_client.cc;l=244?q=web_test_content_browser_client.cc&amp;ss=chromium%2Fchromium%2Fsrc&amp;originalUrl=https:%2F%2Fcs.chromium.org%2F\">content\/shell\/browser\/web_test\/web_test_content_browser_client.cc<\/a><\/strong><\/em><\/p>\n<pre><span style=\"font-weight: 400\">void WebTestContentBrowserClient::<\/span><b>ExposeInterfacesToRenderer<\/b><span style=\"font-weight: 400\"> {\n<\/span> <span style=\"font-weight: 400\"> \u00a0...\n<\/span> <span style=\"font-weight: 400\"> \u00a0associated_registry-&gt;AddInterface(base::BindRepeating(\n<\/span> <span style=\"font-weight: 400\"> \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&amp;WebTestContentBrowserClient::BindWebTestController,\n<\/span> <span style=\"font-weight: 400\"> \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0render_process_host-&gt;GetID(),\n<\/span> <span style=\"font-weight: 400\"> \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0BrowserContext::GetDefaultStoragePartition(\n               browser_context())));\n<\/span> <span style=\"font-weight: 400\">}\n<\/span> <span style=\"font-weight: 400\">void WebTestContentBrowserClient::<\/span><b>BindWebTestController<\/b><span style=\"font-weight: 400\">(\n<\/span> <span style=\"font-weight: 400\"> \u00a0\u00a0\u00a0int render_process_id,\n<\/span> <span style=\"font-weight: 400\"> \u00a0\u00a0\u00a0StoragePartition* partition,\n<\/span> <span style=\"font-weight: 400\"> \u00a0\u00a0\u00a0mojo::PendingAssociatedReceiver&lt;mojom::WebTestClient&gt;\n           receiver) {\n<\/span> <b> \u00a0WebTestClientImpl::Create<\/b><span style=\"font-weight: 400\">(render_process_id,\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/span><span style=\"font-weight: 400\">\u00a0\u00a0\u00a0partition-&gt;GetQuotaManager(),\n<\/span> <span style=\"font-weight: 400\"> \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0\u00a0partition-&gt;GetDatabaseTracker(),\n<\/span> <span style=\"font-weight: 400\"> \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0partition-&gt;GetNetworkContext(),\n<\/span> <span style=\"font-weight: 400\"> \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0std::move(receiver));\n<\/span> <span style=\"font-weight: 400\">} <\/span><\/pre>\n<\/li>\n<li>Call an interface message in the renderer<br \/>\n<em><b><strong>File: <\/strong><a href=\"https:\/\/source.chromium.org\/chromium\/chromium\/src\/+\/master:content\/shell\/renderer\/web_test\/blink_test_runner.cc;l=163?q=blink_test_runner.cc&amp;ss=chromium%2Fchromium%2Fsrc&amp;originalUrl=https:%2F%2Fcs.chromium.org%2F\">content\/shell\/renderer\/web_test\/blink_test_runner.cc<\/a><\/b><\/em><\/p>\n<pre>void BlinkTestRunner::<strong>SimulateWebNotificationClose<\/strong>(\n const std::string&amp; title, bool by_user) {\n GetWebTestClientRemote()-&gt;\n     SimulateWebNotificationClose(title, by_user);\n}<\/pre>\n<\/li>\n<li>Receive the incoming message in the browser<br \/>\n<em><strong>File: <a href=\"https:\/\/source.chromium.org\/chromium\/chromium\/src\/+\/master:content\/shell\/browser\/web_test\/web_test_client_impl.cc;l=125?q=web_test_client_impl.cc&amp;ss=chromium%2Fchromium%2Fsrc&amp;originalUrl=https:%2F%2Fcs.chromium.org%2F\">content\/shell\/browser\/web_test\/web_test_client_impl.cc<\/a><\/strong><\/em><\/p>\n<pre>void WebTestClientImpl::<strong>SimulateWebNotificationClose<\/strong>(\n const std::string&amp; title, bool by_user) {\n DCHECK_CURRENTLY_ON(BrowserThread::UI);\n GetMockPlatformNotificationService()-&gt;\n     SimulateClose(title, by_user);\n}<\/pre>\n<\/li>\n<\/ol>\n<h2><\/h2>\n<h2>Appendix: A case study of Regression<\/h2>\n<ul>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Chromium Bug: <\/span><a href=\"https:\/\/bugs.chromium.org\/p\/chromium\/issues\/detail?id=1060175\"><span style=\"font-weight: 400\">Issue 10075: Hundreds of blink_web_tests are flaky<\/span><\/a><\/li>\n<\/ul>\n<p>There were a lot of flaky web test failures after finishing the migration of <span style=\"font-weight: 400\">WebTestHostMsg to Mojo. The failures were caused by using &#8216;Remote&#8217; instead of &#8216;AssociatedRemote&#8217; for <strong>WebTestClient<\/strong> interface in the BlinkTestRunner class. Because BlinkTestRunner was using the <strong>WebTestControlHost<\/strong> interface for &#8216;PrintMessage&#8217; as an &#8216;AssociatedRemote&#8217;. But, &#8216;Remote&#8217; used by <strong>WebTestClient<\/strong> didn&#8217;t guarantee the message order between &#8216;PrintMessage&#8217; and &#8216;InitiateCaptureDump&#8217; message implemented by different interfaces(<strong>WebTestControlHost vs. WebTestClient<\/strong>). Thus, tests had often finished before receiving all logs. The actual results could be different from the expected results.<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-746\" src=\"http:\/\/blogs.igalia.com\/gyuyoung\/files\/2020\/05\/regression.jpg\" alt=\"\" width=\"982\" height=\"248\" srcset=\"https:\/\/blogs.igalia.com\/gyuyoung\/files\/2020\/05\/regression.jpg 982w, https:\/\/blogs.igalia.com\/gyuyoung\/files\/2020\/05\/regression-300x76.jpg 300w, https:\/\/blogs.igalia.com\/gyuyoung\/files\/2020\/05\/regression-768x194.jpg 768w\" sizes=\"auto, (max-width: 982px) 100vw, 982px\" \/><\/p>\n<p><span style=\"font-weight: 400\">Changing <strong>Remote<\/strong> with <strong>AssociatedRemote<\/strong> for the WebTestClient interface solved the flaky test issues.<\/span><\/p>\n<hr \/>\n<p>[1] <a href=\"https:\/\/www.chromium.org\/developers\/design-documents\/inter-process-communication\"><span id=\"sites-page-title\" dir=\"ltr\">Inter-process Communication (IPC)<\/span><\/a><br \/>\n[2] <a href=\"https:\/\/chromium.googlesource.com\/chromium\/src.git\/+\/51.0.2704.48\/docs\/mojo_in_chromium.md\">Mojo in Chromium<\/a><br \/>\n[3] <a href=\"https:\/\/docs.google.com\/document\/d\/1n7qYjQ5iy8xAkQVMYGqjIy_AXu2_JJtMoAcOOupO_jQ\/edit\">Mojo &amp; Servicification Performance Notes<\/a><br \/>\n[4] <a href=\"https:\/\/groups.google.com\/a\/chromium.org\/d\/msg\/chromium-mojo\/KBSXCmeA29Q\/mzpNJUIcEwAJ\">Chrome IPC legacy Conversion Status<\/a><br \/>\n[5] <a href=\"https:\/\/chromium.googlesource.com\/chromium\/src.git\/+\/master\/docs\/mojo_ipc_conversion.md\">Convert Legacy IPC to Mojo<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Chromium IPC Chromium has a multi-process architecture to become more secure and robust like modern operating systems, and it means that Chromium has a lot of processes communicating with each other. For example, renderer process, browser process, GPU process, utility process, and so on. Those processes have been communicating using IPC [1]. Why is Mojo [&hellip;]<\/p>\n","protected":false},"author":52,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1,3],"tags":[4,15,14],"class_list":["post-625","post","type-post","status-publish","format-standard","hentry","category-igalia-chromium","category-igalia-planet","tag-chromium","tag-ipc","tag-mojo"],"_links":{"self":[{"href":"https:\/\/blogs.igalia.com\/gyuyoung\/wp-json\/wp\/v2\/posts\/625","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blogs.igalia.com\/gyuyoung\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.igalia.com\/gyuyoung\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.igalia.com\/gyuyoung\/wp-json\/wp\/v2\/users\/52"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.igalia.com\/gyuyoung\/wp-json\/wp\/v2\/comments?post=625"}],"version-history":[{"count":113,"href":"https:\/\/blogs.igalia.com\/gyuyoung\/wp-json\/wp\/v2\/posts\/625\/revisions"}],"predecessor-version":[{"id":820,"href":"https:\/\/blogs.igalia.com\/gyuyoung\/wp-json\/wp\/v2\/posts\/625\/revisions\/820"}],"wp:attachment":[{"href":"https:\/\/blogs.igalia.com\/gyuyoung\/wp-json\/wp\/v2\/media?parent=625"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.igalia.com\/gyuyoung\/wp-json\/wp\/v2\/categories?post=625"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.igalia.com\/gyuyoung\/wp-json\/wp\/v2\/tags?post=625"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}