在 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 及更高版本的可配置音频政策引擎配置管理:
图 1. 从 Android 6 开始,CAP 引擎配置管理。
如图所示,音频政策服务通过解析 vendor
分区中的 audio_policy_engine_configuration.xml
文件中的信息来获取 CAP 引擎配置。CAP 引擎配置文件使用 audio_policy_engine_configuration.xsd
中定义的架构来获取所需信息。audio_policy_engine_configuration.xml
是汽车行业的一个示例。适用于其他外形规格的类似示例位于 frameworks/av/services/audiopolicy/engineconfigurable/config/example/ 文件夹中。
下图详细说明了如何在音频政策服务中加载可配置的音频政策引擎信息。在本例中,参数框架会从 XML 文件加载结构和设置。
图 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
是音频政策引擎配置文件。此汽车示例引用了automotive 文件夹中的音频政策配置文件。其他示例展示了如何配置 build 以将文件推送到设备的供应商分区中。
Android 15 及更低版本中的 CAP 设置文件
与结构类似,设置信息(表示参数的规则和值)在 ParameterFrameworkConfigurationPolicy.xml
文件中引用为:
<SettingsConfiguration>
<ConfigurableDomainsFileLocation Path="Settings/Policy/PolicyConfigurableDomains.xml"/>
</SettingsConfiguration>
Android 还提供了 build 工具,可使用音频政策引擎配置和参数框架文件生成此类信息。如需了解详情,请参阅配置。
AIDL 音频 HAL CAP 初始化
从 Android 16 开始,AIDL Audio HAL API 定义通过音频政策引擎配置 AudioHalCapConfiguration.aidl 进行了扩展。下图简要概述了 Android 16 及更高版本的 CAP 引擎配置管理:
图 3. 从 Android 16 开始,CAP 引擎配置管理。
音频政策服务会直接使用 AIDL Audio HAL API 获取 CAP 引擎信息,而不是从设备供应商分区中的 XML 文件解析信息。
在此配置中,参数框架的结构仍由音频服务器端的 CAP 引擎加载。
图 4. CAP 引擎结构。
在所有情况下,配置都必须完整指定与产品策略、销量组和条件相关的信息。
下图简要概述了音频政策服务用于获取 CAP 引擎配置的 AIDL 音频 HAL 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
文件来获取结构信息。具体而言,它会从结构描述文件中获取信息:
<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_1000
到 vx_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_OEM
、VX_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 搭配使用的主要实用程序之一是允许更灵活地定义音频分组。
音量组
此外,每个音频属性组都必须有一个关联的音量组。此音量组与与音频属性组中的音频属性匹配的任何串流相关联。产品策略部分中的音乐产品策略示例具有媒体量组 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 文件,请通过以下步骤定义构建规则,通过构建系统运行参数框架 (PFW) 文件:
在
Android.bp
文件中,为该文件创建文件组:filegroup { name: ":device_for_product_strategies.pfw", srcs: ["engine/parameter-framework/Settings/device_for_product_strategyies.pfw"], }
将该文件添加到其他 PfW 文件(如果有)。
filegroup { name: "edd_files", srcs: [ ":device_for_input_source.pfw", ":volumes.pfw", ":device_for_product_strategyies.pfw", ], }
创建相应的网域生成规则:
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:从使用 CAP 的旧设备升级到使用 Android 16 或更高版本的新设备
新设备必须在 vendor
分区上发布时搭载 Android 16 或更高版本的代码。不过,由于原始设备制造商 (OEM) 拥有可用的设备 CAP 引擎配置,因此希望将其用作起点(或完全重复使用)。与 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 版本 |