Introduction: Unlocking Automotive Customization with VHAL
Android Automotive OS (AAOS) offers a robust, open-source platform for in-vehicle infotainment systems. While it provides a rich set of predefined vehicle properties through the Vehicle Hardware Abstraction Layer (VHAL), real-world automotive applications often demand highly specific controls and sensor readings that aren’t covered by the standard specification. This is where custom VHAL properties come into play. This expert-level tutorial will guide you through the intricate process of defining and implementing a custom VHAL property for HVAC control – specifically, a custom target temperature setting – from the AIDL definition to the client application, ensuring a deep understanding of AAOS’s underlying hardware interaction.
Understanding the VHAL Architecture
The VHAL is the bridge between Android Automotive OS and the vehicle’s hardware. It defines a set of properties that vehicles can implement, allowing Android components and applications to interact with car features like HVAC, windows, lights, and more. Key components involved in VHAL interaction are:
- Vehicle HAL Implementation: A native C++ daemon (e.g.,
DefaultVehicleHal.cppor a vendor-specific HAL) that directly communicates with the vehicle’s hardware, implementing theIVehicle.aidlinterface. - CarService: A system service running within Android that acts as a broker between client applications and the VHAL implementation.
- CarPropertyManager: The public API available to Android applications for reading and writing vehicle properties.
- AIDL Definitions: Interface Definition Language files (
.aidl) that define the structure and behavior of VHAL properties and the communication interfaces.
When an app requests a vehicle property, CarPropertyManager relays it to CarService, which then forwards the request to the VHAL implementation. The VHAL interacts with the hardware and returns the result up the chain.
Designing Our Custom HVAC Property: Target Temperature
For our demonstration, we’ll create a custom VHAL property to set and retrieve the target HVAC temperature for specific vehicle zones (e.g., driver, passenger). Let’s define its characteristics:
- Property ID: A unique identifier, typically starting from a custom range (e.g.,
0x21000000and above for vendor-specific properties). We’ll useHVAC_CUSTOM_TARGET_TEMPERATURE. - Data Type: Since temperature can be fractional,
FLOATis appropriate. - Access Type:
READ_WRITE, as we need to both set and read the target temperature. - Change Type:
ON_CHANGE, meaning the VHAL will send updates to clients whenever the property’s value changes (e.g., if the user adjusts it via a physical knob). - Area ID:
VEHICLE_AREA_TYPE_SEAT, allowing us to specify temperature for individual seats (driver, front passenger, rear left, etc.).
Defining the Property in AIDL (VehicleProperty.java)
The first step is to declare our new property ID. This is typically done by adding an entry to hardware/interfaces/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleProperty.java. This file contains the integer constants for all standard and custom vehicle properties.
package android.hardware.automotive.vehicle;@VintfStabilitypublic final class VehicleProperty { // ... existing properties /** * Custom HVAC target temperature property. * Units: Celsius. * Area: VehicleAreaSeat. * PropertyType: FLOAT. * Access: READ_WRITE. * ChangeMode: ON_CHANGE. */ public static final int HVAC_CUSTOM_TARGET_TEMPERATURE = 0x21000001; // ... rest of the file}
After modifying this file, you must run m update-api to ensure that the newly defined constant is propagated throughout the Android build system and available to other modules that depend on VHAL definitions.
Implementing the VHAL Backend
Now, we need to teach the VHAL service how to handle our new property. This involves modifying the C++ implementation of the VHAL. We’ll use DefaultVehicleHal.cpp as a reference, which is located in hardware/interfaces/automotive/vehicle/aidl/default.
1. Declare the Property
First, the HAL needs to advertise that it supports this property. This is done within the DefaultVehicleHal::getProperties() method.
// In DefaultVehicleHal.cppVehiclePropConfig DefaultVehicleHal::getPropConfig(int32_t propId) { VehiclePropConfig config{}; config.prop = propId; switch (propId) { case VehicleProperty::HVAC_CUSTOM_TARGET_TEMPERATURE: config.access = VehiclePropertyAccess::READ_WRITE; config.changeMode = VehiclePropertyChangeMode::ON_CHANGE; // Add supported area IDs, e.g., driver and front passenger seats config.areaIds.push_back(VehicleAreaSeat::ROW_1_LEFT | VehicleAreaSeat::ROW_1_RIGHT); config.valueType = VehiclePropertyType::FLOAT; // Set min/max values if applicable, e.g., 16 to 30 Celsius config.minValue.floatValues.push_back(16.0f); config.maxValue.floatValues.push_back(30.0f); break; // ... existing cases } return config;}std::vector<VehiclePropConfig> DefaultVehicleHal::getProperties() { std::vector<VehiclePropConfig> configs; // ... add existing configs configs.push_back(getPropConfig(VehicleProperty::HVAC_CUSTOM_TARGET_TEMPERATURE)); return configs;}
2. Handle Property Write Requests (setVehicleProperty)
When an application tries to set the custom temperature, the setVehicleProperty method in your HAL implementation will be called.
// In DefaultVehicleHal.cppReturn<void> DefaultVehicleHal::setVehicleProperty(const VehiclePropValue& value, setVehicleProperty_cb _hidl_cb) { // ... existing property handling switch (value.prop) { case VehicleProperty::HVAC_CUSTOM_TARGET_TEMPERATURE: { if (value.valueType != VehiclePropertyType::FLOAT) { _hidl_cb(StatusCode::INVALID_ARG, value); return Void(); } // Extract the area ID and value int32_t areaId = value.areaId; float targetTemp = value.value.floatValues[0]; // Simulate writing to hardware and updating internal state ALOGI(
Android Mobile Specs & Compare Directory
Are you researching mobile hardware properties, processor SoCs, GPU chipsets, or RAM configurations? Access our complete specs catalog to compare up to 5 devices side-by-side!
Compare Devices Specs →