Skip to content

Foundations

The AAOS stack, layer by layer

A map of the whole platform, explained one layer at a time — what each layer is for, who writes it, and a worked example following a single temperature reading from a sensor in the car to the number on the screen.

Beginner11 minArchitecture · AAOS · Treble

Almost every AAOS bug you will ever debug comes down to one question: which layer is lying to you?

A number on the screen is wrong. Is the sensor wrong? Is the car's own computer sending the wrong value? Is Android misreading it? Is the app displaying it badly? Until you can name the layers, you cannot answer that, and you end up guessing.

So this page is the map. Take your time with it — everything else in the curriculum refers back to it.

First, the shape of the problem#

A car contains dozens of small computers called s. One controls the engine, another the doors, another the climate system. They were designed decades before Android existed and they know nothing about it.

Android needs to show the driver what those computers know, and sometimes tell them to do something. But Android cannot simply "read the car" — there is no such thing. It has to go through several translation steps.

The stack is those translation steps, stacked up.

Automotive appsmedia · navigation · OEM · third-partyCar APIandroid.car — CarPropertyManager, CarAudioManager…Android frameworksystem_server, ActivityManager, WindowManagerCar Servicecom.android.car — CarPropertyService, CarAudioServiceVehicle HAL (AIDL)IVehicle — get / set / subscribeVendor vehicle network serviceproprietary — CAN, SOME/IP, MCU linkVehicle buses & ECUsCAN · LIN · FlexRay · Automotive EthernetAOSP / Google-maintainedOEM / suppliervehicle state flows upTreble / vendor boundary
The Android Automotive OS stackRead it from the top down. Everything above the dashed line ships from AOSP and is broadly the same on every AAOS vehicle. Everything below it is written by the car maker or their supplier, and is different on every vehicle.

Walking down the layers#

Layer 1 — Automotive apps#

These are ordinary Android apps, with two extra rules.

First, they cannot touch the vehicle directly. There is no way for an app to open the car's wiring and read a message. It must ask the platform.

Second, they must obey the driver distraction rules covered later in the curriculum — limits on what may be displayed while the car is moving.

Layer 2 — The Car API (android.car)#

This is a library your app links against. It is the public face of everything car-related.

You already know this pattern from ordinary Android: to play a sound you use android.media; to send a notification you use android.app. To read the cabin temperature you use .

The two names worth knowing here:

  • VehiclePropertyIds — the catalogue of every piece of vehicle data Android defines, as a long list of constants.
  • — the object you actually call to read or watch a value.

Layer 3 — The Android framework#

The ordinary Android you already know: activity management, window management, the package manager. AAOS does not replace this. It adds to it.

Layer 4 — Car Service#

Now we are into the genuinely automotive part.

is a single process — com.android.car — that holds about a dozen smaller services inside it. It is the centre of gravity of the whole platform.

Inside Car ServiceWhat it owns
CarPropertyServiceAll vehicle data, and who is allowed to see it
CarAudioServiceWhich speakers a sound comes out of
CarPowerManagementServiceWhat happens when the car is switched off
CarUserServiceDriver profiles and switching between them
CarUxRestrictionsManagerServiceWhat the screen may show while moving
CarWatchdogServiceNoticing when something has stopped responding

Layer 5 — The Vehicle HAL#

The is the narrowest point in the entire stack, and deliberately so.

It offers exactly one thing: a list of named values — — each of which can be read, written, or watched for changes. That is the whole interface.

Layer 6 — The vendor vehicle network service#

This layer is not in AOSP. It is written by the car maker or their supplier, and it is different on every vehicle.

Its job is to actually talk to the car: open the connection, read messages, and convert raw numbers into the units the VHAL promised.

Layer 7 — The buses and ECUs#

The car's own electronics. Dozens to hundreds of small computers, wired together with and other networks, running software that is not Android and was often written before Android existed.

The dashed line: Treble#

The dashed line in the diagram is the most important architectural fact in AAOS, and it has a name: .

Android is split into separate storage areas called partitions:

  • /system holds the Android framework. Google and the car maker's platform team update this.
  • /vendor holds hardware-specific code — including the VHAL. The supplier writes this, and it is often frozen for years.

They are only allowed to talk to each other through fixed, versioned interfaces. Not by sharing code. Not by sharing data structures. Not by one calling a function in the other.

Following one value all the way down#

Here is the whole stack in one worked example. Your app wants to display the cabin temperature.

What your app writes
val car = Car.createCar(context)
val propertyManager = car.getCarManager(Car.PROPERTY_SERVICE) as CarPropertyManager
 
val temperature = propertyManager.getFloatProperty(
    VehiclePropertyIds.HVAC_TEMPERATURE_CURRENT,   // which value
    VehicleAreaSeat.SEAT_ROW_1_LEFT,               // for which seat
)

Three lines. Here is what actually happens:

1. Your app asks the Car API. getFloatProperty is a normal method call inside your own process. Nothing has left your app yet.

2. The request crosses to Car Service. This is — Android's way for one process to ask another process to do something. Your app pauses while it waits for an answer.

3. Car Service checks permission. Does this app hold android.car.permission.CONTROL_CAR_CLIMATE? If not, it stops here and your app receives a SecurityException.

4. Car Service asks the VHAL. "Give me property HVAC_TEMPERATURE_CURRENT for area SEAT_ROW_1_LEFT."

5. The VHAL answers from its cache. It does not go and ask the car right now — its own background thread has been listening to the vehicle network and keeping a recent value. It hands back what it last heard.

6. The value travels back up through the same path, and getFloatProperty returns 21.5f.

Layers you are allowed to change#

Worth knowing early, because it shapes what job you are actually doing:

LayerCan you change it?
AppsYes — this is ordinary app development
Car APIOnly if you work on the platform
FrameworkOnly if you work on the platform, and it risks CTS failures
Car ServiceYes, if you are the car maker — but it is an AOSP fork to maintain
Vehicle HALYes — this is the supplier's code
Vendor network serviceYes — this is entirely the supplier's
ECUsA different team, often a different company

Next#

Getting a build running on your own machine, so you can try all of this.

References & further reading

Code links target the main branch on cs.android.com. AOSP moves — if a path 404s, search the symbol instead.