2. Android系统架构与Vendor Module定位
要理解 Vendor Module 在 Android 中的位置,必须先建立一张“纵向分层 + 横向分区”的系统地图。Android 并不是一个单体系统,而是由应用层、框架层、原生库与运行时、HAL、内核等层次叠加而成;同时,从 Android 8.0 开始,Google 又用 Treble 机制在“框架”和“供应商实现”之间划出了一条稳定的边界。Vendor Module 正是这条边界上最关键的工程载体。
一、Android 分层架构:从 App 到 Kernel
Android 的经典分层自上而下可以概括为:
- 应用层(Apps):系统应用与第三方应用,通过 SDK 调用框架能力。
- Java API 框架层(Framework):ActivityManager、WindowManager、CameraService 等,向应用暴露统一接口。
- 系统服务与 Native 层:Binder、SurfaceFlinger、AudioFlinger、MediaCodec 等,负责跨进程与硬件抽象调度。
- HAL 层(Hardware Abstraction Layer):把摄像头、音频、传感器、蓝牙、Wi-Fi 等硬件能力抽象成标准接口。
- 内核与驱动层(Kernel / Driver):Linux 内核、设备驱动、电源管理、内存管理。
在没有 Treble 之前,HAL 往往以“共享库 + JNI 直连”的方式被 Framework 加载,框架与供应商代码耦合严重。每次 Android 大版本升级,芯片厂商和 ODM 都要重新适配大量 HAL,导致升级周期长、维护成本高。
二、Treble 机制:把“框架”和“供应商”解耦
Treble 的核心思想是:在 Framework 与 Vendor 实现之间定义稳定的 HIDL/AIDL 接口,并通过 VNDK、VINTF、Vendor 分区 等机制,让两者可以独立升级。其关键约束包括:
- 接口稳定:HAL 接口以 .hal 或 .aidl 描述,版本化发布,Framework 只依赖接口,不依赖具体实现。
- 进程隔离:HAL 通常运行在独立的 vendor 进程中,通过 Binder 与 Framework 通信。
- VNDK 限制:Vendor 代码只能使用 VNDK 允许的库,避免依赖 Framework 私有实现。
- VINTF 清单:通过 manifest.xml 声明“我提供什么接口、我要求什么接口”,在启动时校验兼容性。
三、Vendor 分区与 Vendor Module 的物理位置
在 Treble 设备上,典型分区布局如下:
| 分区 | 主要内容 | 升级归属 |
|---|---|---|
| system | Framework、系统服务、VNDK、系统 App | Google / AOSP |
| vendor | HAL 实现、Vendor Module、固件、厂商库 | 芯片厂商 / ODM |
| odm | ODM 定制 HAL、配置、客制化模块 | ODM |
| product | 产品差异化应用与配置 | 品牌商 |
| boot / dtbo | 内核、设备树、启动镜像 | 芯片厂商 |
Vendor Module 通常以 .so、可执行文件或 .rc 服务的形式存在于 /vendor/lib64/hw/、/vendor/bin/hw/ 等目录中。例如一个相机 HAL 模块可能表现为:
/vendor/lib64/hw/android.hardware.camera.provider@2.4-impl.so
/vendor/bin/hw/android.hardware.camera.provider@2.4-service
/vendor/etc/vintf/manifest.xml
/vendor/etc/init/vendor.camera.provider.rc
Framework 侧只认识 android.hardware.camera.provider@2.4 这个接口名,具体由哪个 .so 实现、放在哪个目录,由 Vendor 侧决定。这就是“接口与实现分离”的直接体现。
四、HAL 与 Vendor Module 的关系
HAL 是“接口规范”,Vendor Module 是“接口的实现载体”。可以这样理解:
- HAL 接口:定义在 hardware/interfaces 下,如
android.hardware.light@2.0,描述方法、参数、返回值。 - HAL 实现:由 Vendor 编写,通常是一个继承自接口的 C++ 类,编译成 .so 或独立 service。
- Vendor Module:把 HAL 实现、依赖库、init 脚本、VINTF 声明打包在一起,形成可独立升级的模块。
因此,Vendor Module 不只是“一个 so 文件”,而是一个包含实现、配置、启动脚本和接口声明的完整交付单元。它既可以被 Framework 通过 Binder 调用,也可以被其他 Vendor 模块复用。
五、典型场景:一次 Camera HAL 调用链
以拍照为例,一次跨层调用大致如下:
- App 调用 Camera2 API。
- Framework 的 CameraService 通过 HIDL/AIDL 调用
ICameraProvider。 - Binder 将请求路由到 vendor 分区中的 Camera Provider Service。
- 该 Service 加载具体 Vendor Module,操作 ISP、Sensor、MIPI 等硬件。
- 图像数据经 BufferQueue 返回 Framework,最终显示或保存。
整个过程中,Framework 不知道 ISP 型号,也不关心驱动细节;Vendor Module 也不需要修改 Framework 代码。这种“各管一段”的结构,正是 Treble 想要达到的效果。
六、常见误区与复盘
误区二:认为 Vendor 分区可以随意放 Framework 库。 Treble 设备会校验 VNDK 和 VINTF,违规依赖可能导致启动失败或 CTS 不通过。
误区三:忽略 VINTF 清单。 只编译出 .so 而不声明接口,Framework 在启动时可能找不到对应 HAL,表现为服务缺失或功能不可用。
复盘时建议按“接口声明 → 实现编译 → 分区放置 → init 启动 → VINTF 校验 → Framework 调用”这条链路逐项检查。只要其中一环缺失,Vendor Module 就无法被系统正确识别。
把这张图记在脑中,后续无论是编写 HAL 接口、配置 init 脚本,还是排查“服务起不来”“Framework 找不到 HAL”等问题,都可以快速定位到具体层次和分区。Vendor Module 的工程化本质,就是在 Treble 边界之下,交付一个接口稳定、分区正确、可被系统校验和调用的实现单元。