Android Build系列专题【篇六:VINTF机制】

VINTF(Vendor Interface Object)用于聚合设备信息,并通过可查询 API 提供这些信息。它确保设备与框架之间的接口兼容。

这句话是官方网站的原文,googke官方文档可以参考链接:https://source.android.com/docs/core/architecture/vintf

官方的这段话,不知所云,这里先引入我在调试HAL和HIDL接口的时候,遇到的报错:

2026-01-06 01:33:22 - check_target_files_vintf.py - INFO : stderr: [31mERROR: files are incompatible: The following instances are in the device manifest but not specified in framework compatibility matrix:

vendor.xxx.hardware.googlekey@1.0::IGoogleKey/default

vendor.xxx.hardware.oemsarsensor@1.0::IOemSarSensor/default

Suggested fix:
1. Update deprecated HALs to the latest version.
2. Check for any typos in device manifest or framework compatibility matrices with FCM version >= 202504.
3. For new platform HALs, add them to any framework compatibility matrix with FCM version >= 202504 where applicable.
4. For device-specific HALs, add to DEVICE_FRAMEWORK_COMPATIBILITY_MATRIX_FILE or DEVICE_PRODUCT_COMPATIBILITY_MATRIX_FILE
.: Success[0m

根据这段报错,可以了解到framework compatibility没有对hidl接口的配置进行声明。为了研究这个咨询AI针对VINTF的解释:

VINTF(Virtual Interface Testing Framework)是 Android 系统用于‌强制验证硬件抽象层(HAL)兼容性‌的核心机制。它的作用是:

  • 确保系统与设备的协同工作‌:Android 框架(如 System Server)和设备厂商的 HAL 实现(如传感器、密钥服务)必须能"对话"。VINTF 通过声明式矩阵,提前检测版本是否匹配、接口是否存在。
  • 防止运行时崩溃‌:如果系统加载了一个未声明的 HAL,会导致服务启动失败、设备无法开机或功能异常。
  • 支持模块化升级‌:Android 8.0+ 引入了分区架构(system/vendor/product),VINTF 让不同厂商的 HAL 能在统一框架下安全共存,无需修改系统镜像。
  • 实现 OTA 安全性‌:即使设备厂商更新了 HAL,只要符合 VINTF 矩阵,系统仍能正常运行,避免"刷机变砖"。

简单说:‌**VINTF 就是 Android 的"硬件身份证验证系统"**‌,没有它,系统不知道你的设备能做什么,也不敢启动。

下面我们来针对官方文档来研究一下这套机制。

一、VINTF架构设计

引用https://source.android.com/docs/core/architecture/vintf

要理解这张设计图首先需要理解如下几个概念:

1、DEVICE & FRAMEWORK

如上图,左侧蓝色框为DEVICE,右侧紫色框为FRAMEWORK,这其实就是trable化之后的产物。可以简单的做如下理解:

  • device等价于vendor和odm分区,或者运行在vendor和odm分区的进程或者服务。通常属于比较底层的东西,例如bsp或者hal
  • framework就是我们的framework框架层,即SystemService进程或者相关服务,或者运行在system分区的其他进程。

2、Manifests

Manifest(清单)--- 声明"提供什么"

作用:声明当前实体(设备或框架)能提供什么。

特点:描述能力(Capabilities),声明可用的接口/服务,类似于"我能做什么"

3、compatibility matrix

Compatibility Matrix(兼容性矩阵)--- 声明"需要什么"

作用:声明当前实体(设备或框架)需要什么。

特点:描述需求(Requirements),声明必需的接口/服务,类似于"我需要什么"

4、Manifests and matrixes策略

如上官方文档原文描述,可以总结如下:

  • device manifest:表示设备清单配置,用来描述device能够提供那些服务,通常就是指底层能够提供那些hal服务
  • framework compatibility matrix:表示框架兼容性矩阵配置,用来描述framework需要什么服务,通常就是指system分区的系统服务或者app进程需要去调用的那些hal服务或者hal接口
  • framework manifest:表示框架清单配置,用来描述framework能够提供那些服务,通常就是指SystemService进程启动了那些系统服务
  • device compatibility matrix:表示设备兼容性矩阵配置,用来描述device需要什么服务,通常就是指vendor分区的进程需要去调用system分区的那些普通service服务或者接口

其中device manifest + framework compatibility matrix就是我们比较熟悉的一种模式:

同样framework manifest + device compatibility matrix这种模式我们比较少见,但确实存在:

总结如下:

  • 在进行自定义hal或者HIDL模块开发,我们通常在vendor分区创建HAL服务进程,提供给system分区服务或者app进程进行调用,那么就需要在vendor分区进行manifests清单配置,在system分区进行compatibility matrix兼容性矩阵配置
  • 在进行自定义系统服务的时候,并且需要提供给vendor分区进行调用,那么就需要在system分区进行mainfests清单配置,在vendor分区进行compatibility matrix兼容性矩阵配置

二、manifests如何配置?

引用https://source.android.com/docs/core/architecture/vintf/objects

1、device manifests配置方式

如官方介绍主要有三种方式可以配置device 清单,我们最常用的就是对HIDL的配置:

1)模块直接指定/最优方案

官方示例如上,即在HAL模块定义的时候,我们在android.bp中通过****vintf_fragments进行指定,soong编译系统会自动将这个xml文件加入到设备清单之中;如果是android.mk的话,就使用LOCAL_VINTF_FRAGMENTS进行指定,同样make编译系统也会自动蒋这个xml加入到设备清单之中。

在我这个案例中,就是通过vintf_fragments进行指定,参考如下代码:

最后输出路径:/vendor/etc/vintf/manifest/xxx.xml

2)DEVICE_MANIFEST_FILE配置

