Android 使用AIDL HAL

本文详细介绍了Android中使用AIDL(Android Interface Definition Language)实现HAL(Hardware Abstraction Layer)的过程,包括AIDL文件的编写、服务端代码实现、接口更新与冻结,以及与设备清单、框架兼容性矩阵的关系。在更新接口后,必须同步更新应用端引用的接口版本,以避免找不到对应接口的错误。同时,文章阐述了Android 11之后AIDL HAL的匹配规则,强调了多个版本元素之间的AND关系。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

生成的目录结构

以audioControl 为例:

  • 首先编写的是aidl文件。
    其文件目录结构是:
── android
│   └── hardware
│       └── automotive
│           └── audiocontrol
│               ├── AudioFocusChange.aidl
│               ├── AudioGainConfigInfo.aidl
│               ├── DuckingInfo.aidl
│               ├── IAudioControl.aidl
│               ├── IAudioGainCallback.aidl
│               ├── IFocusListener.aidl
│               ├── IModuleChangeCallback.aidl
│               ├── MutingInfo.aidl
│               └── Reasons.aidl
  • 对应的Android.bp文件
    Android.bp 用来生成
    out/soong/.intermediates/hardware/interfaces/automotive/audiocontrol/aidl下的接口文件。
    后续客户端和服务端的实现 都需要引用相关的头文件。
    几个要点:
    组成接口的 AIDL 源文件的列表。
  1. 名字android.hardware.automotive.audiocontrol:
    AIDL 接口模块的名称,能唯一标识 AIDL 接口。
  2. aidl源文件路径
  3. 稳定性生命 stability: vintf
    stability:可选标志,用于承诺此接口的稳定性。目前仅支持 “vintf”。如果未设置此属性,这意味着接口在此编译环境下具有稳定性(因此,此处加载的接口只可与一起编译的元素共同使用,例如在 system.img 上)。如果将此标志设为 “vintf”,这表示做出了稳定性承诺:只要有代码使用此接口,接口就必须保持稳定。
  4. 后端 给客户端的代码 java。会生成java的接口给外部调用。
  5. frozen:可选标志,设置为 true 表示接口自上一个接口版本以来没有任何更改。这样可以启用更多构建时检查。设置为 false 表示接口处于开发阶段且包含新更改,因此运行 foo-freeze-api 将会生成新版本并自动将值更改为 true。在 Android 14 中引入。
aidl_interface {
    name: "android.hardware.automotive.audiocontrol",
    vendor_available: true,
    srcs: ["android/hardware/automotive/audiocontrol/*.aidl"],
    imports: [
        "android.hardware.audio.common-V1",
        "android.media.audio.common.types-V2",
    ],
    stability: "vintf",
    backend: {
        java: {
            sdk_version: "module_current",
            min_sdk_version: "31",
            apex_available: [
                "//apex_available:platform",
                "com.android.car.framework",
            ],
        },
    },
}
  • 更新接口

m android.hardware.automotive.audiocontrol-update-api。
运行上述命令会生成current 下面的目录、

├── aidl_api
│   └── android.hardware.automotive.audiocontrol
│       └── current
│           └── android
│               └── hardware
│                   └── automotive
│                       └── audiocontrol
│                           ├── AudioFocusChange.aidl
│                           ├── AudioGainConfigInfo.aidl
│                           ├── DuckingInfo.aidl
│                           ├── IAudioControl.aidl
│                           ├── IAudioGainCallback.aidl
│                           ├── IFocusListener.aidl
│                           ├── IModuleChangeCallback.aidl
│                           ├── MutingInfo.aidl
│                           └── Reasons.aidl
  • 冻结接口

m android.hardware.automotive.audiocontrol-freeze-api。
上述目录添加新的 API 定义,并添加一个 .hash 文件,二者均表示接口的新冻结版本。foo-freeze-api 还会更新 versions_with_info 属性以反映其他版本以及该版本的 imports。
会生成1的目录。

