summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--static/build.html1614
1 files changed, 807 insertions, 807 deletions
diff --git a/static/build.html b/static/build.html
index 11c7bb94..97bb9c2f 100644
--- a/static/build.html
+++ b/static/build.html
@@ -121,443 +121,442 @@
</ul>
</nav>
- <h2 id="building-grapheneos">
- <a href="#building-grapheneos">Building GrapheneOS</a>
- </h2>
+ <section id="building-grapheneos">
+ <h2><a href="#building-grapheneos">Building GrapheneOS</a></h2>
- <h3 id="build-targets">
- <a href="#build-targets">Build targets</a>
- </h3>
+ <h3 id="build-targets">
+ <a href="#build-targets">Build targets</a>
+ </h3>
- <p>Smartphone targets:</p>
+ <p>Smartphone targets:</p>
- <ul>
- <li>aosp_taimen (Pixel 2 XL) - obsolete</li>
- <li>aosp_walleye (Pixel 2) - obsolete</li>
- <li>aosp_crosshatch (Pixel 3 XL)</li>
- <li>aosp_blueline (Pixel 3)</li>
- <li>aosp_bonito (Pixel 3a XL)</li>
- <li>aosp_sargo (Pixel 3a)</li>
- <li>aosp_coral (Pixel 4 XL)</li>
- <li>aosp_flame (Pixel 4)</li>
- <li>aosp_sunfish (Pixel 4a)</li>
- </ul>
+ <ul>
+ <li>aosp_taimen (Pixel 2 XL) - obsolete</li>
+ <li>aosp_walleye (Pixel 2) - obsolete</li>
+ <li>aosp_crosshatch (Pixel 3 XL)</li>
+ <li>aosp_blueline (Pixel 3)</li>
+ <li>aosp_bonito (Pixel 3a XL)</li>
+ <li>aosp_sargo (Pixel 3a)</li>
+ <li>aosp_coral (Pixel 4 XL)</li>
+ <li>aosp_flame (Pixel 4)</li>
+ <li>aosp_sunfish (Pixel 4a)</li>
+ </ul>
- <p>These are all fully supported production-ready targets supporting all the baseline
- security features and receiving full monthly security updates covering all firmware,
- kernel drivers, driver libraries / services and other device-specific code. A fully
- signed user build for these devices is a proper GrapheneOS release. Newer generation
- devices have stronger hardware / firmware security and hardware-based OS security
- features and are better development devices for that reason. It's not possible to work
- on everything via past generation devices. The best development devices are the Pixel
- 3, Pixel 3 XL, Pixel 3a, Pixel 3a XL, Pixel 4, Pixel 4 XL and Pixel 4a.</p>
+ <p>These are all fully supported production-ready targets supporting all the baseline
+ security features and receiving full monthly security updates covering all firmware,
+ kernel drivers, driver libraries / services and other device-specific code. A fully
+ signed user build for these devices is a proper GrapheneOS release. Newer generation
+ devices have stronger hardware / firmware security and hardware-based OS security
+ features and are better development devices for that reason. It's not possible to work
+ on everything via past generation devices. The best development devices are the Pixel
+ 3, Pixel 3 XL, Pixel 3a, Pixel 3a XL, Pixel 4, Pixel 4 XL and Pixel 4a.</p>
- <p>Generic targets:</p>
+ <p>Generic targets:</p>
- <ul>
- <li>aosp_arm</li>
- <li>aosp_arm64</li>
- <li>aosp_mips</li>
- <li>aosp_mips64</li>
- <li>aosp_x86</li>
- <li>aosp_x86_64</li>
- </ul>
+ <ul>
+ <li>aosp_arm</li>
+ <li>aosp_arm64</li>
+ <li>aosp_mips</li>
+ <li>aosp_mips64</li>
+ <li>aosp_x86</li>
+ <li>aosp_x86_64</li>
+ </ul>
- <p>These generic targets can be used with the emulator along with many smartphones,
- tablets and other devices. These targets don't receive full monthly security updates,
- don't offer all of the baseline security features and are intended for development
- usage.</p>
+ <p>These generic targets can be used with the emulator along with many smartphones,
+ tablets and other devices. These targets don't receive full monthly security updates,
+ don't offer all of the baseline security features and are intended for development
+ usage.</p>
- <p>Providing proper support for a device or generic device family requires providing
- an up-to-date kernel and device support code including driver libraries, firmware and
- device SELinux policy extensions. Other than some special cases like the emulator, the
- generic targets rely on the device support code present on the device. Shipping all of
- this is necessary for full security updates and is tied to enabling verified boot /
- attestation. Pixel targets have a lot of device-specific hardening in the AOSP base
- along with some in GrapheneOS which needs to be ported over too. For example, various
- security features in the kernel including type-based Control Flow Integrity (CFI) and
- the shadow call stack are currently specific to the kernels for these devices.</p>
+ <p>Providing proper support for a device or generic device family requires providing
+ an up-to-date kernel and device support code including driver libraries, firmware and
+ device SELinux policy extensions. Other than some special cases like the emulator, the
+ generic targets rely on the device support code present on the device. Shipping all of
+ this is necessary for full security updates and is tied to enabling verified boot /
+ attestation. Pixel targets have a lot of device-specific hardening in the AOSP base
+ along with some in GrapheneOS which needs to be ported over too. For example, various
+ security features in the kernel including type-based Control Flow Integrity (CFI) and
+ the shadow call stack are currently specific to the kernels for these devices.</p>
- <p>SDK emulator targets:</p>
+ <p>SDK emulator targets:</p>
- <ul>
- <li>sdk_phone_armv7</li>
- <li>sdk_phone_arm64</li>
- <li>sdk_phone_mips</li>
- <li>sdk_phone_mips64</li>
- <li>sdk_phone_x86</li>
- <li>sdk_phone_x86_64</li>
- </ul>
+ <ul>
+ <li>sdk_phone_armv7</li>
+ <li>sdk_phone_arm64</li>
+ <li>sdk_phone_mips</li>
+ <li>sdk_phone_mips64</li>
+ <li>sdk_phone_x86</li>
+ <li>sdk_phone_x86_64</li>
+ </ul>
- <p>These are extended versions of the generic targets with extra components for the
- SDK. These targets don't receive full monthly security updates, don't provide all of
- the baseline security features and are intended for development usage.</p>
+ <p>These are extended versions of the generic targets with extra components for the
+ SDK. These targets don't receive full monthly security updates, don't provide all of
+ the baseline security features and are intended for development usage.</p>
- <h3 id="build-dependencies">
- <a href="#build-dependencies">Build dependencies</a>
- </h3>
+ <h3 id="build-dependencies">
+ <a href="#build-dependencies">Build dependencies</a>
+ </h3>
- <p>Arch Linux, Debian buster and Ubuntu 20.04 LTS are the officially supported
- operating systems for building GrapheneOS.</p>
+ <p>Arch Linux, Debian buster and Ubuntu 20.04 LTS are the officially supported
+ operating systems for building GrapheneOS.</p>
- <p>Dependencies for fetching and verifying the sources:</p>
+ <p>Dependencies for fetching and verifying the sources:</p>
- <ul>
- <li>repo</li>
- <li>python3 (for repo)</li>
- <li>git (both for repo and manual usage)</li>
- <li>gpg (both for repo and manual usage)</li>
- <li>89GiB+ storage for a standard sync with history, 61GiB+ storage for a
- lightweight sync</li>
- </ul>
+ <ul>
+ <li>repo</li>
+ <li>python3 (for repo)</li>
+ <li>git (both for repo and manual usage)</li>
+ <li>gpg (both for repo and manual usage)</li>
+ <li>89GiB+ storage for a standard sync with history, 61GiB+ storage for a
+ lightweight sync</li>
+ </ul>
- <p>Baseline build dependencies:</p>
+ <p>Baseline build dependencies:</p>
- <ul>
- <li>x86_64 Linux build environment (macOS is not supported, unlike AOSP which
- partially supports it)</li>
- <li>Android Open Source Project build dependencies</li>
- <li>16GiB of memory or more. Link-Time Optimization (LTO) creates huge peaks
- during linking and is mandatory for Control Flow Integrity (CFI). Linking
- Vanadium (Chromium) and the Linux kernel with LTO + CFI are the most memory
- demanding tasks.</li>
- <li>100GiB+ of additional free storage space for a typical build of the entire
- OS for a multiarch device</li>
- <li>en_US.UTF-8 locale supported</li>
- </ul>
+ <ul>
+ <li>x86_64 Linux build environment (macOS is not supported, unlike AOSP which
+ partially supports it)</li>
+ <li>Android Open Source Project build dependencies</li>
+ <li>16GiB of memory or more. Link-Time Optimization (LTO) creates huge peaks
+ during linking and is mandatory for Control Flow Integrity (CFI). Linking
+ Vanadium (Chromium) and the Linux kernel with LTO + CFI are the most memory
+ demanding tasks.</li>
+ <li>100GiB+ of additional free storage space for a typical build of the entire
+ OS for a multiarch device</li>
+ <li>en_US.UTF-8 locale supported</li>
+ </ul>
- <p>You can either obtain <code>repo</code> as a distribution package or the
- self-updating standalone version from the Android Open Source Project. The
- self-updating variant avoids dealing with out-of-date distribution packages and
- depends on GPG to verify updates.</p>
+ <p>You can either obtain <code>repo</code> as a distribution package or the
+ self-updating standalone version from the Android Open Source Project. The
+ self-updating variant avoids dealing with out-of-date distribution packages and
+ depends on GPG to verify updates.</p>
- <p>The Android Open Source Project build system is designed to provide reliable and
- reproducible builds. To accomplish this, it provides a prebuilt toolchain and other
- utilities fulfilling most of the build dependency requirements itself. These prebuilt
- tools have reproducible builds themselves. It runs the build process within a loose
- sandbox to avoid accidental dependencies on the host system. The process of moving to
- a fully self-contained build process with minimal external dependencies is gradual and
- there are still dependencies that need to be installed on the host system.</p>
+ <p>The Android Open Source Project build system is designed to provide reliable and
+ reproducible builds. To accomplish this, it provides a prebuilt toolchain and other
+ utilities fulfilling most of the build dependency requirements itself. These prebuilt
+ tools have reproducible builds themselves. It runs the build process within a loose
+ sandbox to avoid accidental dependencies on the host system. The process of moving to
+ a fully self-contained build process with minimal external dependencies is gradual and
+ there are still dependencies that need to be installed on the host system.</p>
- <p>The Linux kernel build process is not integrated into the rest of the AOSP build
- process, but does reuse the same prebuilts to make the build reproducible.</p>
+ <p>The Linux kernel build process is not integrated into the rest of the AOSP build
+ process, but does reuse the same prebuilts to make the build reproducible.</p>
- <p>Additional Linux kernel build dependencies not provided by the source tree:</p>
+ <p>Additional Linux kernel build dependencies not provided by the source tree:</p>
- <ul>
- <li>libgcc (for the host, not the target)</li>
- <li>binutils (for the host, not the target)</li>
- </ul>
+ <ul>
+ <li>libgcc (for the host, not the target)</li>
+ <li>binutils (for the host, not the target)</li>
+ </ul>
- <p>The dependency on the host libgcc and binutils for building utilities during the
- build process will be phased out by moving to a pure LLVM-based toolchain alongside
- doing it for the target. This is lagging a bit behind for the kernel, particularly
- code built for the host.</p>
+ <p>The dependency on the host libgcc and binutils for building utilities during the
+ build process will be phased out by moving to a pure LLVM-based toolchain alongside
+ doing it for the target. This is lagging a bit behind for the kernel, particularly
+ code built for the host.</p>
- <p>Additional Android Open Source Project build dependencies not provided by the
- source tree:</p>
+ <p>Additional Android Open Source Project build dependencies not provided by the
+ source tree:</p>
- <ul>
- <li>diff (diffutils)</li>
- <li>freetype2 and any OpenType/TrueType font (such as DejaVu but anything works)
- for OpenJDK despite it being a headless variant without GUI support</li>
- <li>ncurses5 (provided by the source tree for some tools but not others)</li>
- <li>rsync</li>
- <li>unzip</li>
- <li>zip</li>
- </ul>
+ <ul>
+ <li>diff (diffutils)</li>
+ <li>freetype2 and any OpenType/TrueType font (such as DejaVu but anything works)
+ for OpenJDK despite it being a headless variant without GUI support</li>
+ <li>ncurses5 (provided by the source tree for some tools but not others)</li>
+ <li>rsync</li>
+ <li>unzip</li>
+ <li>zip</li>
+ </ul>
- <p>Additional android-prepare-vendor (for Pixel phones) dependencies:</p>
+ <p>Additional android-prepare-vendor (for Pixel phones) dependencies:</p>
- <ul>
- <li>OpenJDK (for the jar command)</li>
- <li>python2</li>
- <li>python2-protobuf</li>
- </ul>
+ <ul>
+ <li>OpenJDK (for the jar command)</li>
+ <li>python2</li>
+ <li>python2-protobuf</li>
+ </ul>
- <p>The <code>signify</code> tool (with the proper naming) is also required for signing
- factory images zips.</p>
+ <p>The <code>signify</code> tool (with the proper naming) is also required for signing
+ factory images zips.</p>
- <h3 id="downloading-source-code">
- <a href="#downloading-source-code">Downloading source code</a>
- </h3>
+ <h3 id="downloading-source-code">
+ <a href="#downloading-source-code">Downloading source code</a>
+ </h3>
- <p>Since this is syncing the sources for the entire operating system and application
- layer, it will use a lot of bandwidth and storage space.</p>
+ <p>Since this is syncing the sources for the entire operating system and application
+ layer, it will use a lot of bandwidth and storage space.</p>
- <p>You likely want to use the most recent stable tag, not the development branch, even
- for developing a feature. It's easier to port between stable tags that are known to
- work properly than dealing with a moving target.</p>
+ <p>You likely want to use the most recent stable tag, not the development branch, even
+ for developing a feature. It's easier to port between stable tags that are known to
+ work properly than dealing with a moving target.</p>
- <h4 id="development-branch">
- <a href="#development-branch">Development branch</a>
- </h4>
+ <h4 id="development-branch">
+ <a href="#development-branch">Development branch</a>
+ </h4>
- <p>The <code>11</code> branch is the only active development branch for GrapheneOS
- development. Older branches are no longer maintained. It is currently used for all
- officially supported devices and should be used for the basis of ports to other
- devices. Occasionally, some devices may be supported through device support branches
- to avoid impacting other devices with changes needed to support them.</p>
+ <p>The <code>11</code> branch is the only active development branch for GrapheneOS
+ development. Older branches are no longer maintained. It is currently used for all
+ officially supported devices and should be used for the basis of ports to other
+ devices. Occasionally, some devices may be supported through device support branches
+ to avoid impacting other devices with changes needed to support them.</p>
- <pre>mkdir grapheneos-11
+ <pre>mkdir grapheneos-11
cd grapheneos-11
repo init -u https://github.com/GrapheneOS/platform_manifest.git -b 11
repo sync -j32</pre>
- <p>If your network is unreliable and <code>repo sync</code> fails, you can run the
- <code>repo sync</code> command again to continue from where it was interrupted. It
- handles connection failures robustly and you shouldn't start over from scratch.</p>
+ <p>If your network is unreliable and <code>repo sync</code> fails, you can run the
+ <code>repo sync</code> command again to continue from where it was interrupted. It
+ handles connection failures robustly and you shouldn't start over from scratch.</p>
- <h4 id="stable-release">
- <a href="#stable-release">Stable release</a>
- </h4>
+ <h4 id="stable-release">
+ <a href="#stable-release">Stable release</a>
+ </h4>
- <p>Pick a specific release for a device from the <a href="/releases">releases page</a>
- and download the source tree. Note that some devices use different Android Open Source
- Project branches so they can end up with different tags. Make sure to use the correct
- tag for a device. For devices without official support, use the latest tag marked as
- being appropriate for generic / other devices in the release notes.</p>
+ <p>Pick a specific release for a device from the <a href="/releases">releases page</a>
+ and download the source tree. Note that some devices use different Android Open Source
+ Project branches so they can end up with different tags. Make sure to use the correct
+ tag for a device. For devices without official support, use the latest tag marked as
+ being appropriate for generic / other devices in the release notes.</p>
- <pre>mkdir grapheneos-TAG_NAME
+ <pre>mkdir grapheneos-TAG_NAME
cd grapheneos-TAG_NAME
repo init -u https://github.com/GrapheneOS/platform_manifest.git -b refs/tags/TAG_NAME</pre>
- <p>Verify the manifest:</p>
+ <p>Verify the manifest:</p>
- <pre>gpg --recv-keys 65EEFE022108E2B708CBFCF7F9E712E59AF5F22A
+ <pre>gpg --recv-keys 65EEFE022108E2B708CBFCF7F9E712E59AF5F22A
cd .repo/manifests
git verify-tag $(git describe)
cd ../..</pre>
- <p>Complete the source tree download:</p>
+ <p>Complete the source tree download:</p>
- <pre>repo sync -j32</pre>
+ <pre>repo sync -j32</pre>
- <p>The manifest for the latest stable release refers to the revisions in other
- repositories via commit hashes rather than tag names. This avoids the need to use a
- script to verify tag signatures across all the repositories, since they simply point
- to the same commits with the same hashes.</p>
+ <p>The manifest for the latest stable release refers to the revisions in other
+ repositories via commit hashes rather than tag names. This avoids the need to use a
+ script to verify tag signatures across all the repositories, since they simply point
+ to the same commits with the same hashes.</p>
- <p>Note that the repo command itself takes care of updating itself and uses gpg to
- verify by default.</p>
+ <p>Note that the repo command itself takes care of updating itself and uses gpg to
+ verify by default.</p>
- <h3 id="updating-and-switching-branches-or-tags">
- <a href="#updating-and-switching-branches-or-tags">Updating and switching branches or tags</a>
- </h3>
+ <h3 id="updating-and-switching-branches-or-tags">
+ <a href="#updating-and-switching-branches-or-tags">Updating and switching branches or tags</a>
+ </h3>
- <p>To update the source tree, run the <code>repo init</code> command again to select
- the branch or tag and then run <code>repo sync -j32</code> again. You may need to add
- <code>--force-sync</code> if a repository switched from one source to another,
- such as when GrapheneOS forks an additional Android Open Source Project repository.
- You don't need to start over to switch between different branches or tags. You may
- need to run <code>repo init</code> again to continue down the same branch since
- GrapheneOS only provides a stable history via tags.</p>
+ <p>To update the source tree, run the <code>repo init</code> command again to select
+ the branch or tag and then run <code>repo sync -j32</code> again. You may need to add
+ <code>--force-sync</code> if a repository switched from one source to another,
+ such as when GrapheneOS forks an additional Android Open Source Project repository.
+ You don't need to start over to switch between different branches or tags. You may
+ need to run <code>repo init</code> again to continue down the same branch since
+ GrapheneOS only provides a stable history via tags.</p>
- <h3 id="kernel">
- <a href="#kernel">Kernel</a>
- </h3>
+ <h3 id="kernel">
+ <a href="#kernel">Kernel</a>
+ </h3>
- <p>The kernel needs to be built in advance, since it uses a separate build system.</p>
+ <p>The kernel needs to be built in advance, since it uses a separate build system.</p>
- <p>Prebuilts are provided for the Pixel 4, 4 XL and 4a so this step is optional for
- those. This will be done for the other devices in the future.</p>
+ <p>Prebuilts are provided for the Pixel 4, 4 XL and 4a so this step is optional for
+ those. This will be done for the other devices in the future.</p>
- <p>List of kernels corresponding to officially supported devices:</p>
+ <p>List of kernels corresponding to officially supported devices:</p>
- <ul>
- <li>Pixel 2, Pixel 2 XL: wahoo - separate builds due to hardening
- <ul>
- <li>Pixel 2: taimen</li>
- <li>Pixel 2 XL: walleye</li>
- </ul>
- </li>
- <li>Pixel 3, Pixel 3 XL, Pixel 3a, Pixel 3a XL: crosshatch - separate builds due to hardening
- <ul>
- <li>Pixel 3: crosshatch</li>
- <li>Pixel 3 XL: blueline</li>
- <li>Pixel 3a, Pixel 3a XL: bonito</li>
- </ul>
- </li>
- <li>Pixel 4, Pixel 4 XL: coral</li>
- <li>Pixel 4a: sunfish</li>
- </ul>
+ <ul>
+ <li>Pixel 2, Pixel 2 XL: wahoo - separate builds due to hardening
+ <ul>
+ <li>Pixel 2: taimen</li>
+ <li>Pixel 2 XL: walleye</li>
+ </ul>
+ </li>
+ <li>Pixel 3, Pixel 3 XL, Pixel 3a, Pixel 3a XL: crosshatch - separate builds due to hardening
+ <ul>
+ <li>Pixel 3: crosshatch</li>
+ <li>Pixel 3 XL: blueline</li>
+ <li>Pixel 3a, Pixel 3a XL: bonito</li>
+ </ul>
+ </li>
+ <li>Pixel 4, Pixel 4 XL: coral</li>
+ <li>Pixel 4a: sunfish</li>
+ </ul>
- <p>As part of the hardening in GrapheneOS, it uses fully monolithic kernel builds with
- dynamic kernel modules disabled. This improves the effectiveness of mitigations like
- Control Flow Integrity benefiting from whole program analysis. It also reduces attack
- surface and complexity including making the build system simpler. The kernel trees
- marked as using a separate build above need to have the device variant passed to the
- GrapheneOS kernel build script to select the device.</p>
+ <p>As part of the hardening in GrapheneOS, it uses fully monolithic kernel builds with
+ dynamic kernel modules disabled. This improves the effectiveness of mitigations like
+ Control Flow Integrity benefiting from whole program analysis. It also reduces attack
+ surface and complexity including making the build system simpler. The kernel trees
+ marked as using a separate build above need to have the device variant passed to the
+ GrapheneOS kernel build script to select the device.</p>
- <p>For the Pixel 3, Pixel 3 XL, Pixel 3a, Pixel 3a XL, Pixel 4, Pixel 4 XL and Pixel
- 4a the kernel repository uses submodules for building in out-of-tree modules. You need
- to make sure the submodule sources are updated before building. In the future, this
- should end up being handled automatically by <code>repo</code>. There's no harm in
- running the submodule commands for other devices as they will simply not do
- anything.</p>
+ <p>For the Pixel 3, Pixel 3 XL, Pixel 3a, Pixel 3a XL, Pixel 4, Pixel 4 XL and Pixel
+ 4a the kernel repository uses submodules for building in out-of-tree modules. You need
+ to make sure the submodule sources are updated before building. In the future, this
+ should end up being handled automatically by <code>repo</code>. There's no harm in
+ running the submodule commands for other devices as they will simply not do
+ anything.</p>
- <p>For example, to build the kernel for blueline:</p>
+ <p>For example, to build the kernel for blueline:</p>
- <pre>cd kernel/google/crosshatch
+ <pre>cd kernel/google/crosshatch
git submodule sync
git submodule update --init --recursive
./build.sh blueline</pre>
- <h3 id="setting-up-the-os-build-environment">
- <a href="#setting-up-the-os-build-environment">Setting up the OS build environment</a>
- </h3>
+ <h3 id="setting-up-the-os-build-environment">
+ <a href="#setting-up-the-os-build-environment">Setting up the OS build environment</a>
+ </h3>
- <p>The build has to be done from bash as envsetup.sh is not compatible with other
- shells like zsh.</p>
+ <p>The build has to be done from bash as envsetup.sh is not compatible with other
+ shells like zsh.</p>
- <p>Set up the build environment:</p>
+ <p>Set up the build environment:</p>
- <pre>source script/envsetup.sh</pre>
+ <pre>source script/envsetup.sh</pre>
- <p>Select the desired build target (<code>aosp_crosshatch</code> is the Pixel 3 XL):</p>
+ <p>Select the desired build target (<code>aosp_crosshatch</code> is the Pixel 3 XL):</p>
- <pre>choosecombo release aosp_crosshatch user</pre>
+ <pre>choosecombo release aosp_crosshatch user</pre>
- <p>For a development build, you may want to replace <code>user</code> with
- <code>userdebug</code> in order to have better debugging support. Production builds
- should be <code>user</code> builds as they are significantly more secure and don't
- make additional performance sacrifices to improve debugging.</p>
+ <p>For a development build, you may want to replace <code>user</code> with
+ <code>userdebug</code> in order to have better debugging support. Production builds
+ should be <code>user</code> builds as they are significantly more secure and don't
+ make additional performance sacrifices to improve debugging.</p>
- <p>Set <code>OFFICIAL_BUILD=true</code> to include the Updater app. You
- <strong>must</strong> change the URL in
- <code>packages/apps/Updater/res/values/config.xml</code> to your own update server
- URL. Using the official update server with a build signed with different keys will not
- work and will essentially perform a denial of service attack on our update service. If
- you try to use the official URL, the app will download an official update and will
- detect it as corrupted or tampered. It will delete the update and try to download it
- over and over again since it will never be signed with your key.</p>
+ <p>Set <code>OFFICIAL_BUILD=true</code> to include the Updater app. You
+ <strong>must</strong> change the URL in
+ <code>packages/apps/Updater/res/values/config.xml</code> to your own update server
+ URL. Using the official update server with a build signed with different keys will not
+ work and will essentially perform a denial of service attack on our update service. If
+ you try to use the official URL, the app will download an official update and will
+ detect it as corrupted or tampered. It will delete the update and try to download it
+ over and over again since it will never be signed with your key.</p>
- <pre>export OFFICIAL_BUILD=true</pre>
+ <pre>export OFFICIAL_BUILD=true</pre>
- <h3 id="reproducible-builds">
- <a href="#reproducible-builds">Reproducible builds</a>
- </h3>
+ <h3 id="reproducible-builds">
+ <a href="#reproducible-builds">Reproducible builds</a>
+ </h3>
- <p>To reproduce a past build, you need to export <code>BUILD_DATETIME</code> and
- <code>BUILD_NUMBER</code> to the values set for the past build. These can be obtained
- from <code>out/build_date.txt</code> and <code>out/build_number.txt</code> in a build
- output directory and the <code>ro.build.date.utc</code> and
- <code>ro.build.version.incremental</code> properties which are also included in the
- over-the-air zip metadata rather than just the OS itself.</p>
+ <p>To reproduce a past build, you need to export <code>BUILD_DATETIME</code> and
+ <code>BUILD_NUMBER</code> to the values set for the past build. These can be obtained
+ from <code>out/build_date.txt</code> and <code>out/build_number.txt</code> in a build
+ output directory and the <code>ro.build.date.utc</code> and
+ <code>ro.build.version.incremental</code> properties which are also included in the
+ over-the-air zip metadata rather than just the OS itself.</p>
- <p>The signing process for release builds is done after completing builds and replaces
- the dm-verity trees, apk signatures, etc. and can only be reproduced with access to
- the same private keys. If you want to compare to production builds signed with
- different keys you need to stick to comparing everything other than the
- signatures.</p>
+ <p>The signing process for release builds is done after completing builds and replaces
+ the dm-verity trees, apk signatures, etc. and can only be reproduced with access to
+ the same private keys. If you want to compare to production builds signed with
+ different keys you need to stick to comparing everything other than the
+ signatures.</p>
- <p>Additionally, set <code>OFFICIAL_BUILD=true</code> per the instructions above to
- reproduce the official builds. Note that if you do not change the URL to your own
- domain, you <strong>must</strong> disable the Updater app before connecting the device
- to the internet, or you will be performing a denial of service attack on our official
- update server.</p>
+ <p>Additionally, set <code>OFFICIAL_BUILD=true</code> per the instructions above to
+ reproduce the official builds. Note that if you do not change the URL to your own
+ domain, you <strong>must</strong> disable the Updater app before connecting the device
+ to the internet, or you will be performing a denial of service attack on our official
+ update server.</p>
- <h3 id="extracting-vendor-files-for-pixel-devices">
- <a href="#extracting-vendor-files-for-pixel-devices">Extracting vendor files for Pixel devices</a>
- </h3>
+ <h3 id="extracting-vendor-files-for-pixel-devices">
+ <a href="#extracting-vendor-files-for-pixel-devices">Extracting vendor files for Pixel devices</a>
+ </h3>
- <p>This section is specific to Pixel devices. The emulator and generic targets don't
- require extra vendor files.</p>
+ <p>This section is specific to Pixel devices. The emulator and generic targets don't
+ require extra vendor files.</p>
- <p>Many of these components are already open source, but not everything is set up to
- be built by the Android Open Source Project build system. Switching to building these
- components from source will be an incremental effort. In many cases, the vendor files
- simply need to be ignored and AOSP will already provide them instead. Firmware cannot
- generally be built from source even when sources are available, other than to verify
- that the official builds match the sources, since it has signature verification (which
- is an important part of the verified boot and attestation security model).</p>
+ <p>Many of these components are already open source, but not everything is set up to
+ be built by the Android Open Source Project build system. Switching to building these
+ components from source will be an incremental effort. In many cases, the vendor files
+ simply need to be ignored and AOSP will already provide them instead. Firmware cannot
+ generally be built from source even when sources are available, other than to verify
+ that the official builds match the sources, since it has signature verification (which
+ is an important part of the verified boot and attestation security model).</p>
- <p>Extract the vendor files corresponding to the matching release:</p>
+ <p>Extract the vendor files corresponding to the matching release:</p>
- <pre>vendor/android-prepare-vendor/execute-all.sh -d DEVICE -b BUILD_ID -o vendor/android-prepare-vendor
+ <pre>vendor/android-prepare-vendor/execute-all.sh -d DEVICE -b BUILD_ID -o vendor/android-prepare-vendor
mkdir -p vendor/google_devices
rm -rf vendor/google_devices/DEVICE
mv vendor/android-prepare-vendor/DEVICE/BUILD_ID/vendor/google_devices/* vendor/google_devices/</pre>
- <p>Note that android-prepare-vendor is non-deterministic unless a timestamp parameter is
- passed with <code>--timestamp</code> (seconds since Epoch).</p>
+ <p>Note that android-prepare-vendor is non-deterministic unless a timestamp parameter is
+ passed with <code>--timestamp</code> (seconds since Epoch).</p>
- <h3 id="building">
- <a href="#building">Building</a>
- </h3>
+ <h3 id="building">
+ <a href="#building">Building</a>
+ </h3>
- <p>Incremental builds (i.e. starting from the old build) usually work for development
- and are the normal way to develop changes. However, there are cases where changes are
- not properly picked up by the build system. For production builds, you should remove
- the remnants of any past builds before starting, particularly if there were
- non-trivial changes:</p>
+ <p>Incremental builds (i.e. starting from the old build) usually work for development
+ and are the normal way to develop changes. However, there are cases where changes are
+ not properly picked up by the build system. For production builds, you should remove
+ the remnants of any past builds before starting, particularly if there were
+ non-trivial changes:</p>
- <pre>rm -r out</pre>
+ <pre>rm -r out</pre>
- <p>Next, start the build process with the <code>m</code> command:</p>
+ <p>Next, start the build process with the <code>m</code> command:</p>
- <pre>m target-files-package</pre>
+ <pre>m target-files-package</pre>
- <p>The <code>-j</code> parameter can be passed to <code>m</code> to set a specific
- number of jobs such as <code>-j4</code> to use 4 jobs. By default, the build system
- sets the number of jobs to <code>NumCPU() + 2</code> where <code>NumCPU()</code> is the
- number of available logical CPUs.</p>
+ <p>The <code>-j</code> parameter can be passed to <code>m</code> to set a specific
+ number of jobs such as <code>-j4</code> to use 4 jobs. By default, the build system
+ sets the number of jobs to <code>NumCPU() + 2</code> where <code>NumCPU()</code> is the
+ number of available logical CPUs.</p>
- <p><strong>For an emulator build, always use the development build approach below.</strong></p>
+ <p><strong>For an emulator build, always use the development build approach below.</strong></p>
- <h3 id="faster-builds-for-development-use-only">
- <a href="#faster-builds-for-development-use-only">Faster builds for development use only</a>
- </h3>
+ <h3 id="faster-builds-for-development-use-only">
+ <a href="#faster-builds-for-development-use-only">Faster builds for development use only</a>
+ </h3>
- <p>The normal production build process involves building a target files package to be
- resigned with secure release keys and then converted into factory images and/or an
- update zip via the sections below. If you have a dedicated development device with no
- security requirements, you can save time by using the default build target rather than
- target-files-package. Leave the bootloader unlocked and flashing the raw images that
- are signed with the default public test keys.</p>
+ <p>The normal production build process involves building a target files package to be
+ resigned with secure release keys and then converted into factory images and/or an
+ update zip via the sections below. If you have a dedicated development device with no
+ security requirements, you can save time by using the default build target rather than
+ target-files-package. Leave the bootloader unlocked and flashing the raw images that
+ are signed with the default public test keys.</p>
- <p>To build the default build target:</p>
+ <p>To build the default build target:</p>
- <pre>m</pre>
+ <pre>m</pre>
- <p>Technically, you could generate test key signed update packages. However, there's
- no point of sideloading update packages when the bootloader is unlocked and there's no
- value in a locked bootloader without signing the build using release keys, since
- verified boot will be meaningless and the keys used to verify sideloaded updates are
- also public. The only reason to use update packages or a locked bootloader without
- signing the build with release keys would be testing that functionality and it makes a
- lot more sense to test it with proper signing keys rather than the default public test
- keys.</p>
+ <p>Technically, you could generate test key signed update packages. However, there's
+ no point of sideloading update packages when the bootloader is unlocked and there's no
+ value in a locked bootloader without signing the build using release keys, since
+ verified boot will be meaningless and the keys used to verify sideloaded updates are
+ also public. The only reason to use update packages or a locked bootloader without
+ signing the build with release keys would be testing that functionality and it makes a
+ lot more sense to test it with proper signing keys rather than the default public test
+ keys.</p>
- <h3 id="generating-release-signing-keys">
- <a href="#generating-release-signing-keys">Generating release signing keys</a>
- </h3>
+ <h3 id="generating-release-signing-keys">
+ <a href="#generating-release-signing-keys">Generating release signing keys</a>
+ </h3>
- <p>Keys need to be generated for resigning completed builds from the publicly
- available test keys. The keys must then be reused for subsequent builds and cannot be
- changed without flashing the generated factory images again which will perform a
- factory reset. Note that the keys are used for a lot more than simply verifying
- updates and verified boot.</p>
+ <p>Keys need to be generated for resigning completed builds from the publicly
+ available test keys. The keys must then be reused for subsequent builds and cannot be
+ changed without flashing the generated factory images again which will perform a
+ factory reset. Note that the keys are used for a lot more than simply verifying
+ updates and verified boot.</p>
- <p>The sample certificate subject (<code>CN=GrapheneOS</code>) should be replaced with
- your own information.</p>
+ <p>The sample certificate subject (<code>CN=GrapheneOS</code>) should be replaced with
+ your own information.</p>
- <p>You should set a passphrase for the signing keys to keep them at rest until you
- need to sign a release with them. The GrapheneOS scripts (<code>make_key</code> and
- <code>encrypt_keys.sh</code>) encrypt the signing keys using scrypt for key derivation
- and AES256 as the cipher. If you use swap, make sure it's encrypted, ideally with an
- ephemeral key rather a persistent key to support hibernation. Even with an ephemeral
- key, swap will reduce the security gained from encrypting the keys since it breaks the
- guarantee that they become at rest as soon as the signing process is finished.
- Consider disabling swap, at least during the signing process.</p>
+ <p>You should set a passphrase for the signing keys to keep them at rest until you
+ need to sign a release with them. The GrapheneOS scripts (<code>make_key</code> and
+ <code>encrypt_keys.sh</code>) encrypt the signing keys using scrypt for key derivation
+ and AES256 as the cipher. If you use swap, make sure it's encrypted, ideally with an
+ ephemeral key rather a persistent key to support hibernation. Even with an ephemeral
+ key, swap will reduce the security gained from encrypting the keys since it breaks the
+ guarantee that they become at rest as soon as the signing process is finished.
+ Consider disabling swap, at least during the signing process.</p>
- <p>The encryption passphrase for all the keys generated for a device needs to
- match for compatibility with the GrapheneOS scripts.</p>
+ <p>The encryption passphrase for all the keys generated for a device needs to
+ match for compatibility with the GrapheneOS scripts.</p>
- <p>To generate keys for crosshatch (you should use unique keys per device
- variant):</p>
+ <p>To generate keys for crosshatch (you should use unique keys per device
+ variant):</p>
- <pre>mkdir -p keys/crosshatch
+ <pre>mkdir -p keys/crosshatch
cd keys/crosshatch
../../development/tools/make_key releasekey '/CN=GrapheneOS/'
../../development/tools/make_key platform '/CN=GrapheneOS/'
@@ -568,121 +567,121 @@ openssl genrsa 4096 | openssl pkcs8 -topk8 -scrypt -out avb.pem
../../external/avb/avbtool extract_public_key --key avb.pem --output avb_pkmd.bin
cd ../..</pre>
- <p>The <code>avb_pkmd.bin</code> file isn't needed for generating a signed release but
- rather to set the public key used by the device to enforce verified boot.</p>
+ <p>The <code>avb_pkmd.bin</code> file isn't needed for generating a signed release but
+ rather to set the public key used by the device to enforce verified boot.</p>
- <p>Generate a signify key for signing factory images:</p>
+ <p>Generate a signify key for signing factory images:</p>
- <pre>signify -G -n -p keys/crosshatch/factory.pub -s keys/crosshatch/factory.sec</pre>
+ <pre>signify -G -n -p keys/crosshatch/factory.pub -s keys/crosshatch/factory.sec</pre>
- <p>Remove the <code>-n</code> switch to set a passphrase. The <code>signify</code>
- tool doesn't provide a way to change the passphrase without generating a new key, so
- this is currently handled separately from encrypting the other keys and there will be
- a separate prompt for the passphrase. In the future, expect this to be handled by the
- same scripts along with the expectation of it using the same passphrase as the other
- keys.</p>
+ <p>Remove the <code>-n</code> switch to set a passphrase. The <code>signify</code>
+ tool doesn't provide a way to change the passphrase without generating a new key, so
+ this is currently handled separately from encrypting the other keys and there will be
+ a separate prompt for the passphrase. In the future, expect this to be handled by the
+ same scripts along with the expectation of it using the same passphrase as the other
+ keys.</p>
- <h4 id="encrypting-keys">
- <a href="#encrypting-keys">Encrypting keys</a>
- </h4>
+ <h4 id="encrypting-keys">
+ <a href="#encrypting-keys">Encrypting keys</a>
+ </h4>
- <p>You can (re-)encrypt your signing keys using the <code>encrypt_keys</code> script,
- which will prompt for the old passphrase (if any) and new passphrase:</p>
+ <p>You can (re-)encrypt your signing keys using the <code>encrypt_keys</code> script,
+ which will prompt for the old passphrase (if any) and new passphrase:</p>
- <pre>script/encrypt_keys.sh keys/crosshatch</pre>
+ <pre>script/encrypt_keys.sh keys/crosshatch</pre>
- <p>The <code>script/decrypt_keys.sh</code> script can be used to remove encryption,
- which is not recommended. The script exists primarily for internal usage to decrypt
- the keys in tmpfs to perform signing.</p>
+ <p>The <code>script/decrypt_keys.sh</code> script can be used to remove encryption,
+ which is not recommended. The script exists primarily for internal usage to decrypt
+ the keys in tmpfs to perform signing.</p>
- <h4 id="enabling-updatable-apex-components">
- <a href="#enabling-updatable-apex-components">Enabling updatable APEX components</a>
- </h4>
+ <h4 id="enabling-updatable-apex-components">
+ <a href="#enabling-updatable-apex-components">Enabling updatable APEX components</a>
+ </h4>
- <p>GrapheneOS disables updatable APEX components for the officially supported devices
- and targets inheriting from the mainline target, so APEX signing keys are not needed
- and this section can be ignored for unmodified builds.</p>
+ <p>GrapheneOS disables updatable APEX components for the officially supported devices
+ and targets inheriting from the mainline target, so APEX signing keys are not needed
+ and this section can be ignored for unmodified builds.</p>
- <p>GrapheneOS uses the <code>TARGET_FLATTEN_APEX := true</code> format to include APEX
- components as part of the base OS without supporting out-of-band updates.</p>
+ <p>GrapheneOS uses the <code>TARGET_FLATTEN_APEX := true</code> format to include APEX
+ components as part of the base OS without supporting out-of-band updates.</p>
- <p><strong>If you don't disable updatable APEX packages, you need to generate an APK and
- AVB key for each APEX component and extend the GrapheneOS release.sh script to pass
- the appropriate parameters to replace the APK and AVB keys for each APEX
- component.</strong></p>
+ <p><strong>If you don't disable updatable APEX packages, you need to generate an APK and
+ AVB key for each APEX component and extend the GrapheneOS release.sh script to pass
+ the appropriate parameters to replace the APK and AVB keys for each APEX
+ component.</strong></p>
- <p>APEX components that are not flattened are a signed APK (used to verify updates)
- with an embedded filesystem image signed with an AVB key (for verified boot). Each
- APEX package must have a unique set of keys. GrapheneOS has no use for these
- out-of-band updates at this time and flattening APEX components avoids needing a bunch
- of extra keys and complexity.</p>
+ <p>APEX components that are not flattened are a signed APK (used to verify updates)
+ with an embedded filesystem image signed with an AVB key (for verified boot). Each
+ APEX package must have a unique set of keys. GrapheneOS has no use for these
+ out-of-band updates at this time and flattening APEX components avoids needing a bunch
+ of extra keys and complexity.</p>
- <p>For now, consult the upstream documentation on generating these keys. It will be
- covered here in the future.</p>
+ <p>For now, consult the upstream documentation on generating these keys. It will be
+ covered here in the future.</p>
- <h3 id="generating-signed-factory-images-and-full-update-packages">
- <a href="#generating-signed-factory-images-and-full-update-packages">Generating signed factory images and full update packages</a>
- </h3>
+ <h3 id="generating-signed-factory-images-and-full-update-packages">
+ <a href="#generating-signed-factory-images-and-full-update-packages">Generating signed factory images and full update packages</a>
+ </h3>
- <p>Build and package up the tools needed to generate over-the-air update packages:</p>
+ <p>Build and package up the tools needed to generate over-the-air update packages:</p>
- <pre>m otatools-package</pre>
+ <pre>m otatools-package</pre>
- <p>Generate a signed release build with the release.sh script:</p>
+ <p>Generate a signed release build with the release.sh script:</p>
- <pre>script/release.sh crosshatch</pre>
+ <pre>script/release.sh crosshatch</pre>
- <p>The factory images and update package will be in
- <code>out/release-crosshatch-$BUILD_NUMBER</code>. The update zip performs a full OS
- installation so it can be used to update from any previous version. More efficient
- incremental updates are used for official over-the-air GrapheneOS updates and can be
- generated by keeping around past signed <code>target_files</code> zips and generating
- incremental updates from those to the most recent signed <code>target_files</code>
- zip.</p>
+ <p>The factory images and update package will be in
+ <code>out/release-crosshatch-$BUILD_NUMBER</code>. The update zip performs a full OS
+ installation so it can be used to update from any previous version. More efficient
+ incremental updates are used for official over-the-air GrapheneOS updates and can be
+ generated by keeping around past signed <code>target_files</code> zips and generating
+ incremental updates from those to the most recent signed <code>target_files</code>
+ zip.</p>
- <p>See the <a href="/install">install guide</a> for information on how to use the
- factory images. See the <a href="/usage#updates-sideloading">usage guide section on
- sideloading updates</a> for information on how to use the update packages.</p>
+ <p>See the <a href="/install">install guide</a> for information on how to use the
+ factory images. See the <a href="/usage#updates-sideloading">usage guide section on
+ sideloading updates</a> for information on how to use the update packages.</p>
- <p>Running <code>script/release.sh</code> also generates channel metadata for the
- update server. If you configured the Updater client URL and set the build to include
- it (see the information on <code>OFFICIAL_BUILD</code> above), you can push signed
- over-the-air updates via the update system. Simply upload the update package to the
- update server along with the channel metadata for the release channel, and it will be
- pushed out to the update client. The <code>$DEVICE-beta</code> and
- <code>$DEVICE-stable</code> metadata provide the Beta and Stable release channels used
- by the update client. The <code>$DEVICE-testing</code> metadata provides
- provides an internal testing channel for the OS developers, which can be temporarily
- enabled using <code>adb shell setprop sys.update.channel testing</code>. The name is
- arbitrary and you can also use any other name for internal testing channels.</p>
+ <p>Running <code>script/release.sh</code> also generates channel metadata for the
+ update server. If you configured the Updater client URL and set the build to include
+ it (see the information on <code>OFFICIAL_BUILD</code> above), you can push signed
+ over-the-air updates via the update system. Simply upload the update package to the
+ update server along with the channel metadata for the release channel, and it will be
+ pushed out to the update client. The <code>$DEVICE-beta</code> and
+ <code>$DEVICE-stable</code> metadata provide the Beta and Stable release channels used
+ by the update client. The <code>$DEVICE-testing</code> metadata provides
+ provides an internal testing channel for the OS developers, which can be temporarily
+ enabled using <code>adb shell setprop sys.update.channel testing</code>. The name is
+ arbitrary and you can also use any other name for internal testing channels.</p>
- <p>For GrapheneOS itself, the testing channel is used to push out updates to developer
- devices, followed by a sample future release to test that the release which is about
- to be pushed out to the Beta channel is able to update to a future release. Once it's
- tested internally, the release is pushed out to the Beta channel, and finally to the
- Stable channel after public testing. A similar approach is recommended for derivatives
- of GrapheneOS.</p>
+ <p>For GrapheneOS itself, the testing channel is used to push out updates to developer
+ devices, followed by a sample future release to test that the release which is about
+ to be pushed out to the Beta channel is able to update to a future release. Once it's
+ tested internally, the release is pushed out to the Beta channel, and finally to the
+ Stable channel after public testing. A similar approach is recommended for derivatives
+ of GrapheneOS.</p>
- <h4 id="generating-delta-updates">
- <a href="#generating-delta-updates">Generating delta updates</a>
- </h4>
+ <h4 id="generating-delta-updates">
+ <a href="#generating-delta-updates">Generating delta updates</a>
+ </h4>
- <p>Incremental updates shipping only the changes between two versions can be generated
- as a much more efficient way of shipping updates than a full update package containing
- the entire operating system. The GrapheneOS Updater app will automatically use a delta
- update if one exists for going directly from the currently installed version to the
- latest release. In order to generate a delta update, the original signed target files
- package for both the source version and target version are needed. The
- <code>script/generate_delta.sh</code> script provides a wrapper script for generating
- delta updates by passing the device, source version build number and target version
- build number. For example:</p>
+ <p>Incremental updates shipping only the changes between two versions can be generated
+ as a much more efficient way of shipping updates than a full update package containing
+ the entire operating system. The GrapheneOS Updater app will automatically use a delta
+ update if one exists for going directly from the currently installed version to the
+ latest release. In order to generate a delta update, the original signed target files
+ package for both the source version and target version are needed. The
+ <code>script/generate_delta.sh</code> script provides a wrapper script for generating
+ delta updates by passing the device, source version build number and target version
+ build number. For example:</p>
- <pre>script/generate_delta.sh crosshatch 2019.09.25.00 2019.10.07.21</pre>
+ <pre>script/generate_delta.sh crosshatch 2019.09.25.00 2019.10.07.21</pre>
- <p>The script assumes that the releases are organized in the following directory
- structure:</p>
+ <p>The script assumes that the releases are organized in the following directory
+ structure:</p>
-<pre>releases
+ <pre>releases
├── 2019.09.25.00
│   └── release-crosshatch-2019.09.25.00
│      ├── crosshatch-factory-2019.09.25.00.zip
@@ -700,184 +699,184 @@ cd ../..</pre>
   ├── crosshatch-target_files-2019.10.07.21.zip
   └── crosshatch-testing</pre>
- <p>Incremental updates are uploaded alongside the update packages and update metadata
- on the static web server used as an update server. The update client will
- automatically check for an incremental update and use it if available. No additional
- metadata is needed to make incremental updates work.</p>
+ <p>Incremental updates are uploaded alongside the update packages and update metadata
+ on the static web server used as an update server. The update client will
+ automatically check for an incremental update and use it if available. No additional
+ metadata is needed to make incremental updates work.</p>
+ </section>
- <h2 id="prebuilt-code">
- <a href="#prebuilt-code">Prebuilt code</a>
- </h2>
+ <section id="prebuilt-code">
+ <h2><a href="#prebuilt-code">Prebuilt code</a></h2>
- <p>Like the Android Open Source Project, GrapheneOS contains some code that's built
- separately and then bundled into the source tree as binaries. This section will be
- gradually expanded to cover building all of it.</p>
+ <p>Like the Android Open Source Project, GrapheneOS contains some code that's built
+ separately and then bundled into the source tree as binaries. This section will be
+ gradually expanded to cover building all of it.</p>
- <h3 id="browser-and-webview">
- <a href="#browser-and-webview">Browser and WebView</a>
- </h3>
+ <h3 id="browser-and-webview">
+ <a href="#browser-and-webview">Browser and WebView</a>
+ </h3>
- <p>Vanadium is a hardened fork of Chromium developed by GrapheneOS and used to provide
- the WebView and <em>optionally</em> the standalone browser app. It tracks the Chromium
- release cycles along with having additional updates for downstream changes to the
- privacy and security hardening patches, so it's updated at a different schedule than
- the monthly Android releases.</p>
+ <p>Vanadium is a hardened fork of Chromium developed by GrapheneOS and used to provide
+ the WebView and <em>optionally</em> the standalone browser app. It tracks the Chromium
+ release cycles along with having additional updates for downstream changes to the
+ privacy and security hardening patches, so it's updated at a different schedule than
+ the monthly Android releases.</p>
- <p>The browser and the WebView are independent applications built from the Chromium
- source tree. The GrapheneOS browser build is located at external/vanadium and the
- WebView is at external/chromium-webview.</p>
+ <p>The browser and the WebView are independent applications built from the Chromium
+ source tree. The GrapheneOS browser build is located at external/vanadium and the
+ WebView is at external/chromium-webview.</p>
- <p>See <a href="https://chromium.googlesource.com/chromium/src/+/master/docs/android_build_instructions.md">
- Chromium's Android build instructions</a> for details on obtaining the
- prerequisites.</p>
+ <p>See <a href="https://chromium.googlesource.com/chromium/src/+/master/docs/android_build_instructions.md">
+ Chromium's Android build instructions</a> for details on obtaining the
+ prerequisites.</p>
- <pre>git clone https://github.com/GrapheneOS/Vanadium.git
+ <pre>git clone https://github.com/GrapheneOS/Vanadium.git
cd Vanadium
git checkout $CORRECT_BRANCH_OR_TAG</pre>
- <p>Generate a signing key for Vanadium if this is the initial build:</p>
+ <p>Generate a signing key for Vanadium if this is the initial build:</p>
- <pre>keytool -genkey -v -keystore vanadium.keystore -storetype pkcs12 -alias vanadium -keyalg RSA -keysize 4096 -sigalg SHA512withRSA -validity 10000 -dname "cn=GrapheneOS"</pre>
+ <pre>keytool -genkey -v -keystore vanadium.keystore -storetype pkcs12 -alias vanadium -keyalg RSA -keysize 4096 -sigalg SHA512withRSA -validity 10000 -dname "cn=GrapheneOS"</pre>
- <p>You will be prompted to enter a password which will be requested by the
- <code>generate_release.sh</code> script for signing releases. You should back up
- the generated keystore with your other keys.</p>
+ <p>You will be prompted to enter a password which will be requested by the
+ <code>generate_release.sh</code> script for signing releases. You should back up
+ the generated keystore with your other keys.</p>
- <p>Fetch the Chromium sources:</p>
+ <p>Fetch the Chromium sources:</p>
- <pre>fetch --nohooks android</pre>
+ <pre>fetch --nohooks android</pre>
- <p>Sync to the latest stable release for Android (replace <code>$VERSION</code> with
- the correct value):</p>
+ <p>Sync to the latest stable release for Android (replace <code>$VERSION</code> with
+ the correct value):</p>
- <pre>cd src
+ <pre>cd src
git fetch --tags
git checkout $VERSION
gclient sync -D --with_branch_heads --with_tags --jobs 32</pre>
- <p>Apply the GrapheneOS patches on top of the tagged release:</p>
+ <p>Apply the GrapheneOS patches on top of the tagged release:</p>
- <pre>git am --whitespace=nowarn ../patches/*.patch</pre>
+ <pre>git am --whitespace=nowarn ../patches/*.patch</pre>
- <p>Then, configure the build in the <code>src</code> directory:</p>
+ <p>Then, configure the build in the <code>src</code> directory:</p>
- <pre>gn args out/Default</pre>
+ <pre>gn args out/Default</pre>
- <p>Copy the GrapheneOS configuration from <code>../args.gn</code> and save/exit the
- editor. Modify <code>target_cpu</code> as needed if the target is not arm64. For
- x86_64, the correct value for <code>target_cpu</code> is <code>x64</code>, but note
- that the Android source tree refers to it as x86_64.</p>
+ <p>Copy the GrapheneOS configuration from <code>../args.gn</code> and save/exit the
+ editor. Modify <code>target_cpu</code> as needed if the target is not arm64. For
+ x86_64, the correct value for <code>target_cpu</code> is <code>x64</code>, but note
+ that the Android source tree refers to it as x86_64.</p>
- <p>You need to set <code>trichrome_certdigest</code> to the correct value for your
- generated signing key. You can obtain this with the following command:</p>
+ <p>You need to set <code>trichrome_certdigest</code> to the correct value for your
+ generated signing key. You can obtain this with the following command:</p>
- <pre>keytool -export-cert -alias vanadium -keystore vanadium.keystore | sha256sum</pre>
+ <pre>keytool -export-cert -alias vanadium -keystore vanadium.keystore | sha256sum</pre>
- <p>Build the components:</p>
+ <p>Build the components:</p>
- <pre>ninja -C out/Default/ trichrome_webview_64_32_apk trichrome_chrome_64_32_bundle trichrome_library_64_32_apk</pre>
+ <pre>ninja -C out/Default/ trichrome_webview_64_32_apk trichrome_chrome_64_32_bundle trichrome_library_64_32_apk</pre>
- <p>Generate TrichromeChrome.apk from the bundle and sign the apks:</p>
+ <p>Generate TrichromeChrome.apk from the bundle and sign the apks:</p>
- <pre>../generate_release.sh</pre>
+ <pre>../generate_release.sh</pre>
- <p>The apks need to be copied from <code>out/Default/apks/release/*.apk</code>
- into the Android source tree at
- <code>external/vanadium/prebuilt/arm64/</code> with arm64
- substituted with the correct value for other architectures (arm, x86, x86_64).</p>
+ <p>The apks need to be copied from <code>out/Default/apks/release/*.apk</code>
+ into the Android source tree at
+ <code>external/vanadium/prebuilt/arm64/</code> with arm64
+ substituted with the correct value for other architectures (arm, x86, x86_64).</p>
- <p>WebView provider apps need to be whitelisted in
- <code>frameworks/base/core/res/res/xml/config_webview_packages</code>. By default,
- only the Vanadium WebView is whitelisted.</p>
+ <p>WebView provider apps need to be whitelisted in
+ <code>frameworks/base/core/res/res/xml/config_webview_packages</code>. By default,
+ only the Vanadium WebView is whitelisted.</p>
- <h3 id="prebuilt-apps">
- <a href="#prebuilt-apps">Prebuilt apps</a>
- </h3>
+ <h3 id="prebuilt-apps">
+ <a href="#prebuilt-apps">Prebuilt apps</a>
+ </h3>
- <p>The official releases of the Auditor and PdfViewer apps are bundled as an apk into
- external/ repositories. There are no modifications to these for GrapheneOS. These are
- built and signed with the standard <code>gradle</code> Android plugin build
- system.</p>
+ <p>The official releases of the Auditor and PdfViewer apps are bundled as an apk into
+ external/ repositories. There are no modifications to these for GrapheneOS. These are
+ built and signed with the standard <code>gradle</code> Android plugin build
+ system.</p>
- <p>A build of Seedvault is bundled as an apk into an external/ repository. There are
- no modifications made to it.</p>
+ <p>A build of Seedvault is bundled as an apk into an external/ repository. There are
+ no modifications made to it.</p>
+ </section>
- <h2 id="update-server">
- <a href="#update-server">Update server</a>
- </h2>
+ <section id="update-server">
+ <h2><a href="#update-server">Update server</a></h2>
- <p>GrapheneOS uses a static web server as the update server. The release signing
- script generates the necessary metadata alongside the release files. You simply need
- to host these files at the URL configured in
- <code>packages/apps/Updater/res/values/config.xml</code>. See above for details on
- including the Updater app in a release. These are the relevant files:</p>
+ <p>GrapheneOS uses a static web server as the update server. The release signing
+ script generates the necessary metadata alongside the release files. You simply need
+ to host these files at the URL configured in
+ <code>packages/apps/Updater/res/values/config.xml</code>. See above for details on
+ including the Updater app in a release. These are the relevant files:</p>
- <pre>$DEVICE-ota_update-$BUILD_NUMBER.zip
+ <pre>$DEVICE-ota_update-$BUILD_NUMBER.zip
$DEVICE-factory-BUILD_NUMBER.zip
$DEVICE-factory-BUILD_NUMBER.zip.sig
$DEVICE-testing
$DEVICE-beta
$DEVICE-stable</pre>
- <p>Generally, you should start by uploading the ota_update, factory images and testing
- channel metadata.</p>
+ <p>Generally, you should start by uploading the ota_update, factory images and testing
+ channel metadata.</p>
- <p>The <code>testing</code> release channel is an example of an internal release
- channel not configurable via the update client GUI. Internal release channels can have
- arbitrary names. You can override the release channel configured in the update client
- via ADB with the following command:</p>
+ <p>The <code>testing</code> release channel is an example of an internal release
+ channel not configurable via the update client GUI. Internal release channels can have
+ arbitrary names. You can override the release channel configured in the update client
+ via ADB with the following command:</p>
- <pre>adb shell setprop sys.update.channel channel_name</pre>
+ <pre>adb shell setprop sys.update.channel channel_name</pre>
- <p>Replace <code>channel_name</code> with the name of the release channel, such as
- <code>testing</code>.</p>
+ <p>Replace <code>channel_name</code> with the name of the release channel, such as
+ <code>testing</code>.</p>
- <p>After pushing out and testing the new release via the internal release channel,
- it's recommended to build a sample future release and push that out as another update
- via an internal testing channel. This is important to test that the changes in your
- latest release have not broken the future upgrade path.</p>
+ <p>After pushing out and testing the new release via the internal release channel,
+ it's recommended to build a sample future release and push that out as another update
+ via an internal testing channel. This is important to test that the changes in your
+ latest release have not broken the future upgrade path.</p>
- <p>Finally, once the release has gone through internal testing, upload the metadata
- for the beta channel. Once the release has gone through beta testing, upload the
- metadata for the stable channel.</p>
+ <p>Finally, once the release has gone through internal testing, upload the metadata
+ for the beta channel. Once the release has gone through beta testing, upload the
+ metadata for the stable channel.</p>
- <p>Delta update packages should simply be uploaded alongside the rest of the releases.
- The update client will check for the presence of a delta update from the current
- version on the device to the newer release in the selected release channel. There is
- no additional metadata to include alongside the delta update package.</p>
+ <p>Delta update packages should simply be uploaded alongside the rest of the releases.
+ The update client will check for the presence of a delta update from the current
+ version on the device to the newer release in the selected release channel. There is
+ no additional metadata to include alongside the delta update package.</p>
+ </section>
- <h2 id="stable-release-manifest">
- <a href="#stable-release-manifest">Stable release manifest</a>
- </h2>
+ <section id="stable-release-manifest">
+ <h2><a href="#stable-release-manifest">Stable release manifest</a></h2>
- <p>Manifests for stable releases are generated with <code>repo manifest -r</code>
- after tagging the release across all the repositories in a temporary branch and
- syncing to it. This provides a manifest referencing the commits by hashes instead of
- just tags to lock in the revisions. This makes verification of the releases simpler,
- since only the manifest tag needs to be verified rather than tags for each
- repository. This also means the whole release can be verified using the GrapheneOS
- signing key despite referencing many upstream repositories that are not forked by the
- GrapheneOS project.</p>
+ <p>Manifests for stable releases are generated with <code>repo manifest -r</code>
+ after tagging the release across all the repositories in a temporary branch and
+ syncing to it. This provides a manifest referencing the commits by hashes instead of
+ just tags to lock in the revisions. This makes verification of the releases simpler,
+ since only the manifest tag needs to be verified rather than tags for each
+ repository. This also means the whole release can be verified using the GrapheneOS
+ signing key despite referencing many upstream repositories that are not forked by the
+ GrapheneOS project.</p>
+ </section>
- <h2 id="standalone-sdk">
- <a href="#standalone-sdk">Standalone SDK</a>
- </h2>
+ <section id="standalone-sdk">
+ <h2><a href="#standalone-sdk">Standalone SDK</a></h2>
- <p>It can be useful to set up a standalone installation of the SDK separate from
- the Android Open Source Project tree. This is how the prebuilt apps are built, rather
- than using the older branch of the SDK in the OS source tree.</p>
+ <p>It can be useful to set up a standalone installation of the SDK separate from
+ the Android Open Source Project tree. This is how the prebuilt apps are built, rather
+ than using the older branch of the SDK in the OS source tree.</p>
- <p>Android Studio can also be set up to use an existing SDK and will recognize it and use
- it automatically if Android Studio is installed with an SDK installation already
- available and set up in the environment. You'll also likely want a working
- command-line SDK environment even if you do heavily use Android Studio.</p>
+ <p>Android Studio can also be set up to use an existing SDK and will recognize it and use
+ it automatically if Android Studio is installed with an SDK installation already
+ available and set up in the environment. You'll also likely want a working
+ command-line SDK environment even if you do heavily use Android Studio.</p>
- <p>Using the official releases of the SDK is recommended for simplicity, although with
- a lot of effort you can build everything yourself. Distribution packages are generally
- quite out-of-date and should be avoided. To set up a minimal SDK installation at
- <code>~/android/sdk</code> without Android Studio:</p>
+ <p>Using the official releases of the SDK is recommended for simplicity, although with
+ a lot of effort you can build everything yourself. Distribution packages are generally
+ quite out-of-date and should be avoided. To set up a minimal SDK installation at
+ <code>~/android/sdk</code> without Android Studio:</p>
- <pre>mkdir -p ~/android/sdk/cmdline-tools
+ <pre>mkdir -p ~/android/sdk/cmdline-tools
cd ~/android/sdk/cmdline-tools
curl -O https://dl.google.com/android/repository/commandlinetools-linux-6514223_latest.zip
echo 'ef319a5afdb41822cb1c88d93bc7c23b0af4fc670abca89ff0346ee6688da797 commandlinetools-linux-6514223_latest.zip' | sha256sum -c
@@ -885,101 +884,101 @@ unzip commandlinetools-linux-6514223_latest.zip
rm commandlinetools-linux-6514223_latest.zip
mv tools latest</pre>
- <p>Set <code>ANDROID_HOME</code> to point at the SDK installation in your current
- shell and shell profile configuration. You also need to add the
- <code>cmdline-tools</code> binaries to your <code>PATH</code>. For example:</p>
+ <p>Set <code>ANDROID_HOME</code> to point at the SDK installation in your current
+ shell and shell profile configuration. You also need to add the
+ <code>cmdline-tools</code> binaries to your <code>PATH</code>. For example:</p>
- <pre>export ANDROID_HOME="$HOME/android/sdk"
+ <pre>export ANDROID_HOME="$HOME/android/sdk"
export PATH="$HOME/android/sdk/cmdline-tools/latest/bin:$PATH"</pre>
- <p>Make <code>cmdline-tools</code> responsible for updating itself:</p>
+ <p>Make <code>cmdline-tools</code> responsible for updating itself:</p>
- <pre>sdkmanager 'cmdline-tools;latest'</pre>
+ <pre>sdkmanager 'cmdline-tools;latest'</pre>
- <p>Install platform-tools for tools like adb and fastboot:</p>
+ <p>Install platform-tools for tools like adb and fastboot:</p>
- <pre>sdkmanager platform-tools</pre>
+ <pre>sdkmanager platform-tools</pre>
- <p>Add the <code>platform-tools</code> executables to your <code>PATH</code>:</p>
+ <p>Add the <code>platform-tools</code> executables to your <code>PATH</code>:</p>
- <pre>export PATH="$HOME/android/platform-tools:$PATH"</pre>
+ <pre>export PATH="$HOME/android/platform-tools:$PATH"</pre>
- <p>For running the Compatibility Test Suite you'll also need the build-tools for
- aapt:</p>
+ <p>For running the Compatibility Test Suite you'll also need the build-tools for
+ aapt:</p>
- <pre>sdkmanager 'build-tools;30.0.2'</pre>
+ <pre>sdkmanager 'build-tools;30.0.2'</pre>
- <p>Add the <code>build-tools</code> executables to your <code>PATH</code>:</p>
+ <p>Add the <code>build-tools</code> executables to your <code>PATH</code>:</p>
- <pre>export PATH="$HOME/android/sdk/build-tools/30.0.2:$PATH"</pre>
+ <pre>export PATH="$HOME/android/sdk/build-tools/30.0.2:$PATH"</pre>
- <p>For working with native code, you need the NDK:</p>
+ <p>For working with native code, you need the NDK:</p>
- <pre>sdkmanager ndk-bundle</pre>
+ <pre>sdkmanager ndk-bundle</pre>
- <p>Add the <code>ndk-bundle</code> executables to your <code>PATH</code>:</p>
+ <p>Add the <code>ndk-bundle</code> executables to your <code>PATH</code>:</p>
- <pre>export PATH="$HOME/android/sdk/ndk-bundle:$PATH"</pre>
+ <pre>export PATH="$HOME/android/sdk/ndk-bundle:$PATH"</pre>
- <p>You should update the sdk before use from this point onwards:</p>
+ <p>You should update the sdk before use from this point onwards:</p>
- <pre>sdkmanager --update</pre>
+ <pre>sdkmanager --update</pre>
+ </section>
- <h2 id="android-studio">
- <a href="#android-studio">Android Studio</a>
- </h2>
+ <section id="android-studio">
+ <h2><a href="#android-studio">Android Studio</a></h2>
- <p>You can install Android Studio alongside the standalone SDK and it will detect it
- via the <code>ANDROID_HOME</code> environment variable rather than installing another
- copy of it. For example:</p>
+ <p>You can install Android Studio alongside the standalone SDK and it will detect it
+ via the <code>ANDROID_HOME</code> environment variable rather than installing another
+ copy of it. For example:</p>
- <pre>cd ~/android
+ <pre>cd ~/android
curl -O https://dl.google.com/dl/android/studio/ide-zips/4.0.1.0/android-studio-ide-193.6626763-linux.tar.gz
echo 'f2f82744e735eae43fa018a77254c398a3bab5371f09973a37483014b73b7597 android-studio-ide-193.6626763-linux.tar.gz' | sha256sum -c
tar xvf android-studio-ide-193.6626763-linux.tar.gz
rm android-studio-ide-193.6626763-linux.tar.gz
mv android-studio studio</pre>
- <p>Add the Android Studio executables to your <code>PATH</code>:</p>
+ <p>Add the Android Studio executables to your <code>PATH</code>:</p>
- <pre>export PATH="$HOME/android/studio/bin:$PATH"</pre>
+ <pre>export PATH="$HOME/android/studio/bin:$PATH"</pre>
- <p>You can start it with <code>studio.sh</code>.</p>
+ <p>You can start it with <code>studio.sh</code>.</p>
+ </section>
- <h2 id="testing">
- <a href="#testing">Testing</a>
- </h2>
+ <section id="testing">
+ <h2><a href="#testing">Testing</a></h2>
- <p>This section will be expanded to cover various test suites and testing procedures
- rather than only the current very minimal coverage of the Compatibility Test Suite
- (CTS).</p>
+ <p>This section will be expanded to cover various test suites and testing procedures
+ rather than only the current very minimal coverage of the Compatibility Test Suite
+ (CTS).</p>
- <h3 id="emulator">
- <a href="#emulator">Emulator</a>
- </h3>
+ <h3 id="emulator">
+ <a href="#emulator">Emulator</a>
+ </h3>
- <p>To test a build for the emulator, run <code>emulator</code> within the build
- environment. The emulator will use CPU hardware acceleration via KVM along with
- optional graphics acceleration via the host GPU if these are available.</p>
+ <p>To test a build for the emulator, run <code>emulator</code> within the build
+ environment. The emulator will use CPU hardware acceleration via KVM along with
+ optional graphics acceleration via the host GPU if these are available.</p>
- <h3 id="compatibility-test-suite">
- <a href="#compatibility-test-suite">Compatibility Test Suite</a>
- </h3>
+ <h3 id="compatibility-test-suite">
+ <a href="#compatibility-test-suite">Compatibility Test Suite</a>
+ </h3>
- <h4 id="compatibility-test-suite-download">
- <a href="#compatibility-test-suite-download">Download</a>
- </h4>
+ <h4 id="compatibility-test-suite-download">
+ <a href="#compatibility-test-suite-download">Download</a>
+ </h4>
- <p>Testing with the Compatibility Test Suite (CTS) can be done by either building the
- test suite from source or using the official releases.</p>
- <p>Official releases of the CTS can be downloaded from
- <a href="https://source.android.com/compatibility/cts/downloads">the Compatibility
- Suite Downloads page</a>. You should download the CTS for the relevant release
- (Android 11) and architecture (ARM). There's a separate zip for the main CTS, the
- manual portion (CTS Verifier) and the CTS for Instant Apps. The latest release of the
- CTS Media Files also needs to be downloaded from that section.</p>
+ <p>Testing with the Compatibility Test Suite (CTS) can be done by either building the
+ test suite from source or using the official releases.</p>
+ <p>Official releases of the CTS can be downloaded from
+ <a href="https://source.android.com/compatibility/cts/downloads">the Compatibility
+ Suite Downloads page</a>. You should download the CTS for the relevant release
+ (Android 11) and architecture (ARM). There's a separate zip for the main CTS, the
+ manual portion (CTS Verifier) and the CTS for Instant Apps. The latest release of the
+ CTS Media Files also needs to be downloaded from that section.</p>
- <pre>mkdir -p ~/android/cts/{arm,x86}
+ <pre>mkdir -p ~/android/cts/{arm,x86}
cd ~/android/cts/arm
curl -O https://dl.google.com/dl/android/cts/android-cts-11_r1-linux_x86-arm.zip
unzip android-cts-11_r1-linux_x86-arm.zip
@@ -999,186 +998,186 @@ curl -O https://dl.google.com/dl/android/cts/android-cts-media-1.5.zip
unzip android-cts-media-1.5.zip
rm android-cts-media-1.5.zip</pre>
- <h4 id="compatibility-test-suite-setup">
- <a href="#compatibility-test-suite-setup">Setup</a>
- </h4>
- <p>You'll need a device attached to your computer with ADB enabled along with the
- Android SDK installed. The build-tools and platform-tools packages need to be
- installed and the binaries need to be added to your PATH. See the
- <a href="#standalone-sdk">standalone SDK installation instructions</a> above.</p>
+ <h4 id="compatibility-test-suite-setup">
+ <a href="#compatibility-test-suite-setup">Setup</a>
+ </h4>
+ <p>You'll need a device attached to your computer with ADB enabled along with the
+ Android SDK installed. The build-tools and platform-tools packages need to be
+ installed and the binaries need to be added to your PATH. See the
+ <a href="#standalone-sdk">standalone SDK installation instructions</a> above.</p>
- <p>Copy media onto the device:</p>
- <pre>cd android-cts-media-1.5
+ <p>Copy media onto the device:</p>
+ <pre>cd android-cts-media-1.5
./copy_images.sh
./copy_media.sh</pre>
- <p>You also need to do some basic setup for the device. It's possible for changes from
- a baseline install to cause interference, so it can be a good idea to factory reset
- the device if assorted changes have been made. The device needs to be running a user
- build for the security model to be fully intact in order to pass all the security
- tests. A userdebug build is expected to fail some of the tests. GrapheneOS also makes
- various changes intentionally deviating from the requirements expected by the CTS, so
- there will always be some expected failures. A few of the tests are also known to be
- quite flaky or broken even with the stock OS and/or AOSP. These will be documented
- here at some point.</p>
+ <p>You also need to do some basic setup for the device. It's possible for changes from
+ a baseline install to cause interference, so it can be a good idea to factory reset
+ the device if assorted changes have been made. The device needs to be running a user
+ build for the security model to be fully intact in order to pass all the security
+ tests. A userdebug build is expected to fail some of the tests. GrapheneOS also makes
+ various changes intentionally deviating from the requirements expected by the CTS, so
+ there will always be some expected failures. A few of the tests are also known to be
+ quite flaky or broken even with the stock OS and/or AOSP. These will be documented
+ here at some point.</p>
- <ul>
- <li>Must be connected to a WiFi network with IPv6 internet access</li>
- <li>Must have a working SIM card with mobile data with IPv6 internet access</li>
- <li>Disable SIM lock</li>
- <li>Enable Bluetooth</li>
- <li>Enable NFC</li>
- <li>Open / close Chromium to deal with initial setup</li>
- <li>Prop up with a good object to focus on and good lighting for Camera tests.
- Both the front and rear cameras will be used, so ensure this is true for both the
- front and the rear cameras.</li>
- <li>Bluetooth beacons for Bluetooth tests</li>
- <li>Must have a great GPS/GNSS signal for location tests</li>
- <li>SIM card with carrier privilege rules</li>
- <li>Secure element applet installed on the embedded secure element or SIM
- card</li>
- <li>At least one Wi-Fi RTT access point powered up but not connected to any
- network</li>
- <li>The screen lock must be disabled.</li>
- </ul>
+ <ul>
+ <li>Must be connected to a WiFi network with IPv6 internet access</li>
+ <li>Must have a working SIM card with mobile data with IPv6 internet access</li>
+ <li>Disable SIM lock</li>
+ <li>Enable Bluetooth</li>
+ <li>Enable NFC</li>
+ <li>Open / close Chromium to deal with initial setup</li>
+ <li>Prop up with a good object to focus on and good lighting for Camera tests.
+ Both the front and rear cameras will be used, so ensure this is true for both the
+ front and the rear cameras.</li>
+ <li>Bluetooth beacons for Bluetooth tests</li>
+ <li>Must have a great GPS/GNSS signal for location tests</li>
+ <li>SIM card with carrier privilege rules</li>
+ <li>Secure element applet installed on the embedded secure element or SIM
+ card</li>
+ <li>At least one Wi-Fi RTT access point powered up but not connected to any
+ network</li>
+ <li>The screen lock must be disabled.</li>
+ </ul>
- <h4 id="compatibility-test-suite-run-modules">
- <a href="#compatibility-test-suite-run-modules">Run modules</a>
- </h4>
+ <h4 id="compatibility-test-suite-run-modules">
+ <a href="#compatibility-test-suite-run-modules">Run modules</a>
+ </h4>
- <p>Run the test harness:</p>
- <pre>./android-cts/tools/cts-tradefed</pre>
- <p>Note that <code>_JAVA_OPTIONS</code> being set will break the version detection.</p>
- <p>To obtain a list of CTS modules:</p>
- <pre>list modules</pre>
- <p>To run a specific module and avoid wasting time capturing device information:</p>
- <pre>run cts --skip-device-info --module CtsModuleName</pre>
- <p>To speed up initialization after running some initial tests:</p>
- <pre>run cts --skip-device-info --skip-preconditions --module CtsModuleName</pre>
- <p>It's possible to run the whole standard CTS plan with a single command, but running
- specific modules is recommended, especially if you don't have everything set up for
- the entire test suite.</p>
+ <p>Run the test harness:</p>
+ <pre>./android-cts/tools/cts-tradefed</pre>
+ <p>Note that <code>_JAVA_OPTIONS</code> being set will break the version detection.</p>
+ <p>To obtain a list of CTS modules:</p>
+ <pre>list modules</pre>
+ <p>To run a specific module and avoid wasting time capturing device information:</p>
+ <pre>run cts --skip-device-info --module CtsModuleName</pre>
+ <p>To speed up initialization after running some initial tests:</p>
+ <pre>run cts --skip-device-info --skip-preconditions --module CtsModuleName</pre>
+ <p>It's possible to run the whole standard CTS plan with a single command, but running
+ specific modules is recommended, especially if you don't have everything set up for
+ the entire test suite.</p>
+ </section>
- <h2 id="obtaining-upstream-manifests">
- <a href="#obtaining-upstream-manifests">Obtaining upstream manifests</a>
- </h2>
+ <section id="obtaining-upstream-manifests">
+ <h2><a href="#obtaining-upstream-manifests">Obtaining upstream manifests</a></h2>
- <p>The Android Open Source Project has branches and/or tags for the releases of many
- different components. There are tags and/or branches for the OS, device kernels,
- mainline components (APEX), the NDK, Android Studio, the platform-tools distribution
- packages, the CTS, androidx components, etc. You should obtain the sources via
- manifests using the repo tool, either using the manifest for a tag / branch in
- platform/manifest.git or a manifest provided elsewhere. Different projects use
- different subsets of the repositories. Many of the repositories only exist as an
- archive for older releases and aren't referenced in current manifests.</p>
+ <p>The Android Open Source Project has branches and/or tags for the releases of many
+ different components. There are tags and/or branches for the OS, device kernels,
+ mainline components (APEX), the NDK, Android Studio, the platform-tools distribution
+ packages, the CTS, androidx components, etc. You should obtain the sources via
+ manifests using the repo tool, either using the manifest for a tag / branch in
+ platform/manifest.git or a manifest provided elsewhere. Different projects use
+ different subsets of the repositories. Many of the repositories only exist as an
+ archive for older releases and aren't referenced in current manifests.</p>
- <p>Some components don't have the infrastructure set up to generate and push their own
- branches and tags to AOSP. In other cases, it's simply not obvious to an outsider
- which one should be used. As long as the component is built on the standard Android
- project CI infrastructure, it's possible to obtain the manifests to build it based on
- the build number, which is generally incorporated into the build. For example, even
- without a platform-tools tag, you can obtain the build number from <code>adb
- version</code> or <code>fastboot version</code>. Their version output uses the format
- <code>$VERSION-$BUILD_NUMBER</code> such as <code>30.0.3-6597393</code> for the
- version <code>30.0.3</code> where the official release had the build number
- <code>6597393</code>. You can obtain the manifest properties with the appropriate
- repository revisions from ci.android.com with a URL like this:
- <a href="https://ci.android.com/builds/submitted/6597393/sdk/latest/view/repo.prop">
- https://ci.android.com/builds/submitted/6597393/sdk/latest/view/repo.prop</a></p>
+ <p>Some components don't have the infrastructure set up to generate and push their own
+ branches and tags to AOSP. In other cases, it's simply not obvious to an outsider
+ which one should be used. As long as the component is built on the standard Android
+ project CI infrastructure, it's possible to obtain the manifests to build it based on
+ the build number, which is generally incorporated into the build. For example, even
+ without a platform-tools tag, you can obtain the build number from <code>adb
+ version</code> or <code>fastboot version</code>. Their version output uses the format
+ <code>$VERSION-$BUILD_NUMBER</code> such as <code>30.0.3-6597393</code> for the
+ version <code>30.0.3</code> where the official release had the build number
+ <code>6597393</code>. You can obtain the manifest properties with the appropriate
+ repository revisions from ci.android.com with a URL like this:
+ <a href="https://ci.android.com/builds/submitted/6597393/sdk/latest/view/repo.prop">
+ https://ci.android.com/builds/submitted/6597393/sdk/latest/view/repo.prop</a></p>
- <p>The platform-tools tags exist because the GrapheneOS project requested them. The
- same could be done for other projects, but it's not strictly necessarily as long as
- it's possible to obtain the build number to request the information from the Android
- project CI server.</p>
+ <p>The platform-tools tags exist because the GrapheneOS project requested them. The
+ same could be done for other projects, but it's not strictly necessarily as long as
+ it's possible to obtain the build number to request the information from the Android
+ project CI server.</p>
- <p>As another kind of example, <code>prebuilts/clang</code>,
- <code>prebuilts/build-tools</code>, etc. have a manifest file committed alongside the
- prebuilts. Other AOSP toolchain prebuilts reference a build number.</p>
+ <p>As another kind of example, <code>prebuilts/clang</code>,
+ <code>prebuilts/build-tools</code>, etc. have a manifest file committed alongside the
+ prebuilts. Other AOSP toolchain prebuilts reference a build number.</p>
+ </section>
- <h2 id="development-guidelines">
- <a href="#development-guidelines">Development guidelines</a>
- </h2>
+ <section id="development-guidelines">
+ <h2><a href="#development-guidelines">Development guidelines</a></h2>
- <h3 id="programming-languages">
- <a href="#programming-languages">Programming languages</a>
- </h3>
+ <h3 id="programming-languages">
+ <a href="#programming-languages">Programming languages</a>
+ </h3>
- <p>The following programming languages are acceptable for <strong>completely
- new</strong> GrapheneOS projects:</p>
- <ul>
- <li>Kotlin for apps and any services closely tied to the apps, now that it's not
- only officially supported by the Android SDK and Android Studio but also the
- default language with Kotlin exclusive enhancements to the APIs</li>
- <li>Web applications must be entirely static HTML/CSS/JavaScript. TypeScript would
- make sense at a larger scale but there are no plans for any large web
- applications.</li>
- <li>Rust with <code>no_std</code> for low-level code used in a hypervisor, kernel,
- daemon, system library, etc. Keep in mind that low-level code is to be avoided
- whenever a higher-level language is better suited to the job. In general,
- the project aims to avoid creating more low-level code manually dealing with
- memory ownership and lifetimes in the first place.</li>
- <li>C in rare cases for very small and particularly low-level projects without
- opportunities to reduce the trusted computing base for memory corruption to
- any significant degree with Rust, such as for the hardened_malloc project</li>
- <li>arm64 assembly in extremely rare cases where C or Rust aren't usable with
- compiler intrinsics</li>
- <li>Python 3 for small (less than 500 lines) development-related scripts that are
- not exposed to untrusted input. It's never acceptable to use it for
- client-side code on devices or for servers. It isn't used on the servers even
- for non-application-server code.</li>
- <li>Bash for tiny (less than 200 lines) build scripts without any non-trivial
- logic where Python would be an annoyance.</li>
- </ul>
+ <p>The following programming languages are acceptable for <strong>completely
+ new</strong> GrapheneOS projects:</p>
+ <ul>
+ <li>Kotlin for apps and any services closely tied to the apps, now that it's not
+ only officially supported by the Android SDK and Android Studio but also the
+ default language with Kotlin exclusive enhancements to the APIs</li>
+ <li>Web applications must be entirely static HTML/CSS/JavaScript. TypeScript would
+ make sense at a larger scale but there are no plans for any large web
+ applications.</li>
+ <li>Rust with <code>no_std</code> for low-level code used in a hypervisor, kernel,
+ daemon, system library, etc. Keep in mind that low-level code is to be avoided
+ whenever a higher-level language is better suited to the job. In general,
+ the project aims to avoid creating more low-level code manually dealing with
+ memory ownership and lifetimes in the first place.</li>
+ <li>C in rare cases for very small and particularly low-level projects without
+ opportunities to reduce the trusted computing base for memory corruption to
+ any significant degree with Rust, such as for the hardened_malloc project</li>
+ <li>arm64 assembly in extremely rare cases where C or Rust aren't usable with
+ compiler intrinsics</li>
+ <li>Python 3 for small (less than 500 lines) development-related scripts that are
+ not exposed to untrusted input. It's never acceptable to use it for
+ client-side code on devices or for servers. It isn't used on the servers even
+ for non-application-server code.</li>
+ <li>Bash for tiny (less than 200 lines) build scripts without any non-trivial
+ logic where Python would be an annoyance.</li>
+ </ul>
- <p>Much of the work is done on existing projects, and the existing languages should be
- used unless there are already clear stable API boundaries where a different language
- could be used without causing a substantial maintenance burden. The following
- languages are typical from most to least common: Java, C++, C, JavaScript, arm64
- assembly, POSIX shell, Bash.</p>
+ <p>Much of the work is done on existing projects, and the existing languages should be
+ used unless there are already clear stable API boundaries where a different language
+ could be used without causing a substantial maintenance burden. The following
+ languages are typical from most to least common: Java, C++, C, JavaScript, arm64
+ assembly, POSIX shell, Bash.</p>
- <h3 id="code-style">
- <a href="#code-style">Code style</a>
- </h3>
+ <h3 id="code-style">
+ <a href="#code-style">Code style</a>
+ </h3>
- <p>For existing projects, use the official upstream code style. Avoid using legacy
- conventions that they're moving away from themselves. Follow the code style they use
- for new additions. Some projects have different code styles for different directories
- or files depending on their sources, in which case respect the per-file style.</p>
+ <p>For existing projects, use the official upstream code style. Avoid using legacy
+ conventions that they're moving away from themselves. Follow the code style they use
+ for new additions. Some projects have different code styles for different directories
+ or files depending on their sources, in which case respect the per-file style.</p>
- <p>For new projects, follow the official code style for the language. Treat the
- standard library APIs as defining the naming style for usage of the language, i.e. C
- uses <code>variable_or_function_name</code>, <code>type_name</code>,
- <code>MACRO_NAME</code> while JavaScript uses <code>variable_or_function_name</code>,
- <code>ClassName</code> and <code>CONSTANT_NAME</code>. For Python, follow PEP8 and the
- same goes for other languages with official styles whether defined in a document or by
- the default mode for the official formatting tool like <code>rustfmt</code>.</p>
+ <p>For new projects, follow the official code style for the language. Treat the
+ standard library APIs as defining the naming style for usage of the language, i.e. C
+ uses <code>variable_or_function_name</code>, <code>type_name</code>,
+ <code>MACRO_NAME</code> while JavaScript uses <code>variable_or_function_name</code>,
+ <code>ClassName</code> and <code>CONSTANT_NAME</code>. For Python, follow PEP8 and the
+ same goes for other languages with official styles whether defined in a document or by
+ the default mode for the official formatting tool like <code>rustfmt</code>.</p>
- <p>For cases where there isn't an official or prevailing code style for other things,
- avoid tabs, use 4-space indents, <code>function_name</code>,
- <code>variable_name</code>, <code>TypeName</code> and <code>CONSTANT_NAME</code>.
- Prefer single-line comment syntax other than rare cases where it makes sense to add a
- tiny comment within a line of code. In languages with the optional braces misfeature
- (C, C++, Java), always use them. Open braces on the same line as function definitions
- / statements. Wrap lines at 100 columns except in rare cases where it would be far
- uglier to wrap the line.</p>
+ <p>For cases where there isn't an official or prevailing code style for other things,
+ avoid tabs, use 4-space indents, <code>function_name</code>,
+ <code>variable_name</code>, <code>TypeName</code> and <code>CONSTANT_NAME</code>.
+ Prefer single-line comment syntax other than rare cases where it makes sense to add a
+ tiny comment within a line of code. In languages with the optional braces misfeature
+ (C, C++, Java), always use them. Open braces on the same line as function definitions
+ / statements. Wrap lines at 100 columns except in rare cases where it would be far
+ uglier to wrap the line.</p>
- <p>For JavaScript, all code should be contained within ES6 modules. This means every
- script element should use <code>type="module"</code>. Modules provide proper
- namespacing with explicit imports and exports. Modules automatically use strict mode,
- so <code>"use strict";</code> is no longer needed. By default, modules are also
- deferred until after the DOM is ready, i.e. they have an implicit <code>defer</code>
- attribute. This should be relied upon rather than unnecessarily listening for an event
- to determine if the DOM is ready for use. It can make sense to use <code>async</code>
- to run the code earlier if the JavaScript is essential to the content and benefits
- from being able to start tasks before the DOM is ready, such as retrieving important
- content or checking if there's a login session. Always end lines with semicolons
- (since automatic insertion is poorly designed) and always use <code>const</code> to
- declare variables, unless they are reassigned in which case they should be declared
- with <code>let</code> but never use <code>var</code> as it is effectively broken. Try
- to prefer loops with <code>for..of</code>. JavaScript must pass verification with
- <code>eslint</code> using the following <code>.eslintrc.json</code> configuration:</p>
+ <p>For JavaScript, all code should be contained within ES6 modules. This means every
+ script element should use <code>type="module"</code>. Modules provide proper
+ namespacing with explicit imports and exports. Modules automatically use strict mode,
+ so <code>"use strict";</code> is no longer needed. By default, modules are also
+ deferred until after the DOM is ready, i.e. they have an implicit <code>defer</code>
+ attribute. This should be relied upon rather than unnecessarily listening for an event
+ to determine if the DOM is ready for use. It can make sense to use <code>async</code>
+ to run the code earlier if the JavaScript is essential to the content and benefits
+ from being able to start tasks before the DOM is ready, such as retrieving important
+ content or checking if there's a login session. Always end lines with semicolons
+ (since automatic insertion is poorly designed) and always use <code>const</code> to
+ declare variables, unless they are reassigned in which case they should be declared
+ with <code>let</code> but never use <code>var</code> as it is effectively broken. Try
+ to prefer loops with <code>for..of</code>. JavaScript must pass verification with
+ <code>eslint</code> using the following <code>.eslintrc.json</code> configuration:</p>
- <pre>{
+ <pre>{
"env": {
"browser": true,
"es2021": true
@@ -1208,67 +1207,68 @@ rm android-cts-media-1.5.zip</pre>
}
}</pre>
- <p>Cookies are only used for login sessions. The only other use case considered valid
- would be optimizing HTTP/2 Server Push but the intention is only to use that for
- render blocking CSS and it's not really worth optimizing for caching when the CSS is
- tiny in practice. Every cookie must have the <code>__Host</code> prefix to guarantee
- that it has the <code>Secure</code> attribute and <code>Path=/</code>. The
- <code>HttpOnly</code> and <code>SameSite=Strict</code> flags should also always be
- included. These kinds of cookies can provide secure login sessions in browsers with
- fully working <code>SameSite=Strict</code> support. However, CSRF tokens should still
- be used for the near future in case there are browser issues.</p>
+ <p>Cookies are only used for login sessions. The only other use case considered valid
+ would be optimizing HTTP/2 Server Push but the intention is only to use that for
+ render blocking CSS and it's not really worth optimizing for caching when the CSS is
+ tiny in practice. Every cookie must have the <code>__Host</code> prefix to guarantee
+ that it has the <code>Secure</code> attribute and <code>Path=/</code>. The
+ <code>HttpOnly</code> and <code>SameSite=Strict</code> flags should also always be
+ included. These kinds of cookies can provide secure login sessions in browsers with
+ fully working <code>SameSite=Strict</code> support. However, CSRF tokens should still
+ be used for the near future in case there are browser issues.</p>
- <p>For web content, use dashes as user-facing word separators rather than underscores.
- Page titles should follow the scheme "Page | Directory | Higher-level directory |
- Site" for usability with a traditional title as the Open Graph title.</p>
+ <p>For web content, use dashes as user-facing word separators rather than underscores.
+ Page titles should follow the scheme "Page | Directory | Higher-level directory |
+ Site" for usability with a traditional title as the Open Graph title.</p>
- <p>HTML must pass verification with <code>validatornu</code> and <code>xmllint</code>.
- Ensuring that it parses as XML with <code>xmllint</code> catches many common mistakes
- and typos that are missed by HTML validation due to the ridiculously permissive nature
- of HTML. This enforces closing every tag, using proper escaping and so on. XHTML does
- not really exist anymore and we simply use XML parsing as an enforced coding standard
- and lint pass. It can also be useful to make it compatible with XML-based tooling.</p>
+ <p>HTML must pass verification with <code>validatornu</code> and <code>xmllint</code>.
+ Ensuring that it parses as XML with <code>xmllint</code> catches many common mistakes
+ and typos that are missed by HTML validation due to the ridiculously permissive nature
+ of HTML. This enforces closing every tag, using proper escaping and so on. XHTML does
+ not really exist anymore and we simply use XML parsing as an enforced coding standard
+ and lint pass. It can also be useful to make it compatible with XML-based tooling.</p>
- <p>Avoid designing around class inheritance unless it's a rare case where it's an
- extremely good fit or the language sucks (Java) and it's the least bad approach, but
- still try to avoid it.</p>
+ <p>Avoid designing around class inheritance unless it's a rare case where it's an
+ extremely good fit or the language sucks (Java) and it's the least bad approach, but
+ still try to avoid it.</p>
- <p>Use concise but self-explanatory variable names. Prefer communicating information
- via naming rather than using comments whenever possible. Don't name variables
- <code>i</code>, <code>j</code>, <code>k</code>, etc. like C programmers. It's okay to
- use things like <code>x</code> and <code>y</code> for parameters if the function is
- genuinely that generic and operates on arbitrary values. In general, try to scope
- variables into the most limited scope (in C or C++, be careful about this when
- references are taken).</p>
+ <p>Use concise but self-explanatory variable names. Prefer communicating information
+ via naming rather than using comments whenever possible. Don't name variables
+ <code>i</code>, <code>j</code>, <code>k</code>, etc. like C programmers. It's okay to
+ use things like <code>x</code> and <code>y</code> for parameters if the function is
+ genuinely that generic and operates on arbitrary values. In general, try to scope
+ variables into the most limited scope (in C or C++, be careful about this when
+ references are taken).</p>
- <p>Write code that's clean and self-explanatory. Use comments to explain or justify
- non-obvious things, but try to avoid needing them in the first place. In most cases,
- they should just be communicating non-local information such as explaining why an
- invariant is true based on the code elsewhere (consider a runtime check to make sure
- it's true, or an assertion if performance would be an issue). Docstrings at the top of
- top-level functions, modules, etc. are a different story and shouldn't be avoided.</p>
+ <p>Write code that's clean and self-explanatory. Use comments to explain or justify
+ non-obvious things, but try to avoid needing them in the first place. In most cases,
+ they should just be communicating non-local information such as explaining why an
+ invariant is true based on the code elsewhere (consider a runtime check to make sure
+ it's true, or an assertion if performance would be an issue). Docstrings at the top of
+ top-level functions, modules, etc. are a different story and shouldn't be avoided.</p>
- <h3 id="library-usage">
- <a href="#library-usage">Library usage</a>
- </h3>
+ <h3 id="library-usage">
+ <a href="#library-usage">Library usage</a>
+ </h3>
- <p>Make extensive usage of well designed standard library modules. For apps, treat
- Jetpack (androidx) as part of the standard library and make good use of it. For Java,
- Guava can also be treated as part of the standard library.</p>
+ <p>Make extensive usage of well designed standard library modules. For apps, treat
+ Jetpack (androidx) as part of the standard library and make good use of it. For Java,
+ Guava can also be treated as part of the standard library.</p>
- <p>Libraries outside of the standard library should be used very cautiously. They
- should be well maintained, stable, well tested and widely used. Libraries implemented
- with memory unsafe languages should generally be avoided (one exception: SQLite).</p>
+ <p>Libraries outside of the standard library should be used very cautiously. They
+ should be well maintained, stable, well tested and widely used. Libraries implemented
+ with memory unsafe languages should generally be avoided (one exception: SQLite).</p>
- <p>Generally, frameworks and libraries existing solely to provide different paradigms
- and coding patterns are to be avoided. They increase barrier to entry for developers,
- generally only increase complexity unless used at very large scales (and may not even
- make things simpler in those cases) and come and go as fads. This is only okay when
- it's part of the standard libraries or libraries that are considered standard
- (androidx, Guava) by GrapheneOS and should still be approached cautiously. Only use it
- if it truly makes the correct approach simpler. Ignore fads and figure out if it
- actually makes sense to use, otherwise just stick to the old fashioned way if the
- fancy alternatives aren't genuinely better.</p>
+ <p>Generally, frameworks and libraries existing solely to provide different paradigms
+ and coding patterns are to be avoided. They increase barrier to entry for developers,
+ generally only increase complexity unless used at very large scales (and may not even
+ make things simpler in those cases) and come and go as fads. This is only okay when
+ it's part of the standard libraries or libraries that are considered standard
+ (androidx, Guava) by GrapheneOS and should still be approached cautiously. Only use it
+ if it truly makes the correct approach simpler. Ignore fads and figure out if it
+ actually makes sense to use, otherwise just stick to the old fashioned way if the
+ fancy alternatives aren't genuinely better.</p>
+ </section>
</main>
<footer>
<a href="/"><img src="/logo.png" width="512" height="512" alt=""/>GrapheneOS</a>