如上官方示例,通过编译宏控DEVICE_MANIFEST_FILE指定xml文件,在被指定的xml文件中进行设备清单配置。

可以参考高通项目的一些默认配置:即我们可以check高通device对应项目中是否有如下配置,如果存在直接在指定文件中添加我们的device manifests

3)odm/etc/vintf/manifest.xml配置

如上说明,odm分区的设备清单文件加载策略,会按以下顺序查找并加载 ODM manifest,找到第一个存在的文件就使用:

优先级 1(最高):

/odm/etc/vintf/manifest_SKU.xml

↓ (如果不存在,继续查找)

优先级 2:

/odm/etc/vintf/manifest.xml

↓ (如果不存在,继续查找)

优先级 3:

/odm/etc/manifest_SKU.xml

↓ (如果不存在,继续查找)

优先级 4(最低):

/odm/etc/manifest.xml

odm sku运行时加载配置

需要注意odm下面的配置都是运行时生效,即SKU的值从ro.boot.product.****hardware.sku属性中取值,然后进行拼接,如下一个案例:就是优先加载manifest_dectwifi.xml生效

那么如上odm/etc/vintf/manifest_xxx.xml清单文件是怎么来的呢?在vendor device mk文件中进行了如下定义:

4)vendor/etc/vintf/manifest.xml配置

如上说明,vendor分区的设备清单文件加载策略,会按以下顺序查找并加载vendor manifest,找到第一个存在的文件就使用:

优先级 1(最高):

/vendor/etc/vintf/manifest_SKU.xml

↓ (如果不存在,继续查找)

优先级 2(最低):

/vendor/etc/vintf/manifest.xml

vendor sku运行时加载配置

需要注意odm下面的配置都是运行时生效,即SKU的值从**ro.boot.product.``vendor.sku**属性中取值,然后进行拼接,如高通A16的一个平台:

5)合并规则

路径 1:Vendor Manifest 存在时(现代设备,Android 9+)

这是最常见的场景,按以下顺序合并:

步骤 1:加载 Vendor Manifest

/vendor/etc/vintf/manifest.xml或

/vendor/etc/vintf/manifest_SKU.xml(如果有 SKU)

步骤 2:合并 Vendor Manifest Fragments

所有通过 vintf_fragments 指定的片段(例如:你的 vendor.tinno.hardware.googlekey@1.0-service.xml)

步骤 3:合并 ODM Manifest(如果存在)

/odm/etc/vintf/manifest.xml或

/odm/etc/vintf/manifest_SKU.xml

步骤 4:合并 ODM Manifest Fragments(如果存在)

ODM 分区的所有 manifest 片段

步骤 5:合并 Vendor APEX Fragments