├── aidl_api
│   └── android.hardware.automotive.audiocontrol
│       ├── 1
│       │   └── android
│       │       └── hardware
│       │           └── automotive
│       │               └── audiocontrol
│       │                   ├── AudioFocusChange.aidl
│       │                   ├── DuckingInfo.aidl
│       │                   ├── IAudioControl.aidl
│       │                   ├── IFocusListener.aidl
│       │                   └── MutingInfo.aidl

  • 有多个version的时候 是如何进行管理的。

大概流程 是先update 然后freeze。 同时更改兼容性矩阵中的version。

基于aidl服务端代码的编写

  • 继承bn接口实现相关的函数
class AudioControl : public BnAudioControl {
  public:
    ndk::ScopedAStatus onAudioFocusChange(const std::string& in_usage, int32_t in_zoneId,
                                          AudioFocusChange in_focusChange) override;

}
  • 注册服务到serviceManager
main.cpp
int main() {
    ABinderProcess_setThreadPoolMaxThreadCount(0);
    std::shared_ptr<AudioControl> audioControl = ::ndk::SharedRefBase::make<AudioControl>();
    const std::string instance = std::string() + AudioControl::descriptor + "/default";
    binder_status_t status =
            AServiceManager_addServi

}
  • 编写rc文件 在系统启动的时候启动服务
    audiocontrol-default.rc
service vendor.audiocontrol-default /vendor/bin/hw/android.hardware.automotive.audiocontrol-service.exa
mple
    class hal
    user audioserver
    group system
  • 配置selinux相关的权限

位于system/sepolicy目录 主要是配置应用的file_contexts、service_context等等

  • 配置设备清单
    audiocontrol-default.xml
<manifest version="2.0" type="device">
    <hal format="aidl">
        <name>android.hardware.automotive.audiocontrol</name>
        <version>4</version>
        <fqname>IAudioControl/default</fqname>
    </hal>
</manifest>
  • 配置兼容性矩阵

位于hardware/interfaces/compatibility_matrices

  <hal format="aidl" optional="true">
        <name>android.hardware.automotive.audiocontrol</name>
        <version>2-4</version>
        <interface>
            <name>IAudioControl</name>
            <instance>default</instance>
        </interface>
    </hal>
  • 设备清单是什么? 有什么作用?

首先了解VINTF的概念: VINTF 是供应商接口对象,汇总设备的相关信息并可以通过API进行查询。
是设备和framework 之间能力交互的一种方式。

设备清单 device manifest:可以在AIDL service 相对应的文件夹中进行定义。定义fragment文件,编译时会包含进去
用于向framework说明提供了怎样的一个怎样的组件(可能是aidl 也可能是hidl)

设备清单:描述了设备可以为框架提供的静态组件。xml中type是device,一般是vendor实现的hal说明, 安装在vendor的目录下。
框架兼容性矩阵:描述了 Android 框架预期从给定设备中获取的内容。此矩阵是一个静态实体
框架清单:描述了框架可以为设备提供的高级层服务。xml的type是framework。一般是android原生实现的aidl服务接口,安装在system目录下。
设备兼容性矩阵:描述了供应商映像需要框架提供的服务,此矩阵的组成在设备开发期间由开发者手动确定。
这两对清单和矩阵必须在 OTA 时进行协调,以确保设备可以获取与设备功能兼容的框架更新。一般来说,清单描述了提供的内容,兼容性矩阵描述了需要的内容。

Android.bp 或 Android.mk 文件中,将 vintf_fragments 添加到任意模块。可以修改实现了 HAL 的模块 (my.package.foo@1.0-service-bar)。

… {

vintf_fragments: [“manifest_foo.xml”],

}

LOCAL_MODULE := …
LOCAL_VINTF_FRAGMENTS := manifest_foo.xml
在名为 manifest_foo.xml 的文件中,为此模块创建清单。编译的时候这个xml会添加到设备中。在此处添加条目与在设备的主清单中添加条目相同。这样,客户端就可以使用该接口,并允许 VTS 识别设备上的 HAL 实现。此清单会执行常规清单执行的任何操作。

下面的示例实现了安装到 vendor 或 odm 分区的 android.hardware.foo@1.0::IFoo/default。如果安装到 system、product 或 system_ext 分区,则改为使用 framework 类型,而不是 device 类型。

android.hardware.foo hwbinder @1.0::IFoo/default

总结

  1. 修改hardware/interfaces/automotive/audiocontrol/aidl的Android.bp文件
    将freeze改为false。
  2. 修改AIDL 文件 添相应的接口
  3. 更新接口 update-api
  4. 冻结接口freeze-api
  5. 编译中间文件
    6.修改兼容性矩形和device清单,service的清单
  • 按照上述的方式修改完成之后 在CarService应用端编译还是会出现错误找不到对应的接口。

原因是应用端java引用的 “android.hardware.automotive.audiocontrol-V3-java”,
而因为更新了api 会生成一个高于目前版本v3的v4 版本。在这个v4版本中才会有新增加的接口。
应用端引用的还是v3生成的java包 所以才会找不到相应的接口。

将对应的java包改成v4就可以了。

  • compatibility_matrix.8.xml 中的version2-3
    需不需要更改,
    不需要修改 也是兼容的。
    如果某个设备的清单文件中的 HAL 版本为 10,而某个框架的兼容性矩阵中指明 5-7,则该设备与此框架保持兼容。

提供的是4, 但是指明的是2-3 是可以支持的。

    <hal format="aidl" optional="true">
        <name>android.hardware.automotive.audiocontrol</name>
        <version>2-3</version>
        <interface>
            <name>IAudioControl</name>
            <instance>default</instance>
        </interface>
    </hal>

AIDL HAL
Android 11(不包括 Android 11)之后的所有 Android 版本都支持 VINTF 中的 AIDL HAL 版本。AIDL HAL 的匹配规则类似于 HIDL 和原生 HAL 的匹配规则,只是没有主要版本,并且每个 HAL 实例只有一个版本(如果未指定版本,则为 1)。

多个 元素具有 AND 关系。
元素可能具有 ,用以将它们标记为不需要。
当需要 时,同一个 中的多个 和 元素具有 AND 关系(请参见下面的<ahref=“#vibrator”>振动器示例)。</ahref=“#vibrator”>
示例:模块的成功 HAL 匹配
对于 5 版的 HAL,匹配规则如下:

矩阵 匹配清单
5 5-∞. 在兼容性矩阵中,5 是 5-5 的简写形式。
5-7 5-∞. 表示以下含义:
5 是要求的最低版本,这意味着提供 HAL 1-4 的清单不兼容。
7 是可以请求的最高版本,这意味着兼容性矩阵(框架或设备)的所有者将不会请求超过 7 的版本。请求版本 7 时,匹配清单的所有者仍然可以提供版本 10(以此为例)。兼容性矩阵所有者只知道请求的服务与 API 版本 7 兼容。
-7 仅供参考,不影响 OTA 更新流程。
因此,如果某个设备的清单文件中的 HAL 版本为 10,而某个框架的兼容性矩阵中指明 5-7,则该设备与此框架保持兼容。
示例:多个模块的成功 HAL 匹配
框架兼容性矩阵指明了振动器和相机 HAL 的以下版本信息:

android.hardware.vibrator 1-2 IVibrator default specific android.hardware.camera 5 ICamera default [a-z]+/[0-9]+ 供应商必须实现以下所有实例:

android.hardware.vibrator.IVibrator/default // version >= 1
android.hardware.vibrator.IVibrator/specific // version >= 1
android.hardware.camera.ICamera/default // version >= 5
android.hardware.camera.ICamera/${INSTANCE}
// with version >= 5, where ${INSTANCE} matches [a-z]+/[0-9]+
// e.g. legacy/0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值