What is Chromium?
As described in the Chromium project's official site:
Chromium is an open-source browser project that aims to build a safer, faster, and more stable way for all users to experience the web
Technically, Chromium is the name of the project, and is not referred to in the code. The product itself is Chrome, not to be confused with Google’s browser named Google Chrome.
Over the years, the Chromium project became more than just a browser. It’s a powerful web platform that can be used in many ways to build different products (Electron, Chromecast, etc). It even became an integral part of an OS (Chromium OS).
Chromium is one of the largest codebases in the world, and it runs almost everywhere. It is developed mostly in C++, but already includes some Rust, TypeScript and more.
Basic concepts / Terminology
Before we begin, let’s set some common terms which anyone interested in Chromium must know.
One of the most commonly known facts about Chromium based browsers is that they have lots of processes. But why are they all needed?
First of all, for security reasons. If we run all of our code in the same process, exploiting one part can lead to code execution all over the browser. It’s harder to isolate threads, so the browser leverages operating system’s features and isolates processes. In Chromium, a renderer doesn’t run in the main browser’s process. Different sites will run in different renderers who have different processes. Also, different types of processes have different privileges. Some processes are sandboxed. This makes exploiting the browser much harder, as in most cases you will have to chain multiple vulnerabilities in order to gain control of the whole browser
This separation is also good for the user’s experience. As more “services” or logical components are moved out of the browser process, it is more likely to recover from errors and crashes - it might be possible to just relaunch the service seamlessly. To be as fast as it can, it uses more operating system resources.
So what kind of processes do we have? Here are some notable examples
- The browser process - The main broker of the engine. It is not sandboxed, provides capabilities via its interfaces and acts as a broker between different processes
- Frame/Tab processes - The renderer of the tab itself. In Chromium, a different renderer instance is created per frame (tab, iframe, etc), usually in its own process
- Utility/Service processes - Provide specific capabilities as a service. The network service is an example of such process, and it's responsible for, as you can guess, network operations
- Extension Processes - each extension runs in its own process
And of course there are more.
You can view your own browser’s processes by opening the browser’s task manager:
In this example, we can see a browser with 2 tabs. It has a browser process, some utility processes, a tab process for each tab and an extension process.
So we’ve got different logics in different processes, and some of them are tightly restricted. But how do they work together? If tabs are sandboxed and cannot access most of the operating system’s features, how can we listen to music or download files? It all starts with a bit of mojo.
Mojo is a platform-agnostic collection of runtime libraries, providing inter process communication primitives, a messaging format and a binding system. To make it simple, it allows components (within the same process or not) to communicate with each other over predefined messages, in different languages.
Mojo is the successor of a legacy IPC system, which barely exists as most code was migrated. Nowadays, the different components of Chromium communicate with each other almost only using Mojo. That way, when we upload a file, the renderer process asks the browser for the file’s contents - and the renderer doesn’t need to actually access the filesystem.
Mojo is relatively similar to other IPC systems, but is unique for its ability to pass object handles - such as file descriptors and file handles. It also allows validations that the browser uses for security (e.g. it doesn’t allow passing file path objects if the receiver might not have permissions to it now or later on).
Blocking/Non blocking threads
In order to maintain a fluid user experience, the browser doesn’t allow blocking/synchronous operations to run everywhere. It would be a shame if the entire UI would freeze while the browser tries to write a file, or a single tab waits for server response.
Any blocking task that runs in the browser must be marked as such, and it would usually run in a dedicated thread. Blocking APIs always validate that they run in a context that allows blocking.
In the browser process itself there are different UI and IO threads.
Extensions and applications
Chromium provides interfaces which allow third parties to extend the browser and provide non-generic features to the browser. Extensions are the most known interface, but others exist as well.
Extensions and apps should be downloaded from the official store, but can practically be downloaded and installed from anywhere else.
An extension is defined via a manifest file. In this file it declares the permissions it requires, its scripts and in which tabs to inject them, what resources it needs, some metadata and more. An extension is limited in regard to what it can and cannot access, and it must ask for specific API permissions in the manifest (e.g. - storage, bookmarks, …).
Extensions can run two types of scripts - background and content. Background scripts run in the extension’s process, have access to the chrome API and in general have more capabilities. Content scripts are injected into the requested tabs and can access them. Background and content scripts can communicate with each other and work together.
Web platform or a browser?
While for the end user Chrome is the entire product, the project is actually built as a framework and a specific implementation of it.
The framework, often referred to as the web platform or the web engine is the multi-process sandboxed browser platform itself. It includes the rendering engine, interfaces for all supported features, most of the services and components of the browser and more. Think about it as a browser library.
Chrome is the product itself, the browser built atop the web platform - the UI, implementations of platform interfaces, browser specific logics and so on. It uses the framework’s library, implements some of its interface and “makes it an app”.
While the two were separated for code health reasons, it also allowed new opportunities such as creating other products on the platform - such as Electron, Chromecast and others.
in the code, all of Chrome’s code is under src/chrome, while the platform’s code is under src/content.
Great, you’re ready to dive deep into Chromium’s internals! We’ve learned what Chromium is, covered some basic concepts and set a common ground. In future blogs, we will move on to explore various features and areas in the project. Stay tuned!