/apex/<apex_name>/etc/vintf/*.xml

路径 2:只有 ODM Manifest 时

如果 vendor manifest 不存在(某些特殊设备):

步骤 1:加载 ODM Manifest

/odm/etc/vintf/manifest.xml

步骤 2:合并 ODM Manifest Fragments

ODM 分区的所有 manifest 片段

路径 3:旧设备兼容(Legacy)

对于 Android 8.x 及更早的设备:

/vendor/manifest.xml(旧格式)

/odm/etc/vintf/manifest.xml(可能完全覆盖 vendor manifest)

注意:在旧设备上,ODM manifest 可能完全覆盖 vendor manifest。

2、framework manifest配置方式

如上说明,因为这块场景用的比较少,这里就不深入研究,后续用到了之后在进行说明。

3、manifest长什么样子?

官方文档中有介绍各种manifest配置是长什么样子的:

如上三个分别为device manifest、OTA manifest、framework manifest的配置,在来一个我这边自定义的一个配置:

XML 复制代码
//hardware/interfaces/oemsarsensor/1.0/default/vendor.xxx.hardware.oemsarsensor@1.0-service.xml
<manifest version="1.0" type="device">
    <hal format="hidl">
        <name>vendor.xxx.hardware.oemsarsensor</name>
        <transport>hwbinder</transport>
        <version>1.0</version>
        <interface>
            <name>IOemSarSensor</name>
            <instance>default</instance>
        </interface>
    </hal>
</manifest>

需要重点说明如下几个参数:

  • manifest:表示配置的清单文件,注意区分后文中的compatibility
  • type:可以为device,也可以为framework,可以参考如下:

三、compatibility matrix如何配置?

引用https://source.android.com/docs/core/architecture/vintf/comp-matrices

1、device compatibility matrix

device compatibility matrix翻译过来叫做device兼容性矩阵,简称DCM。因为应用场景比较少,并且比较简单,和后面要介绍的fcm基本一致,所以先跳过。

2、framework compatibility matrix

framework compatibility matrix翻译过来叫做framework兼容性矩阵,简称FCM,官方这段说明首先讲解了,如果device manifest提供了某项能力(配置了某个hidl接口),那么fcm中也必须配置这个hidl接口,如果不配置就会导致编译过程中进行兼容性矩阵检查失败,从而编译报错。

fcm的配置由三部分组成:system、system_ext、product分区组成。

3、fcm/dcm长什么样子?

这里在介绍一下我这个案例的fcm配置:

特别需要注意的是,兼容性矩阵配置文件的xml已经是compatibility-matrix字段,不再是第二章中讲的manifest字符串了。

其他还有很多参数配置可以参考官方文档的https://source.android.com/docs/core/architecture/vintf/comp-matrices#compatibility-matrix-schema

4、fcm/dcm相关策略

引用https://source.android.com/docs/core/architecture/vintf/fcm

1)源代码配置路径

如上文档解释,首要信息是fcm的代码路径是在aosp/hardware/interfaces/compatibility_matrices/中定义,我们来看看这个目录下都是些什么东西?

可以得出结论:aosp/hardware/interfaces/compatibility_matrices/目录就是对兼容性矩阵配置的文件。

  • 如果是在system侧的代码,该路径就是配置framework compatibility matrix
  • 如果是在vendor侧的代码,该路径就是配置device compatibility matrix

2)compatibility_matrix.F.xml

如上看到了很多compatibility_matrix.?.xml的文件,他们到底有什么关联?

从这里的映射可以得知:从A15开始使用日期的方式来进行区分,这样更加的精细化。但是总感觉很搞笑!!!

compatibility_matrix.1.xml → Android 8.0

compatibility_matrix.2.xml → Android 8.1

compatibility_matrix.3.xml → Android 9.0

compatibility_matrix.4.xml → Android 10
compatibility_matrix.5.xml → Android 11

compatibility_matrix.6.xml → Android 12

compatibility_matrix.7.xml → Android 13

compatibility_matrix.8.xml → Android 14

compatibility_matrix.202404.xml → Android 15(2024年4月)

compatibility_matrix.202504.xml → Android 16(2025年4月)

3)target-level参数解读

AI对这个参数的解读如下:

看到这里我有些恍然大悟,这里举两个例子:

案例一:A14调试新增demo.hal

如上报错,需要在>5的兼容性矩阵文件中进行配置,最后的解决方案在如下文件都进行了声明:

案例二:A16调试新增googlekey.hal

如上报错日志,按照之前的理解,就需要在202504和202604中都进行声明

5、fcm到底如何配置?

2026-01-06 01:33:22 - check_target_files_vintf.py - INFO : stderr: [31mERROR: files are incompatible: The following instances are in the device manifest but not specified in framework compatibility matrix:

vendor.xxx.hardware.googlekey@1.0::IGoogleKey/default

vendor.xxx.hardware.oemsarsensor@1.0::IOemSarSensor/default

Suggested fix:
1.Update deprecated HALs to the latest version.
2. Check for any typos in device manifest or framework compatibility matrices with FCM version >= 202504.
3. For new platform HALs, add them to any framework compatibility matrix with FCM version >= 202504 where applicable.
4. For device-specific HALs, add to DEVICE_FRAMEWORK_COMPATIBILITY_MATRIX_FILE or DEVICE_PRODUCT_COMPATIBILITY_MATRIX_FILE.: Success[0m

补全在A16上面的遇到的编译报错和提示,编译系统给出来的四条建议:

  • 将已弃用的 HAL 更新到最新版本

    检查 vendor.tinno.hardware.googlekey@1.0vendor.tinno.hardware.oemsarsensor@1.0 是否有更新的版本(如 2.0),并升级实现代码和接口定义,避免使用过时的 API。

  • 检查设备清单和框架兼容性矩阵中的拼写错误,特别是 FCM 版本 ≥ 202504 的情况

    确保 manifest.xml 中的 HAL 名称(如 vendor.tinno.hardware.googlekey)与 compatibility_matrix.xml 中的声明完全一致,包括大小写、版本号和路径,任何拼写差异都会导致兼容性失败。

  • 对于平台级 HAL,将其添加到 FCM 版本 ≥ 202504 的框架兼容性矩阵中

    如果这些 HAL 是 Android 平台标准的一部分(如 Google 提供的接口),则必须在系统级的 compatibility_matrix.202504.xml 中显式声明支持,否则系统无法识别其存在。

  • 对于设备专属 HAL,添加到设备框架兼容性矩阵文件或产品兼容性矩阵文件中

    如果这些 HAL 是您厂商自研的(如 oemsarsensor),则不应出现在系统框架矩阵中,而应添加到设备专属的 DEVICE_FRAMEWORK_COMPATIBILITY_MATRIX_FILEDEVICE_PRODUCT_COMPATIBILITY_MATRIX_FILE 中,确保设备层声明其支持能力。

因此总结如下两种修改方案(即fcm 兼容性矩阵配置方案):

1)AOSP矩阵兼容性配置方案

如上案例一,即在aosp/hardware/interfaces/compatibility_matrices/目录下配置>=5的xml,这种方式通常应用于aosp原生的方案。例如:

XML 复制代码
    <hal format="hidl" optional="true">
        <name>vendor.tinno.hardware.demo</name>
        <version>1.0</version>
        <interface>
            <name>IDemo</name>
            <instance>default</instance>
        </interface>
    </hal>

2)非AOSP矩阵兼容性配置方案

针对非aosp平台标准的hal,即产商自研的HAL,例如高通定制的HAL,或者MTK定制的HAL,又或是OEM厂家定制的HAL,可以指定DEVICE_FRAMEWORK_COMPATIBILITY_MATRIX_FILE和DEVICE_PRODUCT_COMPATIBILITY_MATRIX_FILE进行配置。

这种方式在官方文档其实是有示例的,可以参考 https://source.android.com/docs/core/architecture/vintf/resources

因此这里的解决方案我们可以仿照如上:

如上文件在高通项目中已经默认被赋值给了DEVICE_FRAMEWORK_COMPATIBILITY_MATRIX_FILE宏控,如下:

3)两种方案本质一致

这里先给一个结论,这两个方案的本质原理其实几乎一致。

先看看在hardware/interfaces/compatibility_matrices/目录下配置的方案,在该目录下的mk文件,其实还是通过DEVICE_FRAMEWORK_COMPATIBILITY_MATRIX_FILE宏控来实现。

这些脚本我就不细看了,这里我们继续看一下通过DEVICE_FRAMEWORK_COMPATIBILITY_MATRIX_FILE指定的fcm.xml文件最终输出在什么目录下?我们拿了一个手机开机之后如下:

fcm的配置无论是方案一还是方案二,最后都会在/system/etc/vintf/目录下声明hidl相关配置。

四、案例总结

1、device manifests配置方案总结

2、framework compatibility matrix配置方案总结

3、案例之自定义IGoogleKey和OemSarSensor

这里还是以如上案例,自定义两个IGoogleKey.hal和IOemSarSensor.hal

步骤一:创建HAL服务进程

参考Android Init 系列专题【篇七:hal服务进程自定义】第一章

步骤二:device manifest配置

步骤三:framework compatibility matrix配置

最后:自检设备清单和兼容矩阵配置

如上device manifest和framework compatibility matrix能匹配,所以编译成功。

相关推荐
浪客川21 小时前
安卓日志工具类
android
csj5021 小时前
安卓基础之《(14)—数据存储(4)应用组件Application》
android
李坤林1 天前
Android Binder 详解(6) Binder 客户端的创建
android·binder
北京自在科技1 天前
苹果iOS 26.3实现跨安卓数据无缝迁移
android·ios·findmy
_道隐_1 天前
Android里面的layer、DisplayList和hardwarebuffer之间是什么关系
android
stevenzqzq1 天前
ctrl +B和ctrl+shift +B的区别
android·ide·android studio
似霰1 天前
HIDL Hal 开发笔记5----Same-Process HALs 实例分析
android·framework·hal
robotx1 天前
安卓16 设置壁纸中应用网格,有两个5X5的选项
android
Yyuanyuxin1 天前
保姆级学习开发安卓手机软件(三)--安装模拟机并开始简单的进入开发
android·学习