AI 技术博客
Android全栈8 分钟阅读3813

【全栈第8课】HIDL 老式 HAL 与 AIDL 对比

Android 全栈工程师进阶教程 第08课。HIDL 老式 HAL 与 AIDL 对比。基于公开 AOSP 知识整理,含原理、可编译示例、常见问题定位。

> 本文是《Android 全栈工程师进阶教程》系列第 08 课。完整 26 课见 GitHub 仓库

【全栈第8课】HIDL 老式 HAL 与 AIDL 对比


0. 这节课你将做出什么

读懂 某真实机型 里现存的 HIDL .hal 接口,做一份 HIDL vs AIDL 对比。 学完你能回答:HAL 一共经历了哪几代?HIDL 的 .hal 语法长什么样?为什么 Android 新版本 强制把 HAL 从 HIDL 转成 AIDL? 这一课不写新代码(HIDL 已废弃),目的是理解历史,这样 L9 写 AIDL HAL 时你知道"为什么是这样"。

1. 背景:HAL 的三代演进

HAL(Hardware Abstraction Layer,硬件抽象层)是 framework 和硬件驱动之间的一层。它经历了三代:

时期形态问题
第一代 hw_module_tAndroid 8 前dlopen .so + 结构体函数指针,无 IPC,system/vendor 编一起耦合,无法独立升级(Treble 前的痛)
第二代 HIDLAndroid 8(Treble).hal 接口语言 + hidl-gen 生成,跨进程独立一套语言/工具,学习成本高
第三代 AIDL for HALAndroid 11+(新版本 强制)复用 AIDL,语法统一—— L9 学这个

本课聚焦第二代 HIDL,理解它为什么被淘汰。

2. 全局图:HIDL 在哪一层

Framework(system)
   │ 通过 HIDL 接口跨进程调用
   ▼
HIDL HAL 服务(vendor 进程)
   │ 通过 hw_binder(binder 的一个 context)通信
   ▼
内核驱动

HIDL 解决了第一代的耦合问题(跨进程、Treble 解耦),但它是独立的一套接口定义语言(IDL),有自己的 .hal 语法、hidl-gen 工具、版本管理规则——和 framework 一直在用的 AIDL 完全是两套东西

3. 某真实机型 真实源码印证:HIDL 接口长什么样

hardware/interfaces/boot/1.0/IBootControl.hal:

package android.hardware.boot@1.0;          // ← 包名带 @版本号(HIDL 特色)

interface IBootControl {
    // ← 返回值用 generates(...),不是直接 return
    getNumberSlots() generates (uint32_t numSlots);
    setActiveBootSlot(uint32_t slot) generates (CommandResult error);
}

HIDL 语法特点:

  • 包名带 @1.0 版本号(版本是包名的一部分)
  • 返回值用 generates (类型 名字),而不是 C 那样 类型 method()
  • 配套 types.hal 定义结构体

某真实机型 树里还有 749 个 .hal 文件(camera 等遗留没转完),但新 HAL 一律 AIDL。

4. 前置准备

  • 依赖 L7(Treble/VINTF)。
  • 本课是阅读理解,产出一份对比文档,不写可编译代码。

5. 动手:HIDL vs AIDL 全面对比

维度HIDLAIDL(L9)
接口文件I*.hal + types.halI*.aidl
包名android.hardware.boot@1.0(带版本)vendor.example.demo(版本在 manifest)
返回值method() generates (T out)T method() 直接返回
工具hidl-genaidl
版本管理包名 @x.y + .hash 文件aidl_interfaceversions 冻结目录
注册registerAsService()AServiceManager_addService
客户端获取IXxx::getService()IXxx::fromBinder(waitForService(...))
后端C++/JavaC++/Java/NDK/Rust
新版本 态度废弃,chipset API≥202404 强制 AIDL主推

6. 看底层:为什么 Android 抛弃 HIDL 转 AIDL

  1. 重复造轮子:AIDL 本来就有(framework 跨进程一直用它),HIDL 是另起炉灶又造一套 IDL+工具。统一成 AIDL 能减少一整套工具链的维护。
  2. AIDL 通吃:同一套 AIDL 既能给 App 用、又能给 HAL 用、还能给系统服务用。学一套通吃,而 HIDL 只能 HAL 用。
  3. 新版本 硬性要求(见全栈路线 新版本 总结):chipset ro.board.api_level ≥ 202404 且 launch/upgrade 到 新版本 的设备,必须用 AIDL,不能用 HIDL——这是 Google 在 新季度版本 的强制要求,目的是彻底完成 HIDL→AIDL 迁移。

