AIDL与HAL迁移
HIDL 到 AIDL 的迁移不是只改接口文件后缀,它同时改变构建模块、服务注册 API、manifest 声明、客户端库和 VTS 契约。下面的对照图用于定位后文每一层的真实源码入口。
本文面向已经读过 Stable AIDL 和 AIDL后端生成 的读者。迁移不是把 .hal 后缀改成 .aidl:它会同时改变接口版本表达、生成库、服务注册 API、VINTF manifest 格式和 VTS 客户端。本文以 Android 17 的 hardware/interfaces/power 为主线,对照仍保留的 HIDL 1.0 服务和 AIDL V7 服务。
1. 两份接口
1.1 HIDL声明
源码文件:hardware/interfaces/power/1.0/IPower.hal
package android.hardware.power@1.0;
interface IPower {
setInteractive(bool interactive);
powerHint(PowerHint hint, int32_t data);
setFeature(Feature feature, bool activate);
}HIDL 用 package@version 命名空间表达版本,后续 1.1、1.2、1.3 通过 extends 继承前一版本接口。版本是类型名的一部分,客户端编译时就选择具体 V1_0::IPower。
1.2 AIDL声明
源码文件:hardware/interfaces/power/aidl/android/hardware/power/IPower.aidl
AIDL 使用单一包名 android.hardware.power,版本由 aidl_interface 的快照和生成模块后缀 -V7 管理。接口演进不再创建 @1.1 命名空间,而是向当前快照追加兼容声明并冻结新版本。
2. 构建模块
2.1 HIDL模块
源码文件:hardware/interfaces/power/1.0/Android.bp
HIDL 模块名为 android.hardware.power@1.0,依赖 hidlbase/hidltransport 生成的 C++ 类型和服务支持库。每个接口版本有单独的模块与 VTS 目标,依赖关系沿版本继承展开。
2.2 AIDL模块
源码文件:hardware/interfaces/power/aidl/Android.bp
aidl_interface {
name: "android.hardware.power",
vendor_available: true,
stability: "vintf",
backend: {
cpp: { enabled: false },
ndk: { enabled: true },
java: { enabled: true, sdk_version: "module_current" },
rust: { enabled: true },
},
versions_with_info: [
{ version: "1", imports: [] },
{ version: "7", imports: ["android.hardware.common.fmq-V1", "android.hardware.common-V2"] },
],
frozen: true,
}AIDL HAL 关闭 CPP backend,选择 NDK/Rust/Java;这不是语言偏好,而是 vendor 可用性与稳定 ABI 的构建边界。stability: "vintf"、版本列表和 frozen: true 把接口接入 Stable AIDL 的 API/hash 门禁。
3. 服务启动
3.1 HIDL入口
源码文件:hardware/interfaces/power/1.0/default/service.cpp
using android::hardware::power::V1_0::IPower;
int main() {
return defaultPassthroughServiceImplementation<IPower>();
}HIDL 服务入口交给 defaultPassthroughServiceImplementation,实例名和注册细节由 HIDL 支持层处理;对应 init rc 使用 android.hardware.power@1.0::IPower default 接口名。
3.2 AIDL入口
源码文件:hardware/interfaces/power/aidl/default/main.cpp
ABinderProcess_setThreadPoolMaxThreadCount(0);
std::shared_ptr<Power> service = ndk::SharedRefBase::make<Power>();
const std::string instance = std::string() + Power::descriptor + "/default";
binder_status_t status = AServiceManager_addService(
service->asBinder().get(), instance.c_str());
CHECK_EQ(status, STATUS_OK);
ABinderProcess_joinThreadPool();AIDL NDK 服务显式创建实现对象、拼出 descriptor/default、调用 AServiceManager_addService,再进入 NDK Binder 线程池。这里的 owner 已从 HIDL passthrough wrapper 变成 AIDL Bn 实现对象。
4. 清单注册
4.1 HIDL片段
源码文件:hardware/interfaces/power/1.0/default/android.hardware.power@1.0-service.rc
service vendor.power-hal-1-0 /vendor/bin/hw/android.hardware.power@1.0-service
interface android.hardware.power@1.0::IPower defaultHIDL 的接口声明包含 @1.0 版本,服务管理器可按版本化接口名发现实例。
4.2 AIDL片段
源码文件:hardware/interfaces/power/aidl/default/power-default.xml
<manifest version="1.0" type="device">
<hal format="aidl">
<name>android.hardware.power</name>
<version>7</version>
<fqname>IPower/default</fqname>
</hal>
</manifest>AIDL manifest 把包名、版本和 fully-qualified instance 分成三个字段;服务进程注册的 android.hardware.power.IPower/default 必须与 manifest 的 fqname 对齐。只改二进制路径而不改清单,会导致 VINTF/服务发现不一致。
5. 客户端获取
5.1 HIDL客户端
源码文件:hardware/interfaces/power/1.2/vts/functional/VtsHalPowerV1_2TargetTest.cpp
power = IPower::getService(GetParam());
ASSERT_NE(nullptr, power);客户端类型是 android::hardware::power::V1_2::IPower,getService 由 HIDL transport 查询版本化 descriptor 和 instance。
5.2 AIDL客户端
源码文件:hardware/interfaces/power/aidl/vts/Android.bp、hardware/interfaces/power/aidl/vts/VtsHalPowerTargetTest.cpp
AIDL VTS 链接 android.hardware.power-V7-ndk,通过 NDK AServiceManager_waitForService/生成接口获取 IPower/default。客户端不再用 V1_2 C++ namespace,而是把版本选择落实在链接模块和生成 API 上。
6. 数据演进
6.1 HIDL继承
hardware/interfaces/power/1.1/IPower.hal 直接 extends android.hardware.power@1.0::IPower,新增方法出现在新 C++ interface 类型中;旧服务继续实现旧版本。
6.2 AIDL冻结
AIDL aidl_api/android.hardware.power/{1..7} 保存完整快照。新版本通过 checkapi=compatible、hash 和冻结命令生成;旧客户端可链接旧 -Vn 版本,新服务通过生成的版本兼容逻辑处理旧事务。迁移后不能把“方法加到文件末尾”当作唯一兼容策略,必须让 API dump 看到它是兼容扩展。
7. 测试边界
7.1 HIDL VTS
HIDL VTS 按 V1_1、V1_2、V1_3 分目录编译,每个测试使用对应生成接口和继承链,验证 transport 能否取得该版本实例。
7.2 AIDL VTS
源码文件:hardware/interfaces/power/aidl/vts/VtsHalPowerTargetTest.cpp
AIDL VTS 绑定 Stable AIDL V7 NDK 产物,同时由 power-default.xml 的 manifest 约束实际设备必须暴露 IPower/default。因此测试失败可能来自实现逻辑、服务注册、manifest 版本或生成库选择,不能只看方法返回值。
8. 迁移检查
迁移一个 HAL 时,按源码顺序核对:接口包名与版本模型、Android.bp 的 backend/stability/versions、生成服务基类、main.cpp 的注册实例、VINTF manifest 的 format/name/version/fqname、VTS 客户端链接版本。若只替换接口文件而保留 HIDL 的 getService、rc interface 名称或版本继承假设,服务可能成功编译却无法被系统发现。
