Android R introduces the ability to use AIDL for HALs in Android. This makes it possible to implement parts of Android without HIDL. It is strongly recommended to transition HALs to use AIDL exclusively where possible (when upstream HALs use HIDL, HIDL must be used).
HALs using AIDL to communicate between framework components, such as those in
system.img, and hardware components, such as those in
vendor.img, must use
Stable AIDL. However, to communicate within a partition, for instance, from one
HAL to another, there is no restriction on the IPC mechanism being used.
AIDL has been around longer than HIDL, and is used in many other places, such as between Android framework components or in apps. Now that AIDL has stability support, it's possible to implement an entire stack with a single IPC runtime. AIDL also has a better versioning system than HIDL.
- Using a single IPC language means having only one thing to learn, debug, optimize, and secure.
- AIDL supports in-place versioning for the owners of an interface
- Owners can add methods to the end of interfaces or fields to parcelables. This means it's easier to version code over the years, and also the year over year cost is smaller (types can be amended in-place and there is no need for extra libraries for each interface version).
- Extensions are attached at runtime rather than in the type system, so there is no need to rebase downstream extensions onto newer versions of interfaces.
- Existing AIDL interfaces can be used directly when its owner chooses to stabilize it. Before, an entire copy of the interface would have to be created in HIDL.
Writing an AIDL HAL interface
For an AIDL interface to be used between system and vendor, the interface needs two changes:
- Every type definition needs to be annotated with
aidl_interfacedeclaration needs to include
Only the owner of an interface can make these changes.
Finding AIDL HAL interfaces
AOSP Stable AIDL interfaces for HALs are in the same base directories as
HIDL interfaces, in
Building against the AIDL runtime
AIDL has three different backends: Java, NDK, CPP. To use Stable AIDL, you must
always use the system copy of libbinder at
system/lib*/libbinder.so and talk
/dev/binder. For code on the vendor image, this means that
(from the VNDK) cannot be used: this library has an unstable C++ API and
unstable internals. Instead, native vendor code must use the NDK backend of
AIDL, link against
libbinder_ndk (which is backed by system
and link against the
-ndk_platform libraries created by
AIDL HAL server instance names
By convention, AIDL HAL services have an instance name of the format
$package.$type/$instance. For example, an instance of the vibrator HAL is
Wrting an AIDL HAL server
AIDL servers must be declared in the VINTF manifest, for example like this:
<hal format="aidl"> <name>android.hardware.vibrator</name> <fqname>IVibrator/default</fqname> </hal>
Otherwise, they should register an AIDL service normally. When running VTS tests, it's expected that all declared AIDL HALs are available.
Writing an AIDL client
AIDL clients must declare themselves in the compatibility matrix, for example like this:
<name>android.hardware.vibrator</name> <interface> <name>IVibrator</name> <instance>default</instance> </interface>
Major AIDL/HIDL differences
When using AIDL HALs or using AIDL HAL interfaces, be aware of the differences compared to writing HIDL HALs.
- The AIDL language's syntax is closer to Java. HIDL syntax is similar to C++.
- All AIDL interfaces have built-in error statuses. Instead of creating custom
status types, create constant status ints in interface files and use
EX_SERVICE_SPECIFICin the CPP/NDK backends and
ServiceSpecificExceptionin the Java backend.
- AIDL does not abort on unchecked transport errors (HIDL
Returnaborts on unchecked errors).
- AIDL can only declare one type per file.
- AIDL arguments can be specified as in/out/inout in addition to the output parameter (there are no "synchronous callbacks").
- AIDL uses an fd as the primitive type instead of handle.