1. 历史背景
| 时期 | 语言 | Android 版本 | 说明 |
|---|---|---|---|
| Android 7.0 - 12 | HIDL (HAL Interface Definition Language) | Nougat - S | 首个现代 HAL 接口语言 |
| Android 13+ | AIDL (Android Interface Definition Language) | T 及以后 | 统一的 IPC 接口语言 |
| 过渡期 | 两者共存 | S/T | 兼容性层支持 HIDL 驱动 |
2. 核心架构差异
2.1 接口定义方式
HIDL(旧)- .hal 文件:
hardware_interfaces/radio/1.4/IRadio.hal
package android.hardware.radio@1.4;
interface IRadio {
oneway dial(int32_t serial, Dial dialInfo);
oneway hangupConnection(int32_t serial, uint32_t gsmCallNumber);
oneway setResponseFunctions(IRadioResponse radioResponse, IRadioIndication radioIndication);
}
AIDL(新)- .aidl 文件:
hardware_interfaces/radio/aidl/android/hardware/radio/voice/IRadioVoice.aidl
package android.hardware.radio.voice;
interface IRadioVoice {
oneway void dial(in int serial, in Dial dialInfo);
oneway void hangupConnection(in int serial, in int gsmCallNumber);
void setResponseFunctions(in IRadioVoiceResponse radioVoiceResponse,
in IRadioVoiceIndication radioVoiceIndication);
}
2.2 接口颗粒度
HIDL:单体接口
- 一个
IRadio接口包含所有功能(voice, data, network, messaging, sim, config) - 版本号递增:1.0 → 1.1 → 1.2 → ... → 1.6
hardware_interfaces/radio/1.0/IRadio.hal (2000+ 行)
├─ Voice 功能
├─ Data 功能
├─ Network 功能
├─ Messaging 功能
├─ SIM 功能
└─ Config 功能
AIDL:模块化接口
- 按功能域分离成多个接口
- 每个模块独立版本控制
hardware_interfaces/radio/aidl/android/hardware/radio/
├─ voice/IRadioVoice.aidl
├─ data/IRadioData.aidl
├─ network/IRadioNetwork.aidl
├─ messaging/IRadioMessaging.aidl
├─ sim/IRadioSim.aidl
├─ modem/IRadioModem.aidl
└─ config/IRadioConfig.aidl
3. 响应和指示机制
3.1 HIDL 响应流程
Framework (Java)
│
├─ setResponseFunctions(IRadioResponse, IRadioIndication)
│
RIL (JNI/C++)
│
├─ IRadio@1.4::dial()
│
└─ IRadioResponse@1.4::dialResponse()
IRadioIndication@1.4::callStateChanged()
响应和指示通过同一对接口处理:
44:60:hardware_interfaces/radio/1.0/IRadio.hal
interface IRadio {
setResponseFunctions(IRadioResponse radioResponse, IRadioIndication radioIndication);
oneway dial(int32_t serial, Dial dialInfo);
// ...
}
interface IRadioResponse {
dialResponse(RadioResponseInfo info);
}
interface IRadioIndication {
callStateChanged(RadioIndicationType type);
}
3.2 AIDL 响应流程
Framework (Java)
│
├─ setResponseFunctions(IRadioVoiceResponse, IRadioVoiceIndication)
│
RIL (C++)
│
├─ IRadioVoice::dial()
│
└─ IRadioVoiceResponse::dialResponse()
IRadioVoiceIndication::callStateChanged()
AIDL 采用分离的响应接口:
hardware_interfaces/radio/aidl/android/hardware/radio/voice/IRadioVoice.aidl
interface IRadioVoice {
void setResponseFunctions(in IRadioVoiceResponse radioVoiceResponse,
in IRadioVoiceIndication radioVoiceIndication);
oneway void dial(in int serial, in Dial dialInfo);
}
interface IRadioVoiceResponse {
oneway void dialResponse(in RadioResponseInfo info);
}
interface IRadioVoiceIndication {
oneway void callStateChanged(in RadioIndicationType type);
}
4. 数据结构定义
4.1 HIDL - 复杂的继承体系
hardware_interfaces/radio/1.0/types.hal
struct Dial {
string address;
Clir clir;
vec<UusInfo> uusInfo;
};
struct RadioResponseInfo {
RadioResponseType type;
int32_t serial;
RadioError error;
};
HIDL 支持联合(union)和层级继承。
4.2 AIDL - 扁平的数据结构
hardware_interfaces/radio/aidl/android/hardware/radio/voice/Dial.aidl
package android.hardware.radio.voice;
parcelable Dial {
String address;
int clir;
UusInfo[] uusInfo;
}
hardware_interfaces/radio/aidl/android/hardware/radio/RadioResponseInfo.aidl
package android.hardware.radio;
parcelable RadioResponseInfo {
RadioResponseType type;
int serial;
RadioError error;
}
AIDL 使用 parcelable 而非 struct。
5. RIL Java 层的适配
RIL 框架通过代理类适配两种接口:
53:100:frameworks_opt_telephony/src/java/com/android/internal/telephony/RadioServiceProxy.java
/**
* A holder for IRadio services.
* Use getHidl to get the HIDL IRadio service or getAidl to get the corresponding AIDL service.
*/
public abstract class RadioServiceProxy {
boolean mIsAidl; // 标志:是否为 AIDL
HalVersion mHalVersion = RIL.RADIO_HAL_VERSION_UNKNOWN;
volatile android.hardware.radio.V1_4.IRadio mRadioProxy = null;
/**
* Set IRadio as the HIDL implementation for RadioServiceProxy
*/
public void setHidl(HalVersion halVersion, android.hardware.radio.V1_4.IRadio radio) {
mHalVersion = halVersion;
mRadioProxy = radio;
mIsAidl = false;
}
/**
* Set IRadio as the AIDL implementation for RadioServiceProxy
*/
public void setAidl(android.hardware.radio.IRadio radioAidl) {
mAidlRadioProxy = radioAidl;
mIsAidl = true;
}
public boolean isAidl() {
return mIsAidl;
}
}
6. 兼容性层:libradiocompat
Android 13 引入了兼容性层,允许在 AIDL 框架中使用旧的 HIDL HAL 实现。
6.1 架构
Framework (AIDL)
│
┌─────────┴─────────┐
│ │
AIDL HAL libradiocompat
(Native) (Converter)
│
HIDL HAL (Legacy)
6.2 数据结构转换
libradiocompat 提供了双向转换函数:
19:45:hardware_interfaces/radio/aidl/compat/libradiocompat/commonStructs.cpp
namespace android::hardware::radio::compat {
// HIDL to AIDL conversion
aidl::RadioResponseInfo toAidl(const V1_0::RadioResponseInfo& info) {
return {
.type = toAidl(info.type),
.serial = info.serial,
.error = toAidl(info.error),
};
}
// AIDL to HIDL conversion
V1_0::RadioCapability toHidl(const aidl::RadioCapability& capa) {
return {
.session = capa.session,
.phase = static_cast<V1_0::RadioCapabilityPhase>(capa.phase),
.raf = toHidlBitfield<V1_0::RadioAccessFamily>(capa.raf),
.logicalModemUuid = capa.logicalModemUuid,
.status = static_cast<V1_0::RadioCapabilityStatus>(capa.status),
};
}
}
6.3 集合转换
支持向量和数组的自动转换:
23:56:hardware_interfaces/radio/aidl/compat/libradiocompat/collections.h
template <typename T>
auto toAidl(const hidl_vec<T>& inp) {
std::vector<decltype(toAidl(T{}))> out(inp.size());
for (size_t i = 0; i < inp.size(); i++) {
out[i] = toAidl(inp[i]);
}
return out;
}
template <typename T>
auto toHidl(const std::vector<T>& inp) {
hidl_vec<decltype(toHidl(T{}))> out(inp.size());
for (size_t i = 0; i < inp.size(); i++) {
out[i] = toHidl(inp[i]);
}
return out;
}
7. 关键差异对比表
| 特性 | HIDL | AIDL |
|---|---|---|
| 引入时间 | Android 7.0 (Nougat) | Android 13 (Tiramisu) |
| 定义文件 | .hal | .aidl |
| 接口粒度 | 单体(IRadio 包含所有) | 模块化(IRadioVoice, IRadioData 等) |
| 版本管理 | 整体版本(1.0-1.6) | 按模块版本(各模块独立) |
| 类型系统 | 复杂继承体系 | 简洁的 parcelable 类型 |
| 代码生成 | HIDL 编译器 | AIDL 编译器 |
| 二进制兼容性 | 使用 HIDL 运行时 | 使用 Binder |
| 兼容性支持 | 原生支持 HIDL | 通过 libradiocompat |
| 性能特征 | 针对 HAL 优化 | 通用 IPC 优化 |
8. 版本管理对比
HIDL 版本演进:
android.hardware.radio@1.0::IRadio
├─ dial()
├─ hangupConnection()
└─ ...
android.hardware.radio@1.1::IRadio extends @1.0::IRadio
└─ setCarrierInfoForImsiEncryption() (新增)
android.hardware.radio@1.2::IRadio extends @1.1::IRadio
└─ startNetworkScan() (新增)
...
android.hardware.radio@1.6::IRadio extends @1.5::IRadio
└─ setSimCardPower() (新增)
AIDL 模块化版本:
android.hardware.radio.voice@1::IRadioVoice
├─ dial()
├─ hangupConnection()
└─ ...
android.hardware.radio.data@1::IRadioData
├─ setupDataCall()
├─ deactivateDataCall()
└─ ...
android.hardware.radio.sim@1::IRadioSim
├─ getIccCardStatus()
├─ supplyIccPin()
└─ ...
9. 实际通信流程
9.1 HIDL 请求/响应
┌─────────────────┐
│ RIL (Java/JNI) │
└────────┬────────┘
│ 1. mRadioProxy.dial(serial, dialInfo)
▼
┌─────────────────────────────────┐
│ HIDL Service (radio@1.4::IRadio)│ (Native HAL)
└────────┬────────────────────────┘
│ 2. 内部处理
│ 3. 调用响应回调
▼
┌──────────────────────────────────┐
│ HIDL Callback (IRadioResponse) │
└────────┬─────────────────────────┘
│ 4. response->dialResponse(responseInfo)
▼
┌─────────────────────┐
│ RIL Callback Handler│
└─────────────────────┘
9.2 AIDL 请求/响应
┌─────────────────┐
│ RIL (Java/JNI) │
└────────┬────────┘
│ 1. mRadioProxy.dial(serial, dialInfo)
▼
┌─────────────────────────────────┐
│ AIDL Service (IRadioVoice) │ (Native HAL or Compat Layer)
└────────┬────────────────────────┘
│ 2. 内部处理
│ 3. 调用响应回调
▼
┌──────────────────────────────────┐
│ AIDL Callback (IRadioVoiceResponse)
└────────┬─────────────────────────┘
│ 4. response->dialResponse(responseInfo)
▼
┌─────────────────────┐
│ RIL Callback Handler│
└─────────────────────┘
10. 构建系统差异
HIDL 编译:
hidl_interface {
name: "android.hardware.radio",
root: "android.hardware",
srcs: [
"1.4/IRadio.hal",
"1.4/IRadioResponse.hal",
"1.4/IRadioIndication.hal",
"1.4/types.hal",
],
interfaces: [
"android.hardware.base@1.0",
],
}
AIDL 编译:
aidl_interface {
name: "android.hardware.radio",
vendor_available: true,
srcs: [
"android/hardware/radio/voice/*.aidl",
"android/hardware/radio/data/*.aidl",
"android/hardware/radio/network/*.aidl",
"android/hardware/radio/sim/*.aidl",
"android/hardware/radio/modem/*.aidl",
"android/hardware/radio/messaging/*.aidl",
],
stability: "vintf",
backend: {
cpp: { enabled: true; },
java: { enabled: true; },
},
versions_with_info: [
{ version: "1"; },
{ version: "2"; },
{ version: "3"; },
],
frozen: true,
}
11. 性能和稳定性考量
| 方面 | HIDL | AIDL |
|---|---|---|
| 内存占用 | 较小(C++ 优化) | 相同或稍大 |
| IPC 延迟 | 优化的 Binder 使用 | 标准 Binder 延迟 |
| 类型安全 | 强类型检查 | 强类型检查 |
| 向后兼容 | 通过继承链 | 通过版本管理 |
| 热修复 | 困难(版本锁定) | 更容易(模块独立) |
12. 迁移建议
从 HIDL 迁移到 AIDL 的好处:
- 模块化 - 各功能模块独立演进
- 统一 IPC - 不再有特殊的 HAL IPC 机制
- 灵活版本管理 - 每个模块独立版本
- 更好的工具 - 统一使用 AIDL 工具链
- 长期支持 - AIDL 是未来方向
兼容性策略:
- Android 13-14:HIDL 和 AIDL 并存,通过 libradiocompat 支持旧 HAL
- Android 15+:可能逐步淘汰 HIDL 支持
总结来说,HIDL 是针对 HAL 的专用接口语言,而 AIDL 是通用的系统服务接口语言。RIL 从 HIDL 迁移到 AIDL 反映了 Android 系统架构向更统一、模块化方向的演进。
有任何关于 HIDL/AIDL 在 RIL 中的实现细节的问题吗?