7. 编译 & 运行(本课无编译产物)

# 查设备上现存的 HIDL 和 AIDL HAL 各有哪些:
adb shell lshal | grep "@"        # 带 @版本 的是 HIDL
adb shell lshal | grep -v "@"     # 不带的多是 AIDL

> 验证状态(诚实):本课为阅读理解课,无可编译产物。HIDL 语法引自 某真实机型 真实 IBootControl.hal

8. 踩坑提醒(遇到老 HIDL 代码时)

  1. 别再写新 HIDL HAL:新版本 不允许,新需求一律 AIDL(L9)。
  2. 改老 HIDL 接口要慎重:HIDL 接口一旦发布,版本(@1.0)就冻结了,改要发新版本 @1.1,不能直接改老的。
  3. HIDL 和 AIDL 的服务名风格不同:HIDL 是 包名@版本::接口/实例,AIDL 是 包名.接口/实例,lshal 里都能看到。
  4. HIDL 转 AIDL 不是改个语法:数据结构、版本管理、注册方式都变,是重写,要充分测试。

9. 常见问题分析与定位(遗留 HIDL 实战)

9.1 常见问题清单

  1. 老设备某 HIDL HAL 起不来 / lshal 显示 N/A
  2. HIDL → AIDL 迁移后功能异常
  3. 新版本 上 CTS/VTS 报"还在用 HIDL"
  4. HIDL 接口版本冲突

9.2 分析与定位

① HIDL HAL 起不来(lshal N/A)

adb shell lshal | grep <hal名>        # 看状态,N/A=声明了没起
adb shell lshal list --types=b        # 列 hidl/binderized HAL
adb logcat | grep -iE "<hal名>|hwservicemanager"
  • 和 AIDL 类似:声明了没起 → 查 HAL 进程的 .rc/sepolicy(L11);hwservicemanager(HIDL 的 servicemanager)有没有正常工作。

② 迁移后功能异常

  • 原因:HIDL 和 AIDL 数据类型映射、默认值、错误处理语义有差异。
  • 定位:对比迁移前后接口语义;抓 HAL 日志看调用参数/返回值是否一致。

③ 新版本 报还在用 HIDL

  • 现象:VTS/CTS fail,提示 chipset API≥202404 不允许 HIDL。
  • 修复:把对应 HIDL HAL 迁成 AIDL(L9 的做法)。

④ HIDL 版本冲突

  • 原因:manifest 声明版本和实现版本不一致,或多个版本并存。
  • 定位:lshal 看实际版本;对比 manifest target-level。

9.3 定位决策树

遗留 HIDL 出问题
├─ HAL 起不来(N/A) → lshal + hwservicemanager 日志 → .rc/sepolicy(L11)
├─ 迁移后异常 → 对比 HIDL/AIDL 类型映射+语义 → 抓 HAL 日志比对参数
├─ 新版本 报用 HIDL → 迁成 AIDL(L9)
└─ 版本冲突 → lshal 看实际版本 vs manifest target-level

10. 小结

  1. HAL 三代:hw_module_t(无IPC,耦合)→ HIDL(Treble,跨进程)→ AIDL(新版本 强制,统一)。
  2. HIDL 语法特征:包名带 @版本、返回值用 generates、配 types.hal、工具 hidl-gen
  3. 抛弃 HIDL 的原因:AIDL 本就有、通吃、新版本 硬性要求统一。
  4. 实战:别写新 HIDL,遇老 HIDL 改动慎重(版本冻结),迁 AIDL 是重写要测。
  5. 排查口诀:lshal 看状态(带 @ 是 HIDL);起不来查 hwservicemanager+sepolicy;新版本 报错就迁 AIDL。

下节预告

L9:AIDL HAL 编写(vendor 实现) —— 阶段二重头戏!真正从零写一个完整的 hello AIDL HAL:接口+实现+注册+init.rc+vintf+Android.bp。

评论