AOSP Foundations
3 min read

Local Manifests

Learn how to use local manifests to inject private repositories or override upstream AOSP projects without modifying the main manifest.

The default AOSP manifest file downloaded directly from Google describes the pure, generic Android open-source tree. However, if you are building Android for a physical device (like a Raspberry Pi, a custom development board, or a commercial smartphone), you need a way to include your own proprietary hardware drivers, custom apps, and vendor configurations.

Modifying the official default.xml file directly is highly discouraged because your changes will be wiped out the next time you sync with Google's servers. The correct approach is to use Local Manifests.

The .repo/local_manifests/ Directory

The Repo tool is designed to look for a specific directory: .repo/local_manifests/. Any XML files placed inside this directory will be automatically merged with the main default.xml in memory during a repo sync.

You can name the file anything you want (e.g., my_device.xml or roomservice.xml), as long as it has an .xml extension.

Adding Private Projects

The most common use case for a local manifest is to add a completely new repository to the source tree that Google does not know about.

<!-- .repo/local_manifests/my_device.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<manifest>
  <!-- Define our private corporate server -->
  <remote name="my_github" fetch="https://github.com/my-org/" />
  
  <!-- Inject our proprietary hardware drivers into the AOSP tree -->
  <project path="device/mycompany/myboard" 
           name="android_device_myboard" 
           remote="my_github" 
           revision="main" />
</manifest>

When you run repo sync, the Repo tool will download the official AOSP code from Google, and then seamlessly connect to your GitHub remote to download your custom device tree into the device/mycompany/myboard folder.

Overriding Upstream Projects

Sometimes, adding new projects is not enough. You might need to fundamentally alter a core AOSP component (like the Bluetooth stack in system/bt), but you want to maintain your changes in your own private server rather than pushing them to AOSP.

You can use the <remove-project> tag in your local manifest to instruct Repo to ignore Google's version, and then replace it with your own fork:

<!-- .repo/local_manifests/overrides.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<manifest>
  <!-- Remove Google's official Bluetooth stack -->
  <remove-project name="platform/system/bt" />
  
  <!-- Replace it with our custom fork from our own server -->
  <project path="system/bt" 
           name="mycompany/custom_bluetooth_stack" 
           remote="my_github" 
           revision="optimized-bt" />
</manifest>

Use Cases in Device Bring-up

When custom ROM developers (like LineageOS) or commercial hardware teams bring up a new device, their entire device configuration is usually distributed as a single local manifest XML file. By simply copying this one file into the .repo/local_manifests/ directory and typing repo sync, an engineer can pull down thousands of AOSP repositories alongside the exact proprietary drivers required to make the specific hardware boot.

You can quickly create a local manifest directory via the terminal:

mkdir -p .repo/local_manifests
nano .repo/local_manifests/my_customizations.xml