4. HAL 接口定义:.hal 文件的语法结构
HAL(Hardware Abstraction Layer)接口定义文件以 .hal 为扩展名,是 VTS 测试框架验证 HAL 层协议一致性的核心依据。本章系统讲解 .hal 文件的语法结构、包声明、接口定义、方法签名及数据类型,帮助测试工程师准确理解接口规范,为编写 VTS 测试用例奠定基础。
4.1 .hal 文件整体语法结构
.hal 文件采用类 C++ 的语法风格,但具有严格的层次结构。一个完整的 .hal 文件由 package 声明、import 导入、类型定义和接口定义四部分组成。
// 示例:ILight.hal
package android.hardware.light@2.0;
import android.hardware.graphics.common@1.0::types;
enum FlashMode : int32_t {
NONE,
TORCH,
FLASH
};
struct LightState {
FlashMode flashMode;
uint8_t brightness;
uint32_t color;
};
interface ILight {
setLight(LightState state) generates (bool success);
getLight() generates (LightState state);
};
- 文件扩展名固定为
.hal,每个文件通常定义一个接口或一组相关类型。 - 注释支持
//单行和/* */多行两种风格。 - 语句以分号
;结束,块定义使用花括号{}。 - 标识符区分大小写,遵循驼峰命名规范。
4.2 package 声明
package 声明定义了 HAL 接口的命名空间和版本号,是 .hal 文件的第一条有效语句。其语法格式如下:
package <vendor>.<subsystem>.<module>@<major>.<minor>;
| 组成部分 | 说明 | 示例 |
|---|---|---|
| vendor | 厂商或组织名称,通常为 android.hardware |
android.hardware |
| subsystem | 子系统分类,如 camera、sensors、graphics |
camera |
| module | 具体模块名称,如 device、provider |
device |
| major.minor | 主版本号和次版本号,用于接口兼容性管理 | @3.4 |
常见 package 声明示例:
package android.hardware.camera.device@3.4;
package android.hardware.sensors@1.0;
package android.hardware.graphics.composer@2.1;
package vendor.google.example@1.0; // 厂商自定义接口
4.3 interface 定义
interface 是 HAL 接口的核心,定义了一组可供客户端调用的方法。每个 interface 可以包含多个方法签名,并支持继承机制。
interface IMyInterface {
// 同步方法:调用后等待返回结果
doSomething(int32_t input) generates (int32_t output);
// 单向方法:不等待返回,无返回值
oneway fireAndForget(uint32_t event);
// 回调方法:服务端主动向客户端推送数据
registerCallback(ICallback callback);
};
4.3.1 接口命名规范
| 规范项 | 要求 | 正确示例 | 错误示例 |
|---|---|---|---|
| 前缀 | 必须以 I 开头 |
ICameraDevice |
CameraDevice |
| 命名风格 | 大驼峰命名法 | ISensorManager |
Isensor_manager |
| 文件对应 | 接口名与文件名一致 | ILight.hal |
LightInterface.hal |
4.3.2 接口继承
HAL 接口支持单继承,子接口继承父接口的所有方法:
interface IBase {
baseMethod() generates (int32_t result);
};
interface IDerived : IBase {
derivedMethod() generates (int32_t result);
};
4.4 方法签名
方法签名定义了 HAL 接口中可调用的操作,包括方法名、输入参数和输出参数。HAL 的方法签名支持多种模式,以适应不同的通信场景。
4.4.1 方法签名语法
[oneway] <returnType> <methodName>(<inputParams>) [generates (<outputParams>)];
| 语法元素 | 是否必需 | 说明 |
|---|---|---|
oneway |
可选 | 标记为单向调用,不等待服务端处理完成,无返回值 |
returnType |
必需 | 返回值类型,可以是基本类型或复合类型 |
methodName |
必需 | 方法名,小驼峰命名 |
inputParams |
可选 | 输入参数列表,多个参数用逗号分隔 |
generates |
可选 | 定义输出参数,用于返回多个值或回调结果 |
4.4.2 方法签名模式
HAL 接口支持三种方法调用模式,每种模式对应不同的 VTS 测试策略:
- 同步模式(默认):客户端发送请求后阻塞等待服务端返回结果,适用于需要立即获取结果的场景。
- 单向模式(oneway):客户端发送请求后立即返回,不等待服务端处理,适用于日志、事件通知等场景。
- 生成模式(generates):允许方法返回多个输出参数,适用于需要同时返回状态和数据的场景。
// 同步模式:设置亮度,等待返回成功状态
setBrightness(uint8_t level) generates (bool success);
// 单向模式:发送事件通知,不等待返回
oneway notifyEvent(uint32_t eventId);
// 生成模式:获取传感器数据,返回多个值
getSensorData() generates (int32_t x, int32_t y, int32_t z, int64_t timestamp);
- 同步方法需要验证超时处理机制,默认超时时间为 5 秒。
- 单向方法无法通过返回值判断执行结果,需通过回调或状态查询验证。
- generates 中的输出参数顺序必须与实现一致,VTS 会严格校验参数类型和顺序。
4.5 数据类型:struct / enum / union
.hal 文件支持三种复合数据类型:struct(结构体)、enum(枚举)和 union(联合体)。这些类型在 HAL 接口中用于定义复杂的数据结构,VTS 测试需要验证其序列化和反序列化的正确性。
4.5.1 struct(结构体)
struct 用于组合多个字段形成复合数据结构,是 HAL 接口中最常用的数据类型。
struct CameraMetadata {
int32_t sensorWidth;
int32_t sensorHeight;
float focalLength;
vec<uint8_t> rawData; // 变长数组
bool isAvailable;
};
| 字段类型 | 说明 | 示例 |
|---|---|---|
| 基本类型 | int32_t、uint8_t、float、bool 等 | int32_t id; |
| 字符串 | 使用 string 类型 |
string name; |
| 数组 | 使用 vec<T> 表示变长数组 |
vec<uint8_t> data; |
| 嵌套结构 | struct 内部可包含其他 struct | CameraMetadata meta; |
| 枚举 | 可包含 enum 类型字段 | FlashMode mode; |
4.5.2 enum(枚举)
enum 定义一组命名的整型常量,用于表示有限的状态集合。HAL 中的 enum 必须显式指定底层类型。
enum CameraError : int32_t {
OK = 0,
INVALID_ARGUMENT = -1,
PERMISSION_DENIED = -2,
RESOURCE_UNAVAILABLE = -3,
UNKNOWN_ERROR = -100
};
- 必须指定底层类型,常用
int32_t或uint32_t。 - 建议显式赋值,避免依赖默认值导致跨版本兼容问题。
- VTS 测试会验证枚举值是否在合法范围内,非法值会导致测试失败。
4.5.3 union(联合体)
union 允许在同一内存位置存储不同类型的值,但同一时刻只能使用其中一种类型。HAL 中的 union 通常与 enum 配合使用,通过 discriminator 标识当前有效类型。
enum ValueType : uint8_t {
INTEGER,
FLOAT,
STRING
};
union Value {
int32_t intValue;
float floatValue;
string strValue;
};
struct TypedValue {
ValueType type; // discriminator
Value value; // 根据 type 选择有效字段
};
4.6 数据类型在 VTS 测试中的验证要点
VTS 测试框架在验证 HAL 接口时,会对数据类型的以下方面进行严格检查:
- 类型一致性:验证 .hal 文件中声明的类型与 HAL 实现中的类型完全匹配。
- 内存布局:验证 struct 的字段顺序、对齐方式和填充字节是否符合规范。
- 枚举值范围:验证枚举值是否在合法范围内,越界值应被拒绝。
- 联合体判别器:验证 union 的 discriminator 与有效字段的一致性。
- 变长数组边界:验证 vec<T> 的长度是否在合理范围内,防止缓冲区溢出。
4.7 本章小结
本章详细讲解了 .hal 文件的语法结构,包括 package 声明、interface 定义、方法签名以及 struct/enum/union 三种复合数据类型。掌握这些基础知识是进行 VTS 测试框架集成和 HAL 层接口协议验证的前提。在实际测试工作中,需要结合具体 HAL 接口的 .hal 文件,逐项验证语法规范和数据类型的正确性。