# Design

This document contains a high-level technical description of ungoogled-chromium and its components.

## Overview

ungoogled-chromium consists of the following major components:

* [Configuration](#configuration)
    * [Configuration files](#configuration-files)
    * [Source file processors](#source-file-processors)
    * [Patches](#patches)
* [Packaging](#packaging)

The following sections describe each component.

## Configuration

Configuration is a broad term that refers to patches, build flags, and metadata about Chromium source code. It consists of the following components:

* [Configuration files](#configuration-files)
* [Source file processors](#source-file-processors)
* [Patches](#patches)

The following sections describe each component in more depth.

### Configuration Files

Configuration files (or config files) are files that store build configuration and source code changes for a build.

**IMPORTANT**: For consistency, all config files must be encoded in UTF-8.

List of configuration files:

* `chromium_version.txt` - The Chromium version used by ungoogled-chromium
* `revision.txt` - The revision of the changes on top of the given Chromium version.
* `pruning.list` - [See the Source File Processors section](#source-file-processors)
* `domain_regex.list` - [See the Source File Processors section](#source-file-processors)
* `domain_substitution.list` - [See the Source File Processors section](#source-file-processors)
* `downloads.ini` - Archives to download and unpack into the buildspace tree. This includes code not bundled in the Chromium source code archive that is specific to a non-Linux platform. On platforms such as macOS, this also includes a pre-built LLVM toolchain for convenience (which can be removed and built from source if desired).
* `flags.gn` - GN arguments to set before building.

### Source File Processors

Source file processors are utilities that directly manipulate the Chromium source tree before building. Currently, there are two such utilities: binary pruning, and domain substitution.

**Binary Pruning**: Strips binaries from the source code. This includes pre-built executables, shared libraries, and other forms of machine code. Most are substituted with system or user-provided equivalents, or are built from source; those binaries that cannot be removed do not contain machine code.

The list of files to remove are determined by the config file `pruning.list`. This config file is generated by `devutils/update_lists.py`.

**Domain Substitution**: Replaces Google and several other web domain names in the Chromium source code with non-existent alternatives ending in `qjz9zk`. These changes are mainly used as a backup measure to detect potentially unpatched requests to Google. Note that domain substitution is a crude process, and *may not be easily undone*.

With a few patches from ungoogled-chromium, any requests with these domain names sent via `net::URLRequest` in the Chromium code are blocked and notify the user via a info bar.

Similar to binary pruning, the list of files to modify are listed in `domain_substitution.list`; it is also updated with `devutils/update_lists.py`.

The regular expressions to use are listed in `domain_regex.list`; the search and replacement expressions are delimited with a pound (`#`) symbol. The restrictions for the entries are as follows:
* All replacement expressions must end in the TLD `qjz9zk`.
* The search and replacement expressions must have a one-to-one correspondence: no two search expressions can match the same string, and no two replacement expressions can result in the same string.

### Patches

All of ungoogled-chromium's patches for the Chromium source code are located in `patches/`. This directory conforms to the default GNU Quilt format. That is:

* All patches must reside inside `patches/`
* There is a `patches/series` text file that defines the order to apply all the patches. These patches are listed as a relative path from the `patches` directory.
    * Lines starting with the pound symbol (`#`) are ignored
    * For lines with patch paths: If there is a space followed by a pound symbol, the text after the patch path will be ignored.

All patch files in ungoogled-chromium must satisfy these formatting requirements:

* Patch filenames must end with the extension `.patch`
* The content must be in [unified format](https://en.wikipedia.org/wiki/Diff_utility#Unified_format).
* All paths in the hunk headers must begin after the first slash (which corresponds to the argument `-p1` for GNU patch).
* All patches must apply cleanly (i.e. no fuzz).
* It is recommended that hunk paths have the `a/` and `b/` prefixes, and a context of 3 (like the git default).
* All patches must be encoded in UTF-8 (i.e. same encoding as config files).

Patches are categorized into two directories directly under `patches/`:

1. **core**: Changes regarding background requests, code specific to Google web services, or code using pre-made binaries. They must be kept up-to-date with all of the changes in Chromium.
2. **extra**: Changes to features regarding control and transparency. They are not guaranteed to persist across updates to Chromium.

Within each category, patches are grouped by the following:

* `debian/` - Patches from Debian's Chromium
    * Patches are not modified unless they conflict with Inox's patches
    * These patches are not Debian-specific. For those, see the `debian/patches` directory
* `inox-patchset/` - Contains a modified subset of patches from Inox patchset.
    * Some patches such as those that change branding are omitted
    * Patches are not modified unless they do not apply cleanly onto the version of Chromium being built
    * Patches are from [inox-patchset's GitHub](https://github.com/gcarq/inox-patchset)
    * [Inox patchset's license](https://github.com/gcarq/inox-patchset/blob/master/LICENSE)
* `bromite/` - Patches from [Bromite](https://github.com/bromite/bromite)
* `iridium-browser/` - Contains a modified subset of patches from Iridium Browser.
    * Some patches such as those that change branding or URLs to point to Iridium's own servers are omitted
    * Patches are not modified unless they conflict with Debian's or Inox's patches
    * Patches are from the `patchview` branch of Iridium's Git repository. [Git webview of the patchview branch](https://git.iridiumbrowser.de/cgit.cgi/iridium-browser/?h=patchview)
* `opensuse/` - Patches from openSUSE's Chromium
* `ubuntu/` -  Patches from Ubuntu's Chromium
* `ungoogled-chromium/` - Patches by ungoogled-chromium developers

## Packaging

Packaging is the process of downloading, building, and producing a distributable package of ungoogled-chromium.

Packaging files use the code from this repository to build ungoogled-chromium. Each platform and configuration has an associated packaging repository under the [ungoogled-software](https://github.com/ungoogled-software) organization. For more information about each packaging repository, see the [building documentation](building.md).

Packaging generally consists of the major steps:

1. Download and unpack the source tree
2. Prune binaries
3. Apply patches
4. Substitute domains
5. Build GN via `tools/gn/bootstrap/bootstrap.py`
6. Run `gn gen` with the GN flags
7. Build Chromium via `ninja`
8. Create package(s) of build output (usually in `out/Default`)
