Contributing
How a change actually gets into AOSP: the Gerrit review flow, the CLA, repo upload, and the fact that approval requires a code owner — almost all of whom work at Google. What an outside contributor can realistically expect.
AOSP is open source, and that phrase sets an expectation that the contribution process does not entirely meet. You can read everything, build everything and submit anything. Whether a change lands is a different question, and the answer depends on code ownership, tests and the platform's release cadence.
TL;DR#
- Changes go through Gerrit, not pull requests. You upload with
repo upload, review happens in the web UI, and the change lands when it is approved and submitted. - You need a Contributor Licence Agreement before your first change is accepted.
- Approval requires a code owner, and only Google employees can approve changes for submittal.1
- A change is expected to come with tests and to pass the relevant test suites; a platform change that breaks CTS is not landable.
- Outside contributions are most likely to land in small, well-scoped fixes: a bug fix with a test, documentation, or a driver for hardware the tree supports.
Mental model#
Think of a magazine with a large editorial board.
Anyone can submit a manuscript. The board decides what gets published. The board is not hostile; it is constrained by a publication schedule, a style guide and a set of legal requirements. A submission that ignores the style guide is not rejected because the board dislikes it — it is rejected because the board cannot publish it as written.
AOSP's board is the set of code owners, the style guide is the compatibility and testing requirements, and the schedule is the release train.
Where the analogy breaks#
A magazine's editorial board is a gate. AOSP's ownership model is also a responsibility model: the code owner is the person accountable for that subsystem, and the review is partly about transferring that accountability. A change that is technically correct but that the owner cannot maintain is not landable, which is a stricter bar than "good enough to publish".
The big picture#
Text description of this diagram
A timeline of the platform's eras with the architecture and update lanes highlighted. The architecture lane marks the reorganisations — ART in 2014, Treble in 2017, adaptive-first in 2026 — and the update lane marks Treble, Mainline and GKI. For a contributor, the lanes are a map of where a change can land: a change inside a Mainline module has a narrower interface and a different review path from a change in frameworks/base, and a change to the vendor interface has compatibility consequences for every device.
Deep dive#
The review flow#
The mechanics are straightforward and the details are where people get stuck.
1. Set up an account and a key. You sign in to the Android Gerrit with a Google account and add
an SSH key. repo uses that key to upload.
2. Start a branch in each affected project.
repo start my-fixrepo start creates a local branch in every project that will be part of the change. It is the
equivalent of git checkout -b, but across the multi-repository tree.
3. Make the change, build it, test it.
4. Commit with a sign-off.
git add -A
git commit -sThe -s adds the Signed-off-by line, which is part of the contribution process.
5. Upload.
repo uploadrepo upload finds the commits on your branch, pushes them to Gerrit, and prints a review URL. If
you want to upload only one project, repo upload . does that.
6. Review. A reviewer reads the change in Gerrit, comments on lines, and either approves or requests changes. You amend the commit and upload again; Gerrit keeps the same change and adds a new patch set.
7. Submit. Once approved and passing the required checks, the change is submitted and lands on the branch.
The ownership model#
Every part of the tree has an owner, and approval requires an owner's vote. The AOSP contribution documentation is explicit that only Google employees can approve changes for submittal.1
That single fact shapes what an outside contribution can be. It does not mean outside changes cannot land; it means the path runs through a Google owner who is willing to sponsor the change. Practically:
- A clear bug fix with a test is the easiest thing to land, because the owner can see the problem and the fix.
- A new feature requires an owner who wants the feature, which usually means it is already on a roadmap.
- A large refactor is very hard to land from outside, because the maintenance cost falls on the owner.
- Documentation and test improvements are welcomed more often than product changes.
The realistic strategy is to find a bug that an owner already cares about, fix it narrowly, and include a test that demonstrates the fix.
Writing a change someone will accept#
The mechanics are the easy half. The harder half is producing a change an owner wants.
Match the surrounding code. AOSP has no single style: each subsystem has its own idioms, its own helper classes and its own error handling. A change that is correct but foreign to the file will be sent back for style, and the review will take longer than the fix took to write.
Keep the diff small. A ten-line fix reviews in minutes. A 400-line refactor with a one-line behaviour change will be asked to split, and splitting after review is more work than splitting before.
Explain the why in the commit message. The commit message is the permanent record. A reviewer needs the bug, the symptom and the reasoning; the diff shows the what.
Include a test. A fix without a test is a fix that can regress. The test is also evidence that you understood the bug rather than the symptom.
Expect to iterate. A new patch set is normal. The review is a conversation about the change, and the first version is rarely the accepted one.
Tests and compatibility#
A change to the platform is expected to pass the tests that cover it, and a change that affects behaviour is expected to come with a test that would fail without it. On top of that, there are compatibility requirements: the CDD defines what a device must do, and the CTS checks it.23
For a contributor, the practical consequences are:
- A change that alters public behaviour may need a compatibility review, especially if it affects an API or a default.
- A change that alters the vendor interface is much more expensive, because it affects every device that implements the interface.
- A change behind a feature flag is easier to land, because it can be turned off if it goes wrong. This is one reason aconfig flags are common in platform changes.4
Where an outside contribution is realistic#
The honest list, roughly in order of likelihood:
- Bug fixes in areas with active owners. Small, testable, and clearly beneficial.
- Test additions that cover an existing gap.
- Documentation fixes in the source tree and on the site.
- Device support for hardware that the tree already has infrastructure for.
- Tooling improvements in the build or developer tooling.
And the less realistic list:
- A new system app or service with no owner.
- A redesign of an existing subsystem.
- A change to a stable interface that many devices implement.
- Anything that requires a product decision about what Android should be.
Reviewing your own change first#
Before uploading, read your own diff as though it were someone else's. Four questions catch most of the problems a reviewer would raise:
- Does it touch a stable interface? If so, the compatibility consequences are the review.
- Is there a case where the old code was right and the new code is wrong? That is the regression the test should cover.
- Does it change behaviour for apps that did not ask? If so, is it gated?
- Is there a simpler place to fix it? A fix in the facade is often better than a fix in the service, and vice versa.
The other ways to contribute#
AOSP is not the only place to contribute to Android. The AndroidX libraries accept contributions through a different process, the developer documentation has its own feedback channels, and the broader ecosystem — Kotlin libraries, Gradle plugins, test frameworks — has a much lower barrier. For most people, contributing to Android in practice means contributing to something in that ecosystem rather than to the platform tree.
How it evolved#
| API | Version | What changed |
|---|---|---|
| 1 | 1.0 |
|
| 17 | 4.2 Jelly Bean |
|
| 19 | 4.4 KitKat |
|
| 23 | 6.0 Marshmallow |
|
| 24 | 7.0 Nougat |
|
| 26 | 8.0 Oreo |
|
| 28 | 9 Pie |
|
| 29 | 10 |
|
| 30 | 11 |
|
The treble rows are also a history of contribution: as the platform split into modules and a vendor interface, the number of places a change can land increased, and the review path for each became more specific.
Under the hood#
- Android.bpa module definition in the tree's most active project
- release_config_map.textprotothe release configurations a change may need to be enabled in
- an area where changes require careful review because they affect every process
Curiosity corner#
- Gerrit, not GitHub, is the platform's review system. The mirror on GitHub is a convenience;
the review happens on
android-review.googlesource.com. - Only Google employees can approve changes for submittal. Outside contributors need a sponsor inside the ownership structure.
- A feature flag makes a change easier to land, because it can be disabled if it misbehaves.
Try it#
repo start my-fix
git add -A
git commit -s
repo uploadExample output
Illustrative — requires a checkout and a Gerrit account.Build it#
N03 — Write an init service is a small, self-contained platform change: the kind of thing that is realistic to try in a local tree before attempting to upstream it.
Check yourself#
Three questions to answer without looking back. Open each one only after you have tried.
1. What does a Manager object in your app actually hold?
A Binder proxy to a service, not the service itself. The policy lives on the service side, usually
in system_server, and every call crosses a process boundary.
2. Why does the build use a declarative
Because a declarative module definition can be analysed. Soong can build a complete dependency
graph before running anything, which is what makes Ninja parallel and incremental. Conditionals in
a script would make the graph depend on execution.Android.bp instead of a script?
3. What is the difference between reading a facade and reading a service?
The facade defines the public contract — validation, defaults, deprecation. The service implements
the behaviour and holds the state. A bug in behaviour is almost always on the service side; a
compatibility question is almost always on the facade side.
Sources#
Sources
Every version number, API level, class name and date on this page is traced to one of these. Pages are re-verified against them; last_verified above says when.
- sourceAndroid Gerrit code reviewandroid-review.googlesource.comaccessed 2026-10-27↩
- docsAndroid Compatibility Definition Document (CDD)source.android.comaccessed 2026-10-27↩
- docsCompatibility Test Suite (CTS)source.android.comaccessed 2026-10-27↩
- docsConfiguration (aconfig) overviewsource.android.comaccessed 2026-10-27↩
- docsBuild Androidsource.android.comaccessed 2026-10-27↩