可配置的音频政策引擎

在 Android 14 中,Android Automotive 操作系统 (AAOS) 利用可配置的音频政策 (CAP) 引擎在主音频区内管理车载音频。具体而言,CAP 引擎允许 AAOS 仅控制音频路由、仅控制音频音量,或同时控制路由和音量。您可以使用以下标志来控制行为:

  • 使用 useCoreAudioVolume 标志可启用 CAP 音量管理。当此值为 true 时,车载音频服务使用音频管理器 API 来管理音量组。

  • 使用 useCoreAudioRouting 标志可启用 CAP 音频路由管理。 如果此值为 true,汽车音频服务将使用可配置的音频政策路由来管理音频路由。

Android 默认还支持以默认音频政策引擎形式存在的音频政策引擎。

背景

CAP 引擎基于 Intel 的参数框架,该框架基于插件和规则,用于处理各种参数。对于 Android 音频管理,CAP 引擎引入了定义 XML 文件规则的功能,以指定以下内容:

  • 音频产品策略
  • 音频输出设备选择规则
  • 音频输入设备选择规则
  • 用于管理音量和静音的规则以及音量表

Android 16 之前的 CAP 初始化

下图简要概述了 Android 6 中可配置的音频政策引擎配置管理:

Android 16 之前的 CAP 引擎架构

图 1. Android 6 中的 CAP 引擎配置管理。

如图所示,CAP 引擎配置由音频政策服务通过解析 vendor 分区中 audio_policy_engine_configuration.xml 文件的信息来获取。CAP 引擎配置文件使用 audio_policy_engine_configuration.xsd 中定义的架构来获取所需的信息。audio_policy_engine_configuration.xml 是一个汽车行业的示例。其他设备规格的类似示例位于 frameworks/av/services/audiopolicy/engineconfigurable/config/example/ 文件夹中。

下图更详细地展示了如何在音频政策服务中加载可配置的音频政策引擎信息。在这种情况下,参数框架会从 XML 文件中加载结构和设置。

Android 16 之前的 CAP 引擎加载路径

图 2. 在音频政策服务中加载的 CAP 信息。

Android 15 及更低版本中的 CAP 结构文件

为了获取结构和设置,音频政策服务会读取 ParameterFrameworkConfigurationPolicy.xml 文件。这会通过结构描述文件位置来引用结构信息:

<StructureDescriptionFileLocation Path="Structure/Policy/PolicyClass.xml"/>

这指向文件中的结构信息:

/vendor/etc/parameter-framework/Structure/Policy/PolicyClass.xml

Android 中提供了框架结构。结构信息需要产品策略结构信息,因此 Android 提供了 buildStrategiesStructureFile.py 生成工具,该工具可以根据可用的产品策略 XML 文件生成信息。可以通过 genrule 默认 buildstrategiesstructurerule 引用此内容,如下所示:

genrule {
    name: "buildstrategiesstructure_gen",
    defaults: ["buildstrategiesstructurerule"],
    srcs: [
        ":audio_policy_engine_configuration_files",
    ],
}

其中,audio_policy_engine_configuration_files 是音频政策引擎配置文件。此汽车示例引用了汽车文件夹中的音频政策配置文件。其他示例展示了如何配置 build 以推送设备 vendor 分区中的文件。

Android 15 及更低版本中的 CAP 设置文件

与结构类似,表示参数规则和值的设置信息在 ParameterFrameworkConfigurationPolicy.xml 文件中引用,如下所示:

<SettingsConfiguration>
  <ConfigurableDomainsFileLocation Path="Settings/Policy/PolicyConfigurableDomains.xml"/>
</SettingsConfiguration>

Android 还提供了一些 build 工具,用于使用音频政策引擎配置和参数框架文件生成此信息。如需了解详情,请参阅配置

AIDL 音频 HAL CAP 初始化

从 Android 16 开始,AIDL 音频 HAL API 定义通过音频政策引擎配置 AudioHalCapConfiguration.aidl 进行了扩展。下图简要概述了 Android 16 中的 CAP 引擎配置管理:

CAP Engine AIDL 架构

图 3. Android 16 及更高版本中的 CAP 引擎配置管理。

音频政策服务直接使用 AIDL 音频 HAL API 获取 CAP 引擎信息,而不是从设备供应商分区中的 XML 文件解析信息。

在此配置中,参数框架的结构仍由音频服务器端的 CAP 引擎加载。

CAP 引擎 AIDL 加载路径

图 4. CAP 引擎结构。

在所有情况下,配置都必须完整指定与商品策略、音量组和条件相关的信息。

下图简要概述了音频政策服务用于获取 CAP 引擎配置的 AIDL 音频 HAL API:

CAP 引擎 AIDL API 图 5. AIDL 音频 HAL API。

在此设置中,音频政策服务从 AIDL 音频 HAL 获取以下信息:

  • 配置
  • 策略
  • 合集
  • 条件
  • 设置

默认 AIDL 音频 HAL 加载器

为了顺利从 HIDL 过渡到 AIDL,默认音频 AIDL 音频 HAL 提供了一个 XML CAP 引擎加载器。供应商可以通过使用默认音频 HAL 扩展其音频 HAL 或引用 libaudioserviceexampleimpl 库来直接使用此加载器。

默认 AIDL 音频 HAL 加载器使用 audio_policy_engine_configuration.xml 获取以下信息:

  • 配置
  • 策略
  • 合集
  • 条件

结构信息是从 PolicyConfigurableDomains.xml 文件中获取的。与之前的机制相比,主要区别在于结构信息也由 AIDL 音频 HAL 获取,而不是由音频政策服务中的参数框架获取。

供应商可以使用 domaingeneratorpolicyrule 工具,根据音频政策引擎配置中的信息生成可配置的网域。您可以参考汽车 Cuttlefish 虚拟设备示例

AIDL 配置中的结构

在 Android 16 及更高版本中,音频政策服务通过读取和解析 ParameterFrameworkConfigurationCap.xml [文件](https://cs.android.com/android/platform/superproject/+/android-latest-release:frameworks/av/services/audiopolicy/engineconfigurable/wrapper/ParameterManagerWrapper.cpp;l=71

)。特别是,它会从结构描述文件中获取信息:

<StructureDescriptionFileLocation Path="Structure/Policy/CapClass.xml"/>

框架会将所需文件放置到包含所需信息的 /etc/parameter-framework/ 文件夹中。

该结构表示应控制的参数,因此应在配置或网域中引用这些参数。为此,AIDL 引擎配置应使用预定的参数名称。对于产品策略,结构在 CapProductStrategies.xml 中配置。

默认产品策略

默认引擎中提供的默认值开始,产品策略以 STRATEGY_ 前缀开头:

  • STRATEGY_PHONE
  • STRATEGY_SONIFICATION
  • STRATEGY_ENFORCED_AUDIBLE
  • STRATEGY_ACCESSIBILITY
  • STRATEGY_SONIFICATION_RESPECTFUL
  • STRATEGY_MEDIA
  • STRATEGY_DTMF
  • STRATEGY_CALL_ASSISTANT
  • STRATEGY_TRANSMITTED_THROUGH_SPEAKER

提供此格式是为了方便使用默认策略的设备从 HIDL 迁移到 AIDL。此格式更改对用于配置引擎的现有文件(例如 PfW、XML)产生了一些影响。特别是,所有产品策略引用都应更改为使用新名称,例如

非 AIDL 配置参数名称
/Policy/policy/product_strategies/media/device_address
/Policy/policy/product_strategies/media/selected_output_devices/mask
AIDL 配置参数名称
/Policy/policy/product_strategies/STRATEGY_MEDIA/device_address
/Policy/policy/product_strategies/STRATEGY_MEDIA/selected_output_devices/mask
OEM 定义的产品策略

可配置引擎使 OEM 能够更改产品策略定义。为了继续支持这一点,产品策略文件 CapProductStrategies.xml 还提供了 40 种从 vx_1000vx_1039 的供应商可扩展产品策略。所有供应商扩展都必须以 vx_ 前缀开头,后跟一个数字,该数字表示 AIDL 音频 HAL 产品策略定义中的产品策略 ID。其余定义(例如音频属性组、名称)从音频 HAL 引擎配置中的 AudioHALProductStrategy 对象获取。

与默认产品策略类似,供应商定义的 OEM 参考也必须在非 AIDL 配置和 AIDL 配置之间进行调整,例如:

非 AIDL 配置参数名称
/Policy/policy/product_strategies/oem_extension_strategy/device_address
/Policy/policy/product_strategies/oem_extension_strategy/selected_output_devices/mask
AIDL 配置参数名称
/Policy/policy/product_strategies/vx_1037/device_address
/Policy/policy/product_strategies/vx_1037/selected_output_devices/mask

产品策略

产品策略提供了一种自定义音频流分类和分组方式。这样一来,在配置音频设备时,包括如何路由音频设备以及如何管理其音量,就可以更加灵活。每种产品策略都可以有一个或多个音频属性组,用于标识应与相应产品策略关联的音频流。这些音频属性组可用于更精细地对音频进行分类,并且可以包含以下类型的混合:

  • 用法类型用于描述声音的播放原因(即媒体、通知、通话)。
  • 内容类型类型用于描述正在播放的内容(即音乐、语音、视频、声音化)。
  • 标志类型定义了与视频流相关的不同行为或请求。
  • 标记类型支持任意供应商字符串值列表。
    • 每个字符串都必须以 VX_ 开头,后跟字母数字字符串(例如 VX_OEMVX_NAVIGATION
<ProductStrategy name="music" id="1008">
    <AttributesGroup streamType="AUDIO_STREAM_MUSIC" volumeGroup="media">
        <Attributes> <Usage value="AUDIO_USAGE_MEDIA"/> </Attributes>
        <Attributes> <Usage value="AUDIO_USAGE_GAME"/> </Attributes>
        <!-- Default product strategy has empty attributes -->
        <Attributes></Attributes>
    </AttributesGroup>
</ProductStrategy>

此摘录展示了在汽车模拟器中使用的产品策略示例。它包含两个音频属性,分别具有音频使用媒体和游戏。 此产品策略与车载音频服务中使用的 MUSIC 音频上下文相匹配,但并不强制要求这种匹配。对于使用 CAP 和 Android 的 OEM 来说,主要实用程序之一是允许更灵活的音频分组定义。

音量组

此外,每个音频属性组都必须具有关联的音量组。此音量组与属于音频属性组的任何匹配音频属性的音频流相关联。产品策略部分中的音乐产品策略示例包含音量组 media,媒体音量组的定义如下:

<volumeGroup>
    <name>media</name>
    <indexMin>0</indexMin>
    <indexMax>40</indexMax>
    <volume deviceCategory="DEVICE_CATEGORY_SPEAKER">
        <point>0,-2400</point>
        <point>33,-1600</point>
        <point>66,-800</point>
        <point>100,0</point>
    </volume>
</volumeGroup>

在此定义中,音量组包含:

  • 功能组名称
  • 组最低指数
  • 组最大指数
  • 音量组曲线

音量组曲线包含音量组指数和毫分贝音量增益之间的点状映射。所提供的点用于在管理音量时对最佳匹配增益进行线性插值。每个音量组曲线都与设备类型类别(例如耳机、音箱、外部媒体)相关联。

音量组负责管理属于音频属性组的音频流的音量。例如,当启动具有包含音乐或游戏的音频属性的流时,系统会使用媒体音量组的上次设置的音量指数。在这种情况下,系统会根据所选设备选择相应的设备类别曲线,并在开始播放时设置相应的增益。

配置

在 CAP 引擎中,配置用于定义确定音频应如何表现的条件或规则。系统会在运行时评估这些配置,以根据音频系统的当前状态选择要应用的相应规则。

如图 5 所示,该 API 包含多个网域,每个网域的目标是将逻辑拆分为更小的路由问题来解决(例如,设备 1、设备 2)。

每个网域都有配置,而每个配置都有一组规则。规则是根据 AudioPolicyManager 提供的条件制定的:

  • 音频模式
  • 可用的输入和输出设备
  • 可用的输入和输出设备地址
  • 使用此优惠,
    • 媒体
    • 通信
    • 录制
    • 基座
    • 系统
    • HDMI 系统音频
    • 编码环绕声
    • 振动响铃

每个网域都包含决定应影响行为的规则的配置。请注意,配置顺序很重要,务必确保配置按所需顺序排列。在验证配置的规则后,系统会选择该配置。

以下代码显示了参数框架文件的摘录示例,该文件可用于生成配置可配置网域所需的 XML 文件:


supDomain: DeviceForProductStrategies
  supDomain: Music
    domain: SelectedDevice
      conf: BluetoothA2dp
        ForceUseForMedia IsNot NO_BT_A2DP
        ForceUseForCommunication IsNot BT_SCO
        AvailableOutputDevices Includes BLUETOOTH_A2DP
        component:/Policy/policy/product_strategies/vx_1000/selected_output_devices/mask
          bluetooth_a2dp = 1
          bus = 0
      conf: Bus
        AvailableOutputDevices Includes Bus
        AvailableOutputDevicesAddresses Includes BUS00_MEDIA
        component: /Policy/policy/product_strategies/vx_1000/selected_output_devices/mask
          bluetooth_a2dp = 0
          bus = 1
      conf: Default
        component: /Policy/policy/product_strategies/vx_1000/selected_output_devices/mask
          bluetooth_a2dp = 0
          bus = 0

网域 DeviceForProductStrategies 定义了在处理产品策略设备选择时应如何应用不同的规则。蓝色部分描述了应考虑的规则,绿色部分是应用的配置。此特定示例包含以下配置:

  • 选择蓝牙 A2DP 设备作为音乐产品策略(ID 1000,vx_1000
    • 如果用于媒体,则不排除 A2DP
    • 如果用于通信,则不是 BT SCO
    • 如果可用设备包含 BT A2DP
  • 选择总线设备
    • 如果总线设备可用
    • 如果地址为 BUS00_MEDIA
  • 否则,选择默认输出设备

如需生成相应的可配置政策引擎 XML 文件,请通过 build 系统运行参数框架 (PFW) 文件,方法是使用以下步骤定义 build 规则:

  1. Android.bp 文件中,为该文件创建一个 filegroup:

    filegroup {
        name: ":device_for_product_strategies.pfw",
        srcs: ["engine/parameter-framework/Settings/device_for_product_strategyies.pfw"],
    }
    
  2. 将该文件添加到其他 PfW 文件(如有)。

    filegroup {
        name: "edd_files",
        srcs: [
            ":device_for_input_source.pfw",
            ":volumes.pfw",
            ":device_for_product_strategyies.pfw",
        ],
    }
    
  3. 创建相应的网域生成规则

    genrule {
        name: "domaingeneratorpolicyrule_gen",
        defaults: ["domaingeneratorpolicyrule"],
        srcs: [
            ":audio_policy_engine_criterion_types",
            ":audio_policy_pfw_structure_files",
            ":audio_policy_pfw_toplevel",
            ":edd_files",
        ],
    }
    

    其中,domaingeneratorpolicyrule 是框架提供的用于生成 PolicyConfigurableDomains.xml 文件的生成 规则。网域生成规则中包含的其他源文件 (scrs) 如下所示:

    信息来源 说明
    audio_policy_pfw_toplevel 顶级参数框架配置文件。
    audio_policy_pfw_structure_files 用于生成配置文件的网域生成结构文件。
    audio_policy_engine_criterion_types 用于描述生成期间所用条件的条件类型 XML 文件。
    edd_files 单个网域文件的列表(每个文件都包含一个 <ConfigurableDomain> 标记)。

在 build 中运行生成规则后,系统会生成包含所有网域的 PolicyConfigurableDomains.xml。以下内容显示了使用 PfW 规则示例生成的文件的摘录:

---ConfigurableDomain Name="DeviceForProductStrategies.Music.SelectedDevice"---
<Configurations>
  <Configuration Name="BluetoothA2dp">
    <CompoundRule Type="All">
      <SelectionCriterionRule SelectionCriterion="ForceUseForMedia" MatchesWhen="IsNot" Value="NO_BT_A2DP"/>
      <SelectionCriterionRule SelectionCriterion="ForceUseForCommunication" MatchesWhen="IsNot" Value="BT_SCO"/>
      <SelectionCriterionRule SelectionCriterion="AvailableOutputDevices" MatchesWhen="Includes" Value="BLUETOOTH_A2DP"/>
    </CompoundRule>
  </Configuration>
  <Configuration Name="Bus">
    <CompoundRule Type="All">
      <SelectionCriterionRule SelectionCriterion="AvailableOutputDevices" MatchesWhen="Includes" Value="BUS"/>
      <SelectionCriterionRule SelectionCriterion="AvailableOutputDevicesAddresses" MatchesWhen="Includes" Value="BUS00_MEDIA"/>
    </CompoundRule>
  </Configuration>
  <Configuration Name="Default">
    <CompoundRule Type="All"/>
  </Configuration>
</Configurations>

CAP 调试

您可以使用 remote-process 转储 CAP 配置:

adb root && adb remount
adb shell remote-process unix:///dev/socket/audioserver/policy_debug dumpDomains

这会显示所有网域和配置,包括适用性条件。 以下内容展示了使用蓝牙 A2DP、总线设备和默认配置的 Cuttlefish 汽车设备的摘录。请参阅配置

- ConfigurableDomain: DeviceForProductStrategies.Music.SelectedDevice =
 {Sequence aware: no, Last applied configuration: Bus}
  - Configuration: BluetoothA2dp
    - CompoundRule = All
      - SelectionCriterionRule = ForceUseForMedia IsNot NO_BT_A2DP
      - SelectionCriterionRule = ForceUseForCommunication IsNot BT_SCO
      - SelectionCriterionRule = AvailableOutputDevices Includes BLUETOOTH_A2DP
  - Configuration: Bus
    - CompoundRule = All
      - SelectionCriterionRule = AvailableOutputDevices Includes BUS
      - SelectionCriterionRule = AvailableOutputDevicesAddresses Includes BUS00_MEDIA_CARD_0_DEV_0
  - Configuration: Default
    - CompoundRule = All

如需详细了解可用于调试 CAP 参数框架的其他命令,请使用此工具:

adb shell remote-process unix:///dev/socket/audioserver/policy_debug help

如需使用该工具,OEM 制造商必须允许在设备中进行调谐。如需验证设备是否允许调谐,请使用以下命令:

adb shell cat /system/etc/parameter-framework/ParameterFrameworkConfigurationCap.xml

在 Android 15 及更低版本中,该文件可能有所不同,因此请使用以下命令:

adb shell cat /system/etc/parameter-framework/ParameterFrameworkConfigurationPolicy.xml

该文件应包含 TuningAllowed="true" 以及相应的服务器端口:

<?xml version="1.0" encoding="UTF-8"?>
<ParameterFrameworkConfiguration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    SystemClassName="Policy" TuningAllowed="true" ServerPort="unix:///dev/socket/audioserver/policy_debug">
    <SubsystemPlugins>
        <Location Folder="">
            <Plugin Name="libpolicy-subsystem.so"/>
        </Location>
    </SubsystemPlugins>
    <StructureDescriptionFileLocation Path="Structure/Policy/CapClass.xml"/>
</ParameterFrameworkConfiguration>

此文件会根据 build 映像的类型自动生成(或者,对于旧版 build,可以针对发布调试使用不同的文件)。发布 build 会将 TuningAllowed 设置为 false,但不使用套接字端口(发布 build 中禁止使用套接字)。工程 build 和 userdebug build 会将其设置为 true,并使用套接字端口。请注意,这是 audio_policy_pfw_toplevel 引用的文件。远程进程工具还必须包含在设备的 make 或 build 文件中:

# Tool used for debug Parameter Framework (only for eng and userdebug builds)
PRODUCT_PACKAGES_DEBUG += remote-process

还必须包含允许套接字的相应 SELinux 政策。这仅适用于调试模式,因为发布模式明确禁止使用套接字:

BOARD_SEPOLICY_DIRS += frameworks/av/services/audiopolicy/engineconfigurable/sepolicy

Android 16 中的 CAP 迁移

鉴于 AIDL 音频 HAL CAP 引擎和之前版本带来的重大变化,您应考虑各种设备过渡方案。本部分介绍了最常见的过渡场景,并针对启用 CAP 引擎配置的工作给出了建议。

情形 1:新设备使用 Android 16 或更高版本,没有设备 CAP 配置的先前来源

新设备必须在 vendor 分区中发布时搭载 Android 16 或更高版本的代码。这意味着,它必须通过 AIDL 音频 HAL 接口公开可配置的音频政策引擎配置。设备 CAP 引擎配置应从示例中复制。vendor 分区上不应有任何 PfW CAP 网域定义。

设备使用的系统映像是 Android 16 或更高版本。音频服务框架通过 AIDL 音频 HAL 接口发现 CAP 配置,因此它会使用系统映像中的 PfW CAP 网域定义来初始化 PfW,并加载通过 AIDL 接收的设备 CAP 配置。

例如,请参阅此更改中引入的汽车 Cuttlefish 虚拟设备,该设备可用于参考设置所需配置文件所需的文件、构建规则和 make 文件。这适用于默认 AIDL 音频 HAL 中提供的加载器。

情形 2:新设备搭载 Android 16 或更高版本,旧设备使用 CAP

新设备必须在 vendor 分区中发布时搭载 Android 16 或更高版本的代码。不过,由于 OEM 具有可用的设备 CAP 引擎配置,因此 OEM 会希望将其用作起点(或完全重用)。与 Android 15 及更低版本相比,CAP 配置的 AIDL 版本有一些变化,因此供应商必须将现有配置转换为 AIDL。如需了解 Android 16 及更低版本之间的变更,请参阅产品策略,了解所需变更。 一般来说,音频框架会以与方案 1 相同的方式发现并加载 CAP 配置。

场景 3:现有设备(具有 CAP)更新到 Android 16,仅更新系统分区

在此场景中,vendor 分区包含 Android 15 及更低版本的设备 CAP 配置和 PfW CAP 网域定义。vendor 分区未触及,因此仍使用 HIDL HAL。该框架遵循 Android 15 及更低版本的场景,并从 vendor 分区加载所有与 CAP 相关的配置。

场景 4:现有设备发布时搭载 Android 15,具有 CAP

Android 15 上的 AIDL 不支持 CAP,因此一些供应商发布了搭载 AIDL 音频 HAL 和 CAP 的新设备,这些 CAP 由音频框架加载。这种混合模式是非官方的,但包含在 Android 16 中。请注意,此模式不得用于在 Android 16 上发布新设备,而应用于使搭载 Android 15 供应商的现有设备能够更新到 Android 16(system 分区更新)。

音频框架在没有 CAP 配置的情况下发现 AIDL 音频 HAL 音频配置。对于 CAP 配置,音频政策服务(音频框架)会回退到从 vendor 分区加载 CAP 配置。在这种情况下,必须从 vendor 分区加载 PfW CAP 网域定义和设备 CAP 配置。

CAP 迁移摘要

下表总结了与 CAP 配置兼容的系统和供应商配置以及要求:

系统分区 场景 供应商分区代码版本 核心音频 HAL 类型 PfW CAP 网域定义位置 设备 CAP 配置
Android 15 4 Android 14 或更低版本 HIDL vendor HIDL 版本
Android 16 3 Android 14 或更低版本 HIDL vendor HIDL 版本
Android 16 4 Android 15 AIDL vendor HIDL 版本
Android 16 2 Android 16 AIDL system 从 HIDL 转换而来的 AIDL 版本
Android 16 1 Android 16 AIDL system 示例中的 AIDL